Description
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')