Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fortran dialects don't pick up base settings #4686

Open
mwichmann opened this issue Feb 24, 2025 · 1 comment
Open

Fortran dialects don't pick up base settings #4686

mwichmann opened this issue Feb 24, 2025 · 1 comment

Comments

@mwichmann
Copy link
Collaborator

mwichmann commented Feb 24, 2025

Since time immemorial (*), SCons docs have suggested that if you choose a Fortran "dialect", some of its own settings can be used for things specific to that dialect, otherwise you can just set the generic version of the construction variable and pick those up.

(*) Actually, only checked as old as 3.0.0

Here are the three "interesting" variables (for the purposes of this report) described for the F90 dialect (this is the old 3.0 wording, the current wording has evolved a bit):

F90FLAGS - General user-specified options that are passed to the Fortran 90 compiler. Note that this variable does not contain -I (or similar) include search path options that scons generates automatically from $F90PATH. See $_F90INCFLAGS below, for the variable that expands to those options. You only need to set $F90FLAGS if you need to define specific user options for Fortran 90 files. You should normally set the $FORTRANFLAGS variable, which specifies the user-specified options passed to the default Fortran compiler for all Fortran versions.

F90PATH - The list of directories that the Fortran 90 compiler will search for include directories. The implicit dependency scanner will search these directories for include files. Don't explicitly put include directory arguments in $F90FLAGS because the result will be non-portable and the directories will not be searched by the dependency scanner. Note: directory names in $F90PATH will be looked-up relative to the SConscript directory when they are used in a command. To force scons to look-up a directory relative to the root of the source tree use #. You only need to set $F90PATH if you need to define a specific include path for Fortran 90 files. You should normally set the $FORTRANPATH variable, which specifies the include path for the default Fortran compiler for all Fortran versions.

SHF90FLAGS is similar to F90FLAGS, details omitted here.

The difference between this and the implementation is the code chooses the dialect based on the filename suffix, and uses the specific variables only. It appears to never pick up $FORTRANFLAGS or $FORTRANPATH in this case, so the advice is incorrect. The current advice (dare I say convention) is to use .f90 (or .F90) for all free-form Fortran, and if people follow this, even though they're doing what might be called a "generic" compile, they get the F90 dialect settings instead.

A simple example is to compile a file that needs a header:

Object(source="foo.F90", FORTRANPATH='include')

Which won't find it, as $FORTRANPATH doesn't get looked at:

scons: Building targets ...
gfortran -o foo.o -c foo.F90
foo.F90:9:2:

    9 |
      |  1
Fatal Error: assert_macros.h: No such file or directory
compilation terminated.
scons: *** [foo.o] Error 1

Change the PATH variable used:

Object(source="foo.F90", F90PATH='include')

This time you see the include directive in the compile line and it works:

scons: Building targets ...
gfortran -o foo.o -c -Iinclude foo.F90
scons: done building targets.

We can debate "what is the intended behavior" but we really can't have the mismatch, where someone reads the docs, sets FORTRANPATH and FORTRANFLAGS, names their files .f90, and it doesn't work.

My opinion is that a small change in the setup code to pick up the generic variables would improve things, perhaps:

if dialect != 'FORTRAN':
    env.SetDefault(f'{dialect}PATH'=env.get('FORTRANPATH', ''))

The two FLAGS variables already have conditional settings:

    if f'{dialect}FLAGS' not in env:
        env[f'{dialect}FLAGS'] = SCons.Util.CLVar('')
    if f'SH{dialect}FLAGS' not in env:
        env[f'SH{dialect}FLAGS'] = SCons.Util.CLVar(f'${dialect}FLAGS')

which could get a bit of extra logic:

    if dialect != 'FORTRAN':
        env.SetDefault(f'{dialect}FLAGS', env.get('FORTRANFLAGS', SCons.Util.CLVar('')))
        env.SetDefault(f'SH{dialect}FLAGS', env.get('SHFORTRANFLAGS', SCons.Util.CLVar(f'${dialect}FLAGS')))
    else:
        env.SetDefault(f'{dialect}FLAGS'=SCons.Util.CLVar(''))
        env.SetDefault(f'SH{dialect}FLAGS'=SCons.Util.CLVar(f'${dialect}FLAGS')
@mwichmann
Copy link
Collaborator Author

Okay, never mind on the SetDefault part, remembered you can't use strings in this context, so the "paste in the dialect" trick is unworkable. Would need to drop it back to regular assignment satements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant