From 7efb8ce8c6d2181103d7e57840bf1246518876e6 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 26 Feb 2025 07:26:48 -0700 Subject: [PATCH 1/3] Fortran dialects default FLAGS and PATH if not set The manpage has always said that for a given dialect (e.g. F90), to set FORTRANFLAGS and FORTRANPATH unless you need values that are unique to just that dialect, in which case you can set the dialect-specific ones (e.g. F90FLAGS and/or F90PATH). However, the implementation never actually picked up the generic settings if the dialect-specific settings were not given. This change now picks up the defaults if the dialect does not have a value set. Signed-off-by: Mats Wichmann --- CHANGES.txt | 5 ++- RELEASE.txt | 5 +++ SCons/Tool/FortranCommon.py | 25 ++++++----- doc/man/scons.xml | 88 +++++++++++++++++++++---------------- 4 files changed, 73 insertions(+), 50 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 60b6bda6f..8d39cce74 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -206,8 +206,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER Includes code embedded in docstrings. - Handle case of "memoizer" as one member of a comma-separated --debug string - this was previously missed. - - test YACC/live.py fixed - finally started failing on an "old-style" + - test YACC/live.py fixed - gcc 15 failed this on an "old-style" (K&R flavor) function declaration, updated. + - Fortran dialect *PATH and *FLAGS settings fall back to generic + dialect's settings if not explicitly set, bringing the behavior in line + with long-standing documentation claims. From Adam Scott: - Changed Ninja's TEMPLATE rule pool to use `install_pool` instead of diff --git a/RELEASE.txt b/RELEASE.txt index 0d1b63763..8a78d84c8 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -183,6 +183,11 @@ FIXES - Handle case of "memoizer" as one member of a comma-separated --debug string - this was previously missed. +- Fortran dialect *PATH and *FLAGS settings fall back to generic + dialect's settings if not explicitly set, bringing the behavior in line + with long-standing documentation claims. + + IMPROVEMENTS ------------ diff --git a/SCons/Tool/FortranCommon.py b/SCons/Tool/FortranCommon.py index dc9dcddf6..ccddda322 100644 --- a/SCons/Tool/FortranCommon.py +++ b/SCons/Tool/FortranCommon.py @@ -146,6 +146,20 @@ def DialectAddToEnv( """ ComputeFortranSuffixes(suffixes, ppsuffixes) + defaults = {} + # Dialect-specific variables that should fall back to FORTRAN dialect: + if dialect == 'FORTRAN': + defaults[f'{dialect}FLAGS'] = SCons.Util.CLVar('') + defaults[f'SH{dialect}FLAGS'] = SCons.Util.CLVar(f'${dialect}FLAGS') + else: + defaults[f'{dialect}PATH'] = '$FORTRANPATH' + defaults[f'{dialect}FLAGS'] = '$FORTRANFLAGS' + defaults[f'SH{dialect}FLAGS'] = '$SHFORTRANFLAGS' + # Variables that should fall back to the C version: + defaults[f'INC{dialect}PREFIX'] = '$INCPREFIX' + defaults[f'INC{dialect}SUFFIX'] = '$INCSUFFIX' + env.SetDefault(**defaults) + fscan = SCons.Scanner.Fortran.FortranScan(f"{dialect}PATH") for suffix in suffixes + ppsuffixes: SCons.Tool.SourceFileScanner.add_scanner(suffix, fscan) @@ -168,17 +182,6 @@ def DialectAddToEnv( static_obj.add_emitter(suffix, FortranEmitter) shared_obj.add_emitter(suffix, ShFortranEmitter) - 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') - - # If a tool does not define fortran prefix/suffix for include path, use C ones - if f'INC{dialect}PREFIX' not in env: - env[f'INC{dialect}PREFIX'] = '$INCPREFIX' - if f'INC{dialect}SUFFIX' not in env: - env[f'INC{dialect}SUFFIX'] = '$INCSUFFIX' - env[f'_{dialect}INCFLAGS'] = f'${{_concat(INC{dialect}PREFIX, {dialect}PATH, INC{dialect}SUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}}' if support_mods: diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 5a05466ba..e230d922e 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -8205,34 +8205,36 @@ in &t-link-fortran;; (&consvars; start with FORTRAN) While &SCons; recognizes multiple internal dialects based on filename suffixes, -the convention of various available Fortran compilers is +the convention of many popular Fortran compilers is to assign an actual meaning to only two of these suffixes: .f -(as well as .for and .ftn) -refers to the fixed-format source -code that was the only available option in FORTRAN 77 and earlier, -and .f90 refers to free-format source code +(with .for and .ftn +usually given the same meaning), +interpreted as fixed-format source +code that was the only available option in Fortran 77 and earlier; +.f90, +interpreted as free-format source code which became available as of the Fortran 90 standard. Some compilers recognize suffixes which correspond to Fortran specifications later than F90 as equivalent to .f90 for this purpose, while some do not - check the documentation for your compiler. -An occasionally suggested policy suggestion is to use only +An occasionally suggested policy is to use only .f and .f90 as Fortran filename suffixes. The fixed/free form determination can usually be controlled explicitly with compiler flags -(e.g. for gfortran), +(e.g. for GNU Fortran), overriding any assumption that may be made based on the source file suffix. -The source file suffix does not imply conformance +A source file suffix does not imply conformance with the similarly-named Fortran standard - a suffix of .f08 does not mean you are compiling specifically for Fortran 2008. Normally, compilers provide command-line options for making this selection -(e.g. for gfortran). +(e.g. for GNU Fortran). @@ -8241,9 +8243,9 @@ a suffix of .mod is recognized for Fortran modules. These files are a side effect of compiling a Fortran source file containing module declarations, and must be available when other code which declares -that it uses the module is processed. -&SCons; does not currently have integrated support for submodules, -introduced in the Fortran 2008 standard - +it uses the module is processed. +&SCons; does not currently have integrated support for submodules +(introduced in the Fortran 2008 standard) - the invoked compiler will produce results, but &SCons; will not recognize .smod files as tracked objects. @@ -8259,33 +8261,43 @@ a file with a an upper-cased suffix from the set .F95, .F03 and .F08 -is treated as a Fortran source file -which shall first be run through -the standard C preprocessor. -The lower-cased versions of these suffixes do not -trigger this behavior. -On systems which do not distinguish between upper -and lower case in filenames, -this behavior is not available, -but files suffixed with either -.FPP -or .fpp -are always passed to the preprocessor first. -This matches the convention of gfortran -from the GNU Compiler Collection, -and also followed by certain other Fortran compilers. -For these two suffixes, -the generic FORTRAN dialect will be selected. - - - -&SCons; itself does not invoke the preprocessor, -that is handled by the compiler, -but it adds &consvars; which are applicable to the preprocessor run. -You can see this difference by examining -&cv-link-FORTRANPPCOM; and &cv-link-FORTRANPPCOMSTR; +is assumed to be a Fortran source file +which may contain macros and conditional compilation directives. +Most popular Fortran compilers will first pass such +a source file through a Fortran preprocssor +(fpp, which in some implementations +may be the same as the C preprocessor); +the lower-cased suffixes do not trigger this behavior. +On systems which do not distinguish between +upper and lower case in filenames, +this scheme cannot be used, +but you can usually use the .fpp +suffix to force this behavior +(.FPP is a synonym). +Since this suffix-driven behavior is convention, +not mandated by standards, +consult the compiler's documentation to be sure. + + + +Although &SCons; itself is not responsible for invoking the preprocessor, +it does add &consvars; which are applicable to the preprocessor. +You can see this difference by examining, for example, +&cv-link-FORTRANPPCOM; and &cv-link-FORTRANPPCOMSTR;, which are used instead of -&cv-link-FORTRANCOM; and &cv-link-FORTRANCOMSTR; for that dialect. +&cv-link-FORTRANCOM; and &cv-link-FORTRANCOMSTR; +for the generic compiler dialect if a preprocessor suffix is detected. +The .fpp suffix indicates a +Fortran 90+ (free-form) source file without implying a dialect, +so &SCons; selects the generic FORTRAN dialect in this case. +Otherwise, if the suffix matches one of the dialects, +&SCons; selects that dialect for the settings. +Compilers typically also have a flag available +to indicate preprocessing is required +(e.g. for GNU Fortran), +but using such an option will not trigger &SCons; +to use the alternate &consvars; in building command lines +so you are responsible for that setup yourself. From dc48d3706286093e31714e56b3d041b4c05d95e4 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 26 Feb 2025 09:58:40 -0700 Subject: [PATCH 2/3] Fix Fortran dialect FLAGS default After the change to default to generic dialect's flags/paths, if a test did an Append to *FLAGS, it would do string concatenation with the un-substituted default, as that looks like a string. That is, if $SHF90FLAGS is '$SHFORTRANFLAGS', then appending '-x' became '$SHFORTRANFLAGS-x' rather than ['$SHFORTRANFLAGS', '-x']. This failed tests on Windows, though for some reason I'm not clear on, not on Linux. Turning the initial assignment to a CLVar takes care of this. Signed-off-by: Mats Wichmann --- SCons/Tool/FortranCommon.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SCons/Tool/FortranCommon.py b/SCons/Tool/FortranCommon.py index ccddda322..9709d6bb3 100644 --- a/SCons/Tool/FortranCommon.py +++ b/SCons/Tool/FortranCommon.py @@ -153,8 +153,8 @@ def DialectAddToEnv( defaults[f'SH{dialect}FLAGS'] = SCons.Util.CLVar(f'${dialect}FLAGS') else: defaults[f'{dialect}PATH'] = '$FORTRANPATH' - defaults[f'{dialect}FLAGS'] = '$FORTRANFLAGS' - defaults[f'SH{dialect}FLAGS'] = '$SHFORTRANFLAGS' + defaults[f'{dialect}FLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS') + defaults[f'SH{dialect}FLAGS'] = SCons.Util.CLVar('$SHFORTRANFLAGS') # Variables that should fall back to the C version: defaults[f'INC{dialect}PREFIX'] = '$INCPREFIX' defaults[f'INC{dialect}SUFFIX'] = '$INCSUFFIX' From a62064650ba49b15c58d097e1357fb1c7cc1ef89 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 27 Feb 2025 15:27:00 -0700 Subject: [PATCH 3/3] Update documentation for F90 dialect [skip ci] Signed-off-by: Mats Wichmann --- SCons/Tool/f90.xml | 204 ++++++++++++++++++++++----------------------- 1 file changed, 101 insertions(+), 103 deletions(-) diff --git a/SCons/Tool/f90.xml b/SCons/Tool/f90.xml index 89c5ddced..d770faac1 100644 --- a/SCons/Tool/f90.xml +++ b/SCons/Tool/f90.xml @@ -27,7 +27,12 @@ This file is processed by the bin/SConsDoc.py module. -Set construction variables for generic POSIX Fortran 90 compilers. +Set &consvars; for the Fortran 90 dialect. +A Fortran dialect lets you customize the +compilation environment for certain files, +as selected by the dialect's FILESUFFIXES variables. +By default, the Fortran 90 dialect behaves the same +as the Fortran 95, 03 and 08 dialects. @@ -53,12 +58,12 @@ Set construction variables for generic POSIX Fortran 90 compilers. -The Fortran 90 compiler. -You should normally set the &cv-link-FORTRAN; variable, -which specifies the default Fortran compiler -for all Fortran versions. -You only need to set &cv-link-F90; if you need to use a specific compiler -or compiler version for Fortran 90 files. +The compiler for the Fortran 90 dialect. +This dialect is selected when a source file has a suffix +specified in &cv-link-F90FILESUFFIXES; or +&cv-link-F90PPFILESUFFIXES;. +You only need to set &cv-F90; if you need to specify +a compiler different than the one auto-detected for this dialect. @@ -67,11 +72,11 @@ or compiler version for Fortran 90 files. The command line used to compile a Fortran 90 source file to an object file. -You only need to set &cv-link-F90COM; if you need to use a specific -command line for Fortran 90 files. -You should normally set the &cv-link-FORTRANCOM; variable, -which specifies the default command line -for all Fortran versions. +You only need to set &cv-F90COM; if you need to use a customized +command line for this dialect. +The default setting will be equivalent to +&cv-link-FORTRANCOM;, +but using the dialect-specific &consvars; for substitution. @@ -81,8 +86,8 @@ for all Fortran versions. If set, the string displayed when a Fortran 90 source file is compiled to an object file. -If not set, then &cv-link-F90COM; or &cv-link-FORTRANCOM; -(the command line) is displayed. +If not set, then the actual command line, +as generated from &cv-link-F90COM;, is displayed. @@ -90,8 +95,8 @@ If not set, then &cv-link-F90COM; or &cv-link-FORTRANCOM; -The list of file extensions for which the F90 dialect will be used. By -default, this is ['.f90'] +The list of file extensions for which the Fortran 90 dialect will be used. +By default, this is ['.f90'] @@ -100,7 +105,7 @@ default, this is ['.f90'] The list of file extensions for which the compilation + preprocessor pass for -F90 dialect will be used. By default, this is empty. +the Fortran 90 dialect will be used. By default, this is empty. @@ -108,23 +113,16 @@ F90 dialect will be used. By default, this is empty. -General user-specified options that are passed to the Fortran 90 compiler. -Note that this variable does -not -contain - -(or similar) include search path options -that scons generates automatically from &cv-link-F90PATH;. -See -&cv-link-_F90INCFLAGS; -below, -for the variable that expands to those options. +General user-specified options that are passed to the compiler +for the Fortran 90 dialect. You only need to set &cv-link-F90FLAGS; if you need to define specific -user options for Fortran 90 files. -You should normally set the &cv-link-FORTRANFLAGS; variable, -which specifies the user-specified options -passed to the default Fortran compiler -for all Fortran versions. +user options for Fortran 90 dialect files. +You should normally set the &cv-link-FORTRANCOMMONFLAGS; variable, +which holds user-specified options passed to all Fortran builds. + +Changed in version 4.4: +&cv-link-FORTRANCOMMONFLAGS; is included by default +when command lines for this dialect are expanded. @@ -132,13 +130,13 @@ for all Fortran versions. -An automatically-generated construction variable +An automatically-generated &consvar; containing the Fortran 90 compiler command-line options for specifying directories to be searched for include files. -The value of &cv-link-_F90INCFLAGS; is created -by appending &cv-link-INCPREFIX; and &cv-link-INCSUFFIX; -to the beginning and end -of each directory in &cv-link-F90PATH;. +The value of &cv-link-_F90INCFLAGS; is created by +prepending &cv-link-INCPREFIX; +and appending &cv-link-INCSUFFIX; +to each directory in &cv-link-F90PATH;. @@ -147,14 +145,14 @@ of each directory in &cv-link-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 &cv-link-F90FLAGS; because the result will be non-portable -and the directories will not be searched by the dependency scanner. Note: -directory names in &cv-link-F90PATH; will be looked-up relative to the SConscript -directory when they are used in a command. To force -&scons; -to lookup a directory relative to the root of the source tree, use #: +files. The implicit dependency scanner will also search these +directories for include files. +Do not include compiler search path syntax +(such as the option), +as this will make the result not portable +between different systems, +and will cause the directory not to be searched by the +dependency scanner. You only need to set &cv-link-F90PATH; if you need to define a specific include path for Fortran 90 files. You should normally set the &cv-link-FORTRANPATH; variable, @@ -162,6 +160,14 @@ which specifies the include path for the default Fortran compiler for all Fortran versions. + +Note: +directory names in &cv-link-F90PATH; are 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 a top-relative path (starts with #): + env = Environment(F90PATH='#/include') @@ -169,8 +175,7 @@ env = Environment(F90PATH='#/include') The directory lookup can also be forced using the -&Dir;() -function: +&f-link-Dir; function: @@ -181,17 +186,11 @@ env = Environment(F90PATH=include) The directory list will be added to command lines through the automatically-generated -&cv-link-_F90INCFLAGS; -construction variable, -which is constructed by -appending the values of the -&cv-link-INCPREFIX; and &cv-link-INCSUFFIX; -construction variables -to the beginning and end -of each directory in &cv-link-F90PATH;. +&cv-link-_F90INCFLAGS; &consvar;. Any command lines you define that need -the F90PATH directory list should -include &cv-link-_F90INCFLAGS;: +the &cv-F90PATH; directory list should +include &cv-link-_F90INCFLAGS;, +for example: @@ -203,15 +202,14 @@ env = Environment(F90COM="my_compiler $_F90INCFLAGS -c -o $TARGET $SOURCE") -The command line used to compile a Fortran 90 source file to an object file -after first running the file through the C preprocessor. -Any options specified in the &cv-link-F90FLAGS; and &cv-link-CPPFLAGS; construction variables -are included on this command line. -You only need to set &cv-link-F90PPCOM; if you need to use a specific -C-preprocessor command line for Fortran 90 files. -You should normally set the &cv-link-FORTRANPPCOM; variable, -which specifies the default C-preprocessor command line -for all Fortran versions. +The command line used to compile a Fortran 90 source file to an object file, +including options such as &cv-link-F90FLAGS; and &cv-link-CPPFLAGS; +needed for the preprocessor. +You only need to set &cv-F90PPCOM; if you need to use a customized +command line for this dialect. +The default setting will be equivalent to +&cv-link-FORTRANPPCOM;, +but using the dialect-specific &consvars; for substitution. @@ -220,9 +218,9 @@ for all Fortran versions. If set, the string displayed when a Fortran 90 source file -is compiled after first running the file through the C preprocessor. -If not set, then &cv-link-F90PPCOM; or &cv-link-FORTRANPPCOM; -(the command line) is displayed. +is compiled to an object file, including preprocessing. +If not set, then the actual command line, +as generated from &cv-link-F90PPCOM;, is displayed. @@ -230,12 +228,12 @@ If not set, then &cv-link-F90PPCOM; or &cv-link-FORTRANPPCOM; -The Fortran 90 compiler used for generating shared-library objects. -You should normally set the &cv-link-SHFORTRAN; variable, -which specifies the default Fortran compiler -for all Fortran versions. -You only need to set &cv-link-SHF90; if you need to use a specific compiler -or compiler version for Fortran 90 files. +The compiler for the Fortran 90 dialect for generating shared-library objects. +This dialect is selected when a source file has a suffix +specified in &cv-link-F90FILESUFFIXES; or +&cv-link-F90PPFILESUFFIXES; and compiling shared objects. +You only need to set &cv-SHF90; if you need to specify +a compiler different than the one auto-detected for this dialect. @@ -243,13 +241,13 @@ or compiler version for Fortran 90 files. -The command line used to compile a Fortran 90 source file -to a shared-library object file. -You only need to set &cv-link-SHF90COM; if you need to use a specific -command line for Fortran 90 files. -You should normally set the &cv-link-SHFORTRANCOM; variable, -which specifies the default command line -for all Fortran versions. +The command line used to compile a Fortran 90 source file to a +shared object file. +You only need to set &cv-SHF90COM; if you need to use a customized +command line for this dialect. +The default setting will be equivalent to +&cv-link-SHFORTRANCOM;, +but using the dialect-specific &consvars; for substitution. @@ -258,9 +256,9 @@ for all Fortran versions. If set, the string displayed when a Fortran 90 source file -is compiled to a shared-library object file. -If not set, then &cv-link-SHF90COM; or &cv-link-SHFORTRANCOM; -(the command line) is displayed. +is compiled to a shared object file. +If not set, then the actual command line, +as generated from &cv-link-SHF90COM;, is displayed. @@ -269,13 +267,15 @@ If not set, then &cv-link-SHF90COM; or &cv-link-SHFORTRANCOM; Options that are passed to the Fortran 90 compiler -to generated shared-library objects. +when compiling shared-library objects. You only need to set &cv-link-SHF90FLAGS; if you need to define specific user options for Fortran 90 files. You should normally set the &cv-link-FORTRANCOMMONFLAGS; variable, -which specifies the user-specified options -passed to the default Fortran compiler -for all Fortran versions. +which holds user-specified options passed to all Fortran builds. + +Changed in version 4.4: +&cv-link-FORTRANCOMMONFLAGS; is included by default +when command lines for this dialect are expanded. @@ -284,15 +284,14 @@ for all Fortran versions. The command line used to compile a Fortran 90 source file to a -shared-library object file -after first running the file through the C preprocessor. -Any options specified in the &cv-link-SHF90FLAGS; and &cv-link-CPPFLAGS; construction variables -are included on this command line. -You only need to set &cv-link-SHF90PPCOM; if you need to use a specific -C-preprocessor command line for Fortran 90 files. -You should normally set the &cv-link-SHFORTRANPPCOM; variable, -which specifies the default C-preprocessor command line -for all Fortran versions. +shared object file, +including options such as &cv-link-SHF90FLAGS; and &cv-link-CPPFLAGS; +needed for the preprocessor. +You only need to set &cv-SHF90PPCOM; if you need to use a customized +command line for this dialect. +The default setting will be equivalent to +&cv-link-SHFORTRANPPCOM;, +but using the dialect-specific &consvars; for substitution. @@ -301,10 +300,9 @@ for all Fortran versions. If set, the string displayed when a Fortran 90 source file -is compiled to a shared-library object file -after first running the file through the C preprocessor. -If not set, then &cv-link-SHF90PPCOM; or &cv-link-SHFORTRANPPCOM; -(the command line) is displayed. +is compiled to a shared-library object file, including preprocessing. +If not set, then the actual command line, +as generated from &cv-link-SHF90PPCOM;, is displayed.