From bd3cc3b1f0218643a6c8b610bc1328e169f45c6c Mon Sep 17 00:00:00 2001 From: Daniel Moody Date: Mon, 6 Jun 2022 16:11:28 -0500 Subject: Updated lex emitter to respect escaped spaces when climbing out of a the SCosncript dir --- CHANGES.txt | 1 + RELEASE.txt | 1 + SCons/Tool/lex.py | 2 +- test/LEX/lex_headerfile.py | 44 ++++++++++++++++++++++ test/LEX/lex_headerfile/spaced path/SConstruct | 2 + test/LEX/lex_headerfile/spaced path/src/SConscript | 10 +++++ test/LEX/lex_headerfile/spaced path/src/lexer.l | 1 + test/LEX/lex_headerfile/spaced path/src/lexer2.l | 1 + 8 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 test/LEX/lex_headerfile.py create mode 100644 test/LEX/lex_headerfile/spaced path/SConstruct create mode 100644 test/LEX/lex_headerfile/spaced path/src/SConscript create mode 100644 test/LEX/lex_headerfile/spaced path/src/lexer.l create mode 100644 test/LEX/lex_headerfile/spaced path/src/lexer2.l diff --git a/CHANGES.txt b/CHANGES.txt index 03692d6..efea669 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -116,6 +116,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER Note that these are called for every build command run by SCons. It could have considerable performance impact if not used carefully. to connect to the server during start up. + - Updated lex emitter to respect escaped spaces when climbing out of a the SCosncript dir From Mats Wichmann: - Tweak the way default site_scons paths on Windows are expressed to diff --git a/RELEASE.txt b/RELEASE.txt index cfa8afc..a393a36 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -134,6 +134,7 @@ FIXES - The system environment variable names imported for MSVC 7.0 and 6.0 were updated to be consistent with the variables names defined by their respective installers. This fixes an error caused when bypassing MSVC detection by specifying the MSVC 7.0 batch file directly. +- Updated lex emitter to respect escaped spaces when climbing out of a the SCosncript dir IMPROVEMENTS ------------ diff --git a/SCons/Tool/lex.py b/SCons/Tool/lex.py index d8d8de4..c33d0fa 100644 --- a/SCons/Tool/lex.py +++ b/SCons/Tool/lex.py @@ -58,7 +58,7 @@ def lexEmitter(target, source, env): # Different options that are used to trigger the creation of extra files. fileGenOptions = ["--header-file=", "--tables-file="] - lexflags = env.subst("$LEXFLAGS", target=target, source=source) + lexflags = env.subst_list("$LEXFLAGS", target=target, source=source) for option in SCons.Util.CLVar(lexflags): for fileGenOption in fileGenOptions: l = len(fileGenOption) diff --git a/test/LEX/lex_headerfile.py b/test/LEX/lex_headerfile.py new file mode 100644 index 0000000..c2e2e8b --- /dev/null +++ b/test/LEX/lex_headerfile.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +Test the headerfile option for lex tool. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.dir_fixture('lex_headerfile') + +test.run(chdir='spaced path', arguments='.') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/LEX/lex_headerfile/spaced path/SConstruct b/test/LEX/lex_headerfile/spaced path/SConstruct new file mode 100644 index 0000000..aa4aca0 --- /dev/null +++ b/test/LEX/lex_headerfile/spaced path/SConstruct @@ -0,0 +1,2 @@ +DefaultEnvironment(tools=[]) +SConscript("src/SConscript") \ No newline at end of file diff --git a/test/LEX/lex_headerfile/spaced path/src/SConscript b/test/LEX/lex_headerfile/spaced path/src/SConscript new file mode 100644 index 0000000..a3f4bfd --- /dev/null +++ b/test/LEX/lex_headerfile/spaced path/src/SConscript @@ -0,0 +1,10 @@ +env = Environment(tools=['lex']) + +def make_header_path(env, target, source, for_signature): + return target[1] + +env.Replace(LEX_HEADER_FILE_GEN=make_header_path) +env.Append(LEXFLAGS=['--header-file=$LEX_HEADER_FILE_GEN']) + +env.CFile(target=['#gen_src/lexer.c', '#gen_src/lexer.l.h'], source='lexer.l') +env.CFile(target=['#gen_src/lexer2.c', '#gen_src/lexer2.l.h'], source='lexer2.l') \ No newline at end of file diff --git a/test/LEX/lex_headerfile/spaced path/src/lexer.l b/test/LEX/lex_headerfile/spaced path/src/lexer.l new file mode 100644 index 0000000..66b82a4 --- /dev/null +++ b/test/LEX/lex_headerfile/spaced path/src/lexer.l @@ -0,0 +1 @@ +%% \ No newline at end of file diff --git a/test/LEX/lex_headerfile/spaced path/src/lexer2.l b/test/LEX/lex_headerfile/spaced path/src/lexer2.l new file mode 100644 index 0000000..66b82a4 --- /dev/null +++ b/test/LEX/lex_headerfile/spaced path/src/lexer2.l @@ -0,0 +1 @@ +%% \ No newline at end of file -- cgit v0.12 From e2033e5f52002d404383c97e3a6a010efef174c8 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 9 Jun 2022 11:30:47 -0600 Subject: Fortran vairants now include FORTRANCOMMONFLAGS The documentation suggested $FORTRANFLAGS was included in the build lines for all variants, but it was not. Turns out the test suite quite explicitly checks that FORTRANFLAGS doesn't leak through to other variants, so instead define a new FORTRANCOMMONFLAGS to serve the purpose of a flag that applies to all variants. Assorted cleanup. And f-strings. Fixes #2257 Signed-off-by: Mats Wichmann --- CHANGES.txt | 6 ++ RELEASE.txt | 2 + SCons/Tool/FortranCommon.py | 178 ++++++++++++++++---------------- SCons/Tool/f03.xml | 5 +- SCons/Tool/f08.xml | 5 +- SCons/Tool/f77.xml | 7 +- SCons/Tool/f90.xml | 5 +- SCons/Tool/f95.xml | 5 +- SCons/Tool/fortran.xml | 13 ++- SCons/Tool/g77.py | 2 - SCons/Tool/g77.xml | 5 +- SCons/Tool/gfortran.py | 18 ++-- SCons/Tool/gfortran.xml | 19 +--- SCons/Tool/ifl.py | 21 ++-- SCons/Tool/ifort.py | 13 +-- test/Fortran/F77PATH.py | 78 ++++++-------- test/Fortran/F90PATH.py | 66 +++++------- test/Fortran/FORTRANCOMMONFLAGS.py | 132 +++++++++++++++++++++++ test/Fortran/FORTRANFILESUFFIXES2.py | 43 ++++---- test/Fortran/FORTRANPATH.py | 54 +++++----- test/Fortran/fixture/myfortran.py | 17 +-- test/Fortran/fixture/myfortran_flags.py | 17 +-- 22 files changed, 406 insertions(+), 305 deletions(-) create mode 100644 test/Fortran/FORTRANCOMMONFLAGS.py diff --git a/CHANGES.txt b/CHANGES.txt index 28785e1..d221603 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 abecf39..4f42e8c 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 cad16b6..f889383 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 #XXX{dialect}' + env[f'{dialect}PPCOM'] = f'${dialect} -o $TARGET -c $FORTRANCOMMONFLAGS ${dialect}FLAGS $CPPFLAGS $_CPPDEFFLAGS $_{dialect}INCFLAGS $_FORTRANMODFLAG $SOURCES #XXXPP{dialect}' + env[f'SH{dialect}COM'] = f'$SH{dialect} -o $TARGET -c $FORTRANCOMMONFLAGS $SH{dialect}FLAGS $_{dialect}INCFLAGS $_FORTRANMODFLAG $SOURCES #XXX{dialect}' + env[f'SH{dialect}PPCOM'] = f'$SH{dialect} -o $TARGET -c $FORTRANCOMMONFLAGS $SH{dialect}FLAGS $CPPFLAGS $_CPPDEFFLAGS $_{dialect}INCFLAGS $_FORTRANMODFLAG $SOURCES #XXXPP{dialect}' 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 #XXX{dialect}' + env[f'{dialect}PPCOM'] = f'${dialect} -o $TARGET -c $FORTRANCOMMONFLAGS ${dialect}FLAGS $CPPFLAGS $_CPPDEFFLAGS $_{dialect}INCFLAGS $SOURCES #XXXPP{dialect}' + env[f'SH{dialect}COM'] = f'$SH{dialect} -o $TARGET -c $FORTRANCOMMONFLAGS $SH{dialect}FLAGS $_{dialect}INCFLAGS $SOURCES #XXX{dialect}' + env[f'SH{dialect}PPCOM'] = f'$SH{dialect} -o $TARGET -c $FORTRANCOMMONFLAGS $SH{dialect}FLAGS $CPPFLAGS $_CPPDEFFLAGS $_{dialect}INCFLAGS $SOURCES #XXXPP{dialect}' + -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 fc14ace..c989385 100644 --- a/SCons/Tool/f03.xml +++ b/SCons/Tool/f03.xml @@ -1,6 +1,6 @@ @@ -5585,38 +5605,37 @@ and the list of sources for this builder. def e(target, source, env): - return (target + ['foo.foo'], source + ['foo.src']) + return target + ['foo.foo'], source + ['foo.src'] # Simple association of an emitter function with a Builder. -b = Builder("my_build < $TARGET > $SOURCE", - emitter = e) +b = Builder("my_build < $TARGET > $SOURCE", emitter=e) def e2(target, source, env): - return (target + ['bar.foo'], source + ['bar.src']) + return target + ['bar.foo'], source + ['bar.src'] # Simple association of a list of emitter functions with a Builder. -b = Builder("my_build < $TARGET > $SOURCE", - emitter = [e, e2]) +b = Builder("my_build < $TARGET > $SOURCE", emitter=[e, e2]) -# Calling an emitter function through a &consvar;. +# Calling an emitter function through a construction variable. env = Environment(MY_EMITTER=e) -b = Builder("my_build < $TARGET > $SOURCE", - emitter='$MY_EMITTER') +b = Builder("my_build < $TARGET > $SOURCE", emitter='$MY_EMITTER') -# Calling a list of emitter functions through a &consvar;. +# Calling a list of emitter functions through a construction variable. env = Environment(EMITTER_LIST=[e, e2]) -b = Builder("my_build < $TARGET > $SOURCE", - emitter='$EMITTER_LIST') +b = Builder("my_build < $TARGET > $SOURCE", emitter='$EMITTER_LIST') # Associating multiple emitters with different file # suffixes using a dictionary. def e_suf1(target, source, env): - return (target + ['another_target_file'], source) + return target + ['another_target_file'], source + def e_suf2(target, source, env): - return (target, source + ['another_source_file']) -b = Builder("my_build < $TARGET > $SOURCE", - emitter={'.suf1' : e_suf1, - '.suf2' : e_suf2}) + return target, source + ['another_source_file'] + +b = Builder( + action="my_build < $TARGET > $SOURCE", + emitter={'.suf1': e_suf1, '.suf2': e_suf2} +) -- cgit v0.12 From 869c75679492039a5dcb1f66fd9a78d59a4340da Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 20 Jun 2022 08:58:35 -0600 Subject: A few more tweaks in Builder Methods intro [skip appveyor] Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 50 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 8e64290..2e7784c 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -2675,7 +2675,7 @@ and a same-named environment method that splits a single string into a list, using strings of white-space characters as the delimiter -(similar to the Python string split +(similar to the &Python; string split method, but succeeds even if the input isn't a string). @@ -2697,7 +2697,7 @@ env.Program('bar', source='bar.c foo.c'.split()) Sources and targets can be specified as a a scalar or as a list, either of strings or nodes (more on nodes below). When specifying path strings, -Python follows the POSIX pathname convention: +&Python; follows the POSIX pathname convention: if a string begins with the operating system pathname separator (on Windows both the slash and backslash separator are accepted, and any leading drive specifier is ignored for @@ -2806,7 +2806,7 @@ env.Program('build/prog', ['f1.c', 'f2.c'], srcdir='src') The optional parse_flags -keyword argument causes behavior similarly to the +keyword argument causes behavior similarl to the &f-link-env-MergeFlags; method, where the argument value is broken into individual settings and merged into the appropriate &consvars;. @@ -2861,15 +2861,13 @@ env.Command('sub/dir/foo.out', 'sub/dir/foo.in', "cp foo.in foo.out", chdir=True not automatically modify its expansion of -&consvars; like -$TARGET -and -$SOURCE +&consvars; like &cv-link-TARGET; +and &cv-link-SOURCE; when using the chdir keyword argument--that is, the expanded file names will still be relative to -the top-level directory where &SConstruct; was found, +the top-level directory where the &SConstruct; was found, and consequently incorrect relative to the chdir directory. If you use the chdir keyword argument, @@ -2880,7 +2878,7 @@ expansions like and ${SOURCE.file} to use just the filename portion of the -targets and source. +target and source. Keyword arguments that are not specifically recognized are treated as &consvar; @@ -2911,7 +2909,7 @@ env.SharedLibrary( and &cv-link-LIBSUFFIXES; &consvars; must be set if you want &scons; to search automatically for dependencies on the non-standard library names; -see the descriptions below of these variables for more information. +see the descriptions of these variables for more information. Although the builder methods defined by &scons; @@ -2930,11 +2928,11 @@ SharedLibrary('word', 'word.cpp') has determined are appropriate for the local system. Builder methods that can be called without an explicit -environment (indicated in the listing of builders without -a leading env.) -may be called from custom Python modules that you +environment (indicated in the listing of builders below +without a leading env.) +may be called from custom &Python; modules that you import into an SConscript file by adding the following -to the Python module: +to the &Python; module: from SCons.Script import * @@ -2942,17 +2940,17 @@ from SCons.Script import * A builder may add additional targets -(and, in fact, sources) beyond those requested, +beyond those requested if an attached Emitter chooses to do so -(see and, as an example, -&cv-link-PROGEMITTER;, for more information). +(see for more information. +&cv-link-PROGEMITTER; is an example). For example, the GNU linker takes a command-line argument , which causes it to produce a linker map file in addition to the executable file actually being linked. If the &b-link-Program; builder's emitter is configured to add this mapfile if the option is set, -two targets will be returned when you only asked for one. +then two targets will be returned when you only asked for one. @@ -3000,7 +2998,7 @@ contain elements which are themselves lists, such as bar_obj_list returned by the &b-link-StaticObject; call. If you need to manipulate a list of lists returned by builders -directly in Python code, +directly in &Python; code, you can either build a new list by hand: @@ -3025,19 +3023,19 @@ for obj in objects: Since builder calls return -a list-like object, not an actual Python list, -it is not appropriate to use the Python add +a list-like object, not an actual &Python; list, +it is not appropriate to use the &Python; add operator (+ or +=) -to append builder results to a Python list. +to append builder results to a &Python; list. Because the list and the object are different types, -Python will not update the original list in place, +&Python; will not update the original list in place, but will instead create a new NodeList object containing the concatenation of the list elements and the builder results. -This will cause problems for any other Python variables +This will cause problems for any other &Python; variables in your SCons configuration that still hold on to a reference to the original list. -Instead, use the Python list +Instead, use the &Python; list extend method to make sure the list is updated in-place. Example: @@ -3055,7 +3053,7 @@ object_files.extend(Object('bar.c')) The path name for a Node's file may be used -by passing the Node to Python's builtin +by passing the Node to &Python;'s builtin str function: -- cgit v0.12 From 56d8f264280d47bafa19ce982641191bfca5cad2 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 25 Jun 2022 10:56:42 -0400 Subject: updated blurb in CHANGES.txt and RELEASE.txt to indicate more specifically what's fixed. Address a few lint issues in the lex.py file --- CHANGES.txt | 5 ++--- RELEASE.txt | 5 +++-- SCons/Tool/lex.py | 13 ++++++++----- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c986c1e..87766c3 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -135,9 +135,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER Note that these are called for every build command run by SCons. It could have considerable performance impact if not used carefully. to connect to the server during start up. - - Updated lex emitter to respect escaped spaces when climbing out of a the SConscript dir. - Previously if the build/source directories absolute path included a space the lex emitter - would fail to use the correct paths. + - lex: Fixed an issue with the lex tool where file arguments specified to either "--header-file=" + or "--tables-file=" which included a space in the path to the file would be processed incorrectly - Ninja: added option "--skip-ninja-regen" to enable skipping regeneration of the ninja file if scons can determine the ninja file doesnot need to be regenerated, which will also skip restarting the scons daemon. Note this option is could result in incorrect rebuilds diff --git a/RELEASE.txt b/RELEASE.txt index da580b8..fce184f 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -111,9 +111,9 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY if scons can determine the ninja file doesnot need to be regenerated, which will also skip restarting the scons daemon. Note this option is could result in incorrect rebuilds if scons Glob or scons generated files are used in ninja build target's command lines. + FIXES ----- - - Fix a number of Python ResourceWarnings which are issued when running SCons and/or it's tests with python 3.9 (or higher) - Ninja: Fix issue where Configure files weren't being properly processed when build run @@ -156,7 +156,8 @@ FIXES - The system environment variable names imported for MSVC 7.0 and 6.0 were updated to be consistent with the variables names defined by their respective installers. This fixes an error caused when bypassing MSVC detection by specifying the MSVC 7.0 batch file directly. -- Updated lex emitter to respect escaped spaces when climbing out of a the SConscript dir +- lex: Fixed an issue with the lex tool where file arguments specified to either "--header-file=" + or "--tables-file=" which included a space in the path to the file would be processed incorrectly - Suppress issuing a warning when there are no installed Visual Studio instances for the default tools configuration (issue #2813). When msvc is the default compiler because there are no compilers installed, a build may fail due to the cl.exe command not being recognized. At diff --git a/SCons/Tool/lex.py b/SCons/Tool/lex.py index c33d0fa..96f9bcb 100644 --- a/SCons/Tool/lex.py +++ b/SCons/Tool/lex.py @@ -46,6 +46,7 @@ if sys.platform == 'win32': else: BINS = ["flex", "lex"] + def lexEmitter(target, source, env): sourceBase, sourceExt = os.path.splitext(SCons.Util.to_String(source[0])) @@ -56,18 +57,19 @@ def lexEmitter(target, source, env): # files generated by flex. # Different options that are used to trigger the creation of extra files. - fileGenOptions = ["--header-file=", "--tables-file="] + file_gen_options = ["--header-file=", "--tables-file="] lexflags = env.subst_list("$LEXFLAGS", target=target, source=source) for option in SCons.Util.CLVar(lexflags): - for fileGenOption in fileGenOptions: + for fileGenOption in file_gen_options: l = len(fileGenOption) if option[:l] == fileGenOption: # A file generating option is present, so add the # file name to the target list. - fileName = option[l:].strip() - target.append(fileName) - return (target, source) + file_name = option[l:].strip() + target.append(file_name) + return target, source + def get_lex_path(env, append_paths=False): """ @@ -128,6 +130,7 @@ def generate(env): env["LEX"] = env.Detect(BINS) env["LEXCOM"] = "$LEX $LEXFLAGS -t $SOURCES > $TARGET" + def exists(env): if sys.platform == 'win32': return get_lex_path(env) -- cgit v0.12 From 9b7ba04890c6a88b49ff282659199183dda996f9 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 25 Jun 2022 14:06:38 -0400 Subject: Minor edits. Link to Action Objects instead of just referencing it, and removed extraneous '(see)' --- SCons/Environment.xml | 2 +- doc/man/scons.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SCons/Environment.xml b/SCons/Environment.xml index 23fba62..485fe39 100644 --- a/SCons/Environment.xml +++ b/SCons/Environment.xml @@ -1646,7 +1646,7 @@ and then executed. Any additional arguments to &f-Execute; are passed on to the &f-link-Action; factory function which actually creates the Action object -(see the manpage section "Action Objects" +(see the manpage section Action Objects for a description). Example: diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 8545cb7..ef96d28 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -6076,7 +6076,7 @@ keyword arguments may not both be supplied in a single call to &f-Action; Printing of action strings is affected by the setting of -&cv-link-PRINT_CMD_LINE_FUNC; (see). +&cv-link-PRINT_CMD_LINE_FUNC;. Examples: -- cgit v0.12 From 773f267b2ec42b4e629d01bab51f69d49d1605c8 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 25 Jun 2022 15:31:38 -0400 Subject: minor edits plus adding a warning about using chdir --- doc/man/scons.xml | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 2e7784c..19f5eb1 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -2635,7 +2635,7 @@ often (though not always) by tools which determine whether the external dependencies for the builder are satisfied, and which perform the necessary setup (see Tools). -Builers are attached to a &consenv; as methods. +Builders are attached to a &consenv; as methods. The available builder methods are registered as key-value pairs in the &cv-link-BUILDERS; attribute of the &consenv;, @@ -2694,8 +2694,8 @@ env.Program('bar', source='bar.c foo.c'.split()) -Sources and targets can be specified as a a scalar or as a list, -either of strings or nodes (more on nodes below). +Sources and targets can be specified as a scalar or as a list, +composed of either strings or nodes (more on nodes below). When specifying path strings, &Python; follows the POSIX pathname convention: if a string begins with the operating system pathname separator @@ -2806,7 +2806,7 @@ env.Program('build/prog', ['f1.c', 'f2.c'], srcdir='src') The optional parse_flags -keyword argument causes behavior similarl to the +keyword argument causes behavior similar to the &f-link-env-MergeFlags; method, where the argument value is broken into individual settings and merged into the appropriate &consvars;. @@ -2841,6 +2841,23 @@ and evaluates true, then &scons; will change to the target file's directory. + + +Python only keeps one current directory +location even if there are multiple threads. +This means that use of the +chdir +argument +will +not +work with the SCons + +option, +because individual worker threads spawned +by SCons interfere with each other +when they start changing directory. + + # scons will change to the "sub" subdirectory # before executing the "cp" command. @@ -2950,7 +2967,7 @@ which causes it to produce a linker map file in addition to the executable file actually being linked. If the &b-link-Program; builder's emitter is configured to add this mapfile if the option is set, -then two targets will be returned when you only asked for one. +then two targets will be returned when you only provided for one. -- cgit v0.12