diff --git a/CHANGES.txt b/CHANGES.txt index 28785e12f8..d221603b06 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -194,6 +194,12 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER to add a path to the execution environment if it was discovered in default_paths. Previously, the routine, called by many tool modules, never altered the execution environment, leaving it to the tools. + - A new construction variable FORTRANCOMMONFLAGS is added which is + applied to all Fortran dialects, in case someone needs to set some + flags globally. FORTRANFLAGS looked like it was intended for that, + but was not applied to other dialects, and e2e tests explicitly checked + that FORTRANFLAGS did not propagate outside the FORTRAN dialect, + so the conclusion is that behavior is intentional (issue #2257) From Zhichang Yu: - Added MSVC_USE_SCRIPT_ARGS variable to pass arguments to MSVC_USE_SCRIPT. diff --git a/RELEASE.txt b/RELEASE.txt index abecf390d4..4f42e8c3ec 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -43,6 +43,8 @@ NEW FUNCTIONALITY is taken and the constructed environment is likely incomplete. As implemented, the default global policy is "warning". The ability to set the global policy via an SCons command-line option may be added in a future enhancement. +- Fortran: a new construction variable FORTRANCOMMONFLAGS is added which is + applied to all Fortran dialects, to enable global (all-dialect) settings. DEPRECATED FUNCTIONALITY diff --git a/SCons/Tool/FortranCommon.py b/SCons/Tool/FortranCommon.py index cad16b6fe0..aff0f92387 100644 --- a/SCons/Tool/FortranCommon.py +++ b/SCons/Tool/FortranCommon.py @@ -21,43 +21,48 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -""" - -Stuff for processing Fortran, common to all fortran dialects. - -""" +"""Routines for setting up Fortran, common to all dialects.""" import re import os.path +from typing import Tuple -import SCons.Action import SCons.Scanner.Fortran import SCons.Tool import SCons.Util +from SCons.Action import Action + +def isfortran(env, source) -> bool: + """Returns True if source has any fortran files in it. -def isfortran(env, source): - """Return 1 if any of code in source has fortran files in it, 0 - otherwise.""" + Only checks based on filename suffixes, does not examine code. + """ try: fsuffixes = env['FORTRANSUFFIXES'] except KeyError: # If no FORTRANSUFFIXES, no fortran tool, so there is no need to look # for fortran sources. - return 0 + return False if not source: # Source might be None for unusual cases like SConf. - return 0 + return False for s in source: if s.sources: ext = os.path.splitext(str(s.sources[0]))[1] if ext in fsuffixes: - return 1 - return 0 + return True + return False -def _fortranEmitter(target, source, env): +def _fortranEmitter(target, source, env) -> Tuple: + """Common code for Fortran emitter. + + Called by both the static and shared object emitters, + mainly to account for generated module files. + """ + node = source[0].rfile() if not node.exists() and not node.is_derived(): print("Could not locate " + str(node.name)) @@ -78,21 +83,29 @@ def _fortranEmitter(target, source, env): return (target, source) -def FortranEmitter(target, source, env): +def FortranEmitter(target, source, env) -> Tuple: import SCons.Defaults target, source = _fortranEmitter(target, source, env) return SCons.Defaults.StaticObjectEmitter(target, source, env) -def ShFortranEmitter(target, source, env): +def ShFortranEmitter(target, source, env) -> Tuple: import SCons.Defaults target, source = _fortranEmitter(target, source, env) return SCons.Defaults.SharedObjectEmitter(target, source, env) -def ComputeFortranSuffixes(suffixes, ppsuffixes): - """suffixes are fortran source files, and ppsuffixes the ones to be - pre-processed. Both should be sequences, not strings.""" +def ComputeFortranSuffixes(suffixes, ppsuffixes) -> None: + """Update the suffix lists to reflect the platform requirements. + + If upper-cased suffixes can be distinguished from lower, those are + added to *ppsuffixes*. If not, they are added to *suffixes*. + + Args: + suffixes (list): indicate regular Fortran source files + ppsuffixes (list): indicate Fortran source files that should be + be run through the pre-processor + """ assert len(suffixes) > 0 s = suffixes[0] sup = s.upper() @@ -102,31 +115,34 @@ def ComputeFortranSuffixes(suffixes, ppsuffixes): else: suffixes.extend(upper_suffixes) - -def CreateDialectActions(dialect): +def CreateDialectActions(dialect) -> Tuple[Action, Action, Action, Action]: """Create dialect specific actions.""" - CompAction = SCons.Action.Action('$%sCOM ' % dialect, '$%sCOMSTR' % dialect) - CompPPAction = SCons.Action.Action('$%sPPCOM ' % dialect, '$%sPPCOMSTR' % dialect) - ShCompAction = SCons.Action.Action('$SH%sCOM ' % dialect, '$SH%sCOMSTR' % dialect) - ShCompPPAction = SCons.Action.Action('$SH%sPPCOM ' % dialect, '$SH%sPPCOMSTR' % dialect) - + CompAction = Action(f'${dialect}COM ', cmdstr=f'${dialect}COMSTR') + CompPPAction = Action(f'${dialect}PPCOM ', cmdstr=f'${dialect}PPCOMSTR') + ShCompAction = Action(f'$SH{dialect}COM ', cmdstr=f'$SH{dialect}COMSTR') + ShCompPPAction = Action(f'$SH{dialect}PPCOM ', cmdstr=f'$SH{dialect}PPCOMSTR') return CompAction, CompPPAction, ShCompAction, ShCompPPAction -def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_module=False): - """Add dialect specific construction variables.""" - ComputeFortranSuffixes(suffixes, ppsuffixes) +def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_mods=False) -> None: + """Add dialect specific construction variables. - fscan = SCons.Scanner.Fortran.FortranScan("%sPATH" % dialect) + Args: + dialect (str): dialect name + suffixes (list): suffixes associated with this dialect + ppsuffixes (list): suffixes using cpp associated with this dialect + support_mods (bool): whether this dialect supports modules + """ + ComputeFortranSuffixes(suffixes, ppsuffixes) + fscan = SCons.Scanner.Fortran.FortranScan(f"{dialect}PATH") for suffix in suffixes + ppsuffixes: SCons.Tool.SourceFileScanner.add_scanner(suffix, fscan) - env.AppendUnique(FORTRANSUFFIXES = suffixes + ppsuffixes) + env.AppendUnique(FORTRANSUFFIXES=suffixes + ppsuffixes) compaction, compppaction, shcompaction, shcompppaction = \ CreateDialectActions(dialect) - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) for suffix in suffixes: @@ -141,64 +157,60 @@ def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_module=False): static_obj.add_emitter(suffix, FortranEmitter) shared_obj.add_emitter(suffix, ShFortranEmitter) - if '%sFLAGS' % dialect not in env: - env['%sFLAGS' % dialect] = SCons.Util.CLVar('') - - if 'SH%sFLAGS' % dialect not in env: - env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect) + 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 'INC%sPREFIX' % dialect not in env: - env['INC%sPREFIX' % dialect] = '$INCPREFIX' - - if 'INC%sSUFFIX' % dialect not in env: - env['INC%sSUFFIX' % dialect] = '$INCSUFFIX' - - env['_%sINCFLAGS' % dialect] = '${_concat(INC%sPREFIX, %sPATH, INC%sSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}' % (dialect, dialect, dialect) - - if support_module: - env['%sCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) - env['%sPPCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) - env['SH%sCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) - env['SH%sPPCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect) + 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: + env[f'{dialect}COM'] = f'${dialect} -o $TARGET -c $FORTRANCOMMONFLAGS ${dialect}FLAGS $_{dialect}INCFLAGS $_FORTRANMODFLAG $SOURCES' + env[f'{dialect}PPCOM'] = f'${dialect} -o $TARGET -c $FORTRANCOMMONFLAGS ${dialect}FLAGS $CPPFLAGS $_CPPDEFFLAGS $_{dialect}INCFLAGS $_FORTRANMODFLAG $SOURCES' + env[f'SH{dialect}COM'] = f'$SH{dialect} -o $TARGET -c $FORTRANCOMMONFLAGS $SH{dialect}FLAGS $_{dialect}INCFLAGS $_FORTRANMODFLAG $SOURCES' + env[f'SH{dialect}PPCOM'] = f'$SH{dialect} -o $TARGET -c $FORTRANCOMMONFLAGS $SH{dialect}FLAGS $CPPFLAGS $_CPPDEFFLAGS $_{dialect}INCFLAGS $_FORTRANMODFLAG $SOURCES' else: - env['%sCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) - env['%sPPCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) - env['SH%sCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) - env['SH%sPPCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect) + env[f'{dialect}COM'] = f'${dialect} -o $TARGET -c $FORTRANCOMMONFLAGS ${dialect}FLAGS $_{dialect}INCFLAGS $SOURCES' + env[f'{dialect}PPCOM'] = f'${dialect} -o $TARGET -c $FORTRANCOMMONFLAGS ${dialect}FLAGS $CPPFLAGS $_CPPDEFFLAGS $_{dialect}INCFLAGS $SOURCES' + env[f'SH{dialect}COM'] = f'$SH{dialect} -o $TARGET -c $FORTRANCOMMONFLAGS $SH{dialect}FLAGS $_{dialect}INCFLAGS $SOURCES' + env[f'SH{dialect}PPCOM'] = f'$SH{dialect} -o $TARGET -c $FORTRANCOMMONFLAGS $SH{dialect}FLAGS $CPPFLAGS $_CPPDEFFLAGS $_{dialect}INCFLAGS $SOURCES' + -def add_fortran_to_env(env): - """Add Builders and construction variables for Fortran to an Environment.""" +def add_fortran_to_env(env) -> None: + """Add Builders and construction variables for Fortran/generic.""" try: FortranSuffixes = env['FORTRANFILESUFFIXES'] except KeyError: FortranSuffixes = ['.f', '.for', '.ftn'] - #print("Adding %s to fortran suffixes" % FortranSuffixes) try: FortranPPSuffixes = env['FORTRANPPFILESUFFIXES'] except KeyError: FortranPPSuffixes = ['.fpp', '.FPP'] - DialectAddToEnv(env, "FORTRAN", FortranSuffixes, - FortranPPSuffixes, support_module=True) + DialectAddToEnv(env, "FORTRAN", FortranSuffixes, FortranPPSuffixes, support_mods=True) + # Module support env['FORTRANMODPREFIX'] = '' # like $LIBPREFIX env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX - env['FORTRANMODDIR'] = '' # where the compiler should place .mod files env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' -def add_f77_to_env(env): - """Add Builders and construction variables for f77 to an Environment.""" +def add_f77_to_env(env) -> None: + """Add Builders and construction variables for f77 dialect.""" try: F77Suffixes = env['F77FILESUFFIXES'] except KeyError: F77Suffixes = ['.f77'] - #print("Adding %s to f77 suffixes" % F77Suffixes) try: F77PPSuffixes = env['F77PPFILESUFFIXES'] except KeyError: @@ -206,59 +218,50 @@ def add_f77_to_env(env): DialectAddToEnv(env, "F77", F77Suffixes, F77PPSuffixes) -def add_f90_to_env(env): - """Add Builders and construction variables for f90 to an Environment.""" +def add_f90_to_env(env) -> None: + """Add Builders and construction variables for f90 dialect.""" try: F90Suffixes = env['F90FILESUFFIXES'] except KeyError: F90Suffixes = ['.f90'] - #print("Adding %s to f90 suffixes" % F90Suffixes) try: F90PPSuffixes = env['F90PPFILESUFFIXES'] except KeyError: F90PPSuffixes = [] - DialectAddToEnv(env, "F90", F90Suffixes, F90PPSuffixes, - support_module=True) - + DialectAddToEnv(env, "F90", F90Suffixes, F90PPSuffixes, support_mods=True) -def add_f95_to_env(env): - """Add Builders and construction variables for f95 to an Environment.""" +def add_f95_to_env(env) -> None: + """Add Builders and construction variables for f95 dialect.""" try: F95Suffixes = env['F95FILESUFFIXES'] except KeyError: F95Suffixes = ['.f95'] - #print("Adding %s to f95 suffixes" % F95Suffixes) try: F95PPSuffixes = env['F95PPFILESUFFIXES'] except KeyError: F95PPSuffixes = [] - DialectAddToEnv(env, "F95", F95Suffixes, F95PPSuffixes, - support_module=True) - + DialectAddToEnv(env, "F95", F95Suffixes, F95PPSuffixes, support_mods=True) -def add_f03_to_env(env): - """Add Builders and construction variables for f03 to an Environment.""" +def add_f03_to_env(env) -> None: + """Add Builders and construction variables for f03 dialect.""" try: F03Suffixes = env['F03FILESUFFIXES'] except KeyError: F03Suffixes = ['.f03'] - #print("Adding %s to f95 suffixes" % F95Suffixes) try: F03PPSuffixes = env['F03PPFILESUFFIXES'] except KeyError: F03PPSuffixes = [] - DialectAddToEnv(env, "F03", F03Suffixes, F03PPSuffixes, - support_module=True) + DialectAddToEnv(env, "F03", F03Suffixes, F03PPSuffixes, support_mods=True) - -def add_f08_to_env(env): - """Add Builders and construction variables for f08 to an Environment.""" +def add_f08_to_env(env) -> None: + """Add Builders and construction variables for f08 dialect.""" try: F08Suffixes = env['F08FILESUFFIXES'] except KeyError: @@ -269,13 +272,10 @@ def add_f08_to_env(env): except KeyError: F08PPSuffixes = [] - DialectAddToEnv(env, "F08", F08Suffixes, F08PPSuffixes, - support_module=True) - + DialectAddToEnv(env, "F08", F08Suffixes, F08PPSuffixes, support_mods=True) -def add_all_to_env(env): - """Add builders and construction variables for all supported fortran - dialects.""" +def add_all_to_env(env) -> None: + """Add builders and construction variables for all supported dialects.""" add_fortran_to_env(env) add_f77_to_env(env) add_f90_to_env(env) diff --git a/SCons/Tool/f03.xml b/SCons/Tool/f03.xml index fc14ace454..c9893855a9 100644 --- a/SCons/Tool/f03.xml +++ b/SCons/Tool/f03.xml @@ -1,6 +1,6 @@