Skip to content

Fortran dialects don't pick up base settings #4686

Open
@mwichmann

Description

@mwichmann

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions