summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Brill <48932340+jcbrill@users.noreply.github.com>2022-06-26 11:40:02 (GMT)
committerJoseph Brill <48932340+jcbrill@users.noreply.github.com>2022-06-26 11:40:02 (GMT)
commit0b5f192428beb061d77d707d1e010c6119528a57 (patch)
tree4ca0a529e3369dbcdb46656f4eb85b57f2ed2df3
parent607d719e44d58de52f261b95a6c7c8a4dfa5b225 (diff)
parent07dc10b25b6169c9fb7e16dd78de8bb9ea107be6 (diff)
downloadSCons-0b5f192428beb061d77d707d1e010c6119528a57.zip
SCons-0b5f192428beb061d77d707d1e010c6119528a57.tar.gz
SCons-0b5f192428beb061d77d707d1e010c6119528a57.tar.bz2
Merge branch 'master' into jbrill-msvc-batchargs
-rwxr-xr-xCHANGES.txt8
-rwxr-xr-xRELEASE.txt6
-rw-r--r--SCons/Action.xml79
-rw-r--r--SCons/Environment.xml50
-rw-r--r--SCons/Tool/FortranCommon.py178
-rw-r--r--SCons/Tool/f03.xml5
-rw-r--r--SCons/Tool/f08.xml5
-rw-r--r--SCons/Tool/f77.xml7
-rw-r--r--SCons/Tool/f90.xml5
-rw-r--r--SCons/Tool/f95.xml5
-rw-r--r--SCons/Tool/fortran.xml13
-rw-r--r--SCons/Tool/g77.py2
-rw-r--r--SCons/Tool/g77.xml27
-rw-r--r--SCons/Tool/gfortran.py18
-rw-r--r--SCons/Tool/gfortran.xml5
-rw-r--r--SCons/Tool/ifl.py21
-rw-r--r--SCons/Tool/ifort.py13
-rw-r--r--SCons/Tool/lex.py15
-rw-r--r--doc/man/scons.xml423
-rw-r--r--test/Fortran/F77PATH.py78
-rw-r--r--test/Fortran/F90PATH.py66
-rw-r--r--test/Fortran/FORTRANCOMMONFLAGS.py132
-rw-r--r--test/Fortran/FORTRANFILESUFFIXES2.py43
-rw-r--r--test/Fortran/FORTRANPATH.py54
-rw-r--r--test/Fortran/fixture/myfortran.py17
-rw-r--r--test/Fortran/fixture/myfortran_flags.py17
-rw-r--r--test/LEX/lex_headerfile.py44
-rw-r--r--test/LEX/lex_headerfile/spaced path/SConstruct2
-rw-r--r--test/LEX/lex_headerfile/spaced path/src/SConscript10
-rw-r--r--test/LEX/lex_headerfile/spaced path/src/lexer.l1
-rw-r--r--test/LEX/lex_headerfile/spaced path/src/lexer2.l1
31 files changed, 808 insertions, 542 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 28785e1..bea5838 100755
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -135,6 +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.
+ - 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
@@ -194,6 +196,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..c86c1d5 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
@@ -111,9 +113,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,6 +158,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.
+- 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/Action.xml b/SCons/Action.xml
index 1346db2..209c389 100644
--- a/SCons/Action.xml
+++ b/SCons/Action.xml
@@ -130,44 +130,65 @@ A Python function used to print the command lines as they are executed
or
<option>-s</option>
options or their equivalents).
-The function should take four arguments:
+The function must accept four arguments:
<varname>s</varname>,
-the command being executed (a string),
<varname>target</varname>,
-the target being built (file node, list, or string name(s)),
+<varname>source</varname> and
+<varname>env</varname>.
+<varname>s</varname>
+is a string showing the command being executed,
+<varname>target</varname>,
+is the target being built (file node, list, or string name(s)),
<varname>source</varname>,
-the source(s) used (file node, list, or string name(s)), and
-<varname>env</varname>,
-the environment being used.
+is the source(s) used (file node, list, or string name(s)),
+and <varname>env</varname>
+is the environment being used.
</para>
<para>
-The function must do the printing itself. The default implementation,
-used if this variable is not set or is None, is:
+The function must do the printing itself.
+The default implementation,
+used if this variable is not set or is <constant>None</constant>,
+is to just print the string, as in:
</para>
<example_commands>
def print_cmd_line(s, target, source, env):
- sys.stdout.write(s + "\n")
+ sys.stdout.write(s + "\n")
</example_commands>
<para>
-Here's an example of a more interesting function:
+Here is an example of a more interesting function:
</para>
<example_commands>
def print_cmd_line(s, target, source, env):
- sys.stdout.write("Building %s -> %s...\n" %
- (' and '.join([str(x) for x in source]),
- ' and '.join([str(x) for x in target])))
-env=Environment(PRINT_CMD_LINE_FUNC=print_cmd_line)
-env.Program('foo', 'foo.c')
+ sys.stdout.write(
+ "Building %s -> %s...\n"
+ % (
+ ' and '.join([str(x) for x in source]),
+ ' and '.join([str(x) for x in target]),
+ )
+ )
+
+env = Environment(PRINT_CMD_LINE_FUNC=print_cmd_line)
+env.Program('foo', ['foo.c', 'bar.c'])
</example_commands>
<para>
-This just prints "Building <varname>targetname</varname> from <varname>sourcename</varname>..." instead
-of the actual commands.
-Such a function could also log the actual commands to a log file,
-for example.
+This prints:
+</para>
+
+<screen>
+...
+scons: Building targets ...
+Building bar.c -> bar.o...
+Building foo.c -> foo.o...
+Building foo.o and bar.o -> foo...
+scons: done building targets.
+</screen>
+
+<para>
+Another example could be a function that logs the actual commands to a file.
</para>
</summary>
</cvar>
@@ -176,7 +197,7 @@ for example.
<summary>
<para>
A command interpreter function that will be called to execute command line
-strings. The function must expect the following arguments:
+strings. The function must accept five arguments:
</para>
<example_commands>
@@ -184,18 +205,18 @@ def spawn(shell, escape, cmd, args, env):
</example_commands>
<para>
-<varname>sh</varname>
-is a string naming the shell program to use.
+<varname>shell</varname>
+is a string naming the shell program to use,
<varname>escape</varname>
is a function that can be called to escape shell special characters in
-the command line.
+the command line,
<varname>cmd</varname>
-is the path to the command to be executed.
+is the path to the command to be executed,
<varname>args</varname>
-is the arguments to the command.
+holds the arguments to the command and
<varname>env</varname>
-is a dictionary of the environment variables
-in which the command should be executed.
+is a dictionary of environment variables
+defining the execution environment in which the command should be executed.
</para>
</summary>
</cvar>
@@ -222,9 +243,9 @@ targets.
def custom_shell_env(env, target, source, shell_env):
"""customize shell_env if desired"""
if str(target[0]) == 'special_target':
- shell_env['SPECIAL_VAR'] = env.subst('SOME_VAR', target=target, source=source)
+ shell_env['SPECIAL_VAR'] = env.subst('SOME_VAR', target=target, source=source)
return shell_env
-
+
env["SHELL_ENV_GENERATORS"] = [custom_shell_env]
</example_commands>
diff --git a/SCons/Environment.xml b/SCons/Environment.xml
index 5c4326c..485fe39 100644
--- a/SCons/Environment.xml
+++ b/SCons/Environment.xml
@@ -1630,46 +1630,50 @@ See the manpage section "Construction Environments" for more details.
<scons_function name="Execute">
<arguments>
-(action, [strfunction, varlist])
+(action, [actionargs ...])
</arguments>
<summary>
<para>
-Executes an Action object.
-The specified
+Executes an Action.
<parameter>action</parameter>
may be an Action object
-(see manpage section "Action Objects"
-for an explanation of behavior),
or it may be a command-line string,
list of commands,
or executable &Python; function,
-each of which will be converted
+each of which will first be converted
into an Action object
and then executed.
Any additional arguments to &f-Execute;
-(<parameter>strfunction</parameter>, <parameter>varlist</parameter>)
are passed on to the &f-link-Action; factory function
-which actually creates the Action object.
-The exit value of the command
-or return value of the &Python; function
-will be returned.
+which actually creates the Action object
+(see the manpage section <link linkend="action_objects">Action Objects</link>
+for a description). Example:
+</para>
+
+<example_commands>
+Execute(Copy('file.out', 'file.in'))
+</example_commands>
+
+<para>&f-Execute; performs its action immediately,
+as part of the SConscript-reading phase.
+There are no sources or targets declared in an
+&f-Execute; call, so any objects it manipulates
+will not be tracked as part of the &SCons; dependency graph.
+In the example above, neither
+<filename>file.out</filename> nor
+<filename>file.in</filename> will be tracked objects.
</para>
<para>
-Note that
+&f-Execute; returns the exit value of the command
+or return value of the &Python; function.
&scons;
-will print an error message if the executed
+prints an error message if the executed
<parameter>action</parameter>
-fails--that is,
-exits with or returns a non-zero value.
-&scons;
-will
+fails (exits with or returns a non-zero value),
+however it does
<emphasis>not</emphasis>,
-however,
-automatically terminate the build
-if the specified
-<parameter>action</parameter>
-fails.
+automatically terminate the build for such a failure.
If you want the build to stop in response to a failed
&f-Execute;
call,
@@ -1677,8 +1681,6 @@ you must explicitly check for a non-zero return value:
</para>
<example_commands>
-Execute(Copy('file.out', 'file.in'))
-
if Execute("mkdir sub/dir/ectory"):
# The mkdir failed, don't try to build.
Exit(1)
diff --git a/SCons/Tool/FortranCommon.py b/SCons/Tool/FortranCommon.py
index cad16b6..aff0f92 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 fc14ace..c989385 100644
--- a/SCons/Tool/f03.xml
+++ b/SCons/Tool/f03.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
-__COPYRIGHT__
+Copyright The SCons Foundation
This file is processed by the bin/SConsDoc.py module.
See its __doc__ string for a discussion of the format.
@@ -45,6 +45,7 @@ Set construction variables for generic POSIX Fortran 03 compilers.
<item>F03PPCOMSTR</item>
<item>SHF03COMSTR</item>
<item>SHF03PPCOMSTR</item>
+<item>FORTRANCOMMONFLAGS</item>
</uses>
</tool>
@@ -271,7 +272,7 @@ Options that are passed to the Fortran 03 compiler
to generated shared-library objects.
You only need to set &cv-link-SHF03FLAGS; if you need to define specific
user options for Fortran 03 files.
-You should normally set the &cv-link-SHFORTRANFLAGS; variable,
+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.
diff --git a/SCons/Tool/f08.xml b/SCons/Tool/f08.xml
index fa7f633..8f69b93 100644
--- a/SCons/Tool/f08.xml
+++ b/SCons/Tool/f08.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
-__COPYRIGHT__
+Copyright The SCons Foundation
This file is processed by the bin/SConsDoc.py module.
See its __doc__ string for a discussion of the format.
@@ -45,6 +45,7 @@ Set construction variables for generic POSIX Fortran 08 compilers.
<item>F08PPCOMSTR</item>
<item>SHF08COMSTR</item>
<item>SHF08PPCOMSTR</item>
+<item>FORTRANCOMMONFLAGS</item>
</uses>
</tool>
@@ -271,7 +272,7 @@ Options that are passed to the Fortran 08 compiler
to generated shared-library objects.
You only need to set &cv-link-SHF08FLAGS; if you need to define specific
user options for Fortran 08 files.
-You should normally set the &cv-link-SHFORTRANFLAGS; variable,
+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.
diff --git a/SCons/Tool/f77.xml b/SCons/Tool/f77.xml
index cade57f..f60d617 100644
--- a/SCons/Tool/f77.xml
+++ b/SCons/Tool/f77.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
-__COPYRIGHT__
+Copyright The SCons Foundation
This file is processed by the bin/SConsDoc.py module.
See its __doc__ string for a discussion of the format.
@@ -58,6 +58,9 @@ Set construction variables for generic POSIX Fortran 77 compilers.
<item>SHF77PPCOMSTR</item>
<item>SHFORTRANCOMSTR</item>
<item>SHFORTRANPPCOMSTR</item>
+<item>FORTRANFLAGS</item>
+<item>FORTRANCOMMONFLAGS</item>
+<item>SHFORTRANFLAGS</item>
</uses>
</tool>
@@ -284,7 +287,7 @@ Options that are passed to the Fortran 77 compiler
to generated shared-library objects.
You only need to set &cv-link-SHF77FLAGS; if you need to define specific
user options for Fortran 77 files.
-You should normally set the &cv-link-SHFORTRANFLAGS; variable,
+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.
diff --git a/SCons/Tool/f90.xml b/SCons/Tool/f90.xml
index 343aefe..ab76def 100644
--- a/SCons/Tool/f90.xml
+++ b/SCons/Tool/f90.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
-__COPYRIGHT__
+Copyright The SCons Foundation
This file is processed by the bin/SConsDoc.py module.
See its __doc__ string for a discussion of the format.
@@ -45,6 +45,7 @@ Set construction variables for generic POSIX Fortran 90 compilers.
<item>F90PPCOMSTR</item>
<item>SHF90COMSTR</item>
<item>SHF90PPCOMSTR</item>
+<item>FORTRANCOMMONFLAGS</item>
</uses>
</tool>
@@ -270,7 +271,7 @@ Options that are passed to the Fortran 90 compiler
to generated 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-SHFORTRANFLAGS; variable,
+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.
diff --git a/SCons/Tool/f95.xml b/SCons/Tool/f95.xml
index 3f38030..59cfd78 100644
--- a/SCons/Tool/f95.xml
+++ b/SCons/Tool/f95.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
-__COPYRIGHT__
+Copyright The SCons Foundation
This file is processed by the bin/SConsDoc.py module.
See its __doc__ string for a discussion of the format.
@@ -45,6 +45,7 @@ Set construction variables for generic POSIX Fortran 95 compilers.
<item>F95PPCOMSTR</item>
<item>SHF95COMSTR</item>
<item>SHF95PPCOMSTR</item>
+<item>FORTRANCOMMONFLAGS</item>
</uses>
</tool>
@@ -271,7 +272,7 @@ Options that are passed to the Fortran 95 compiler
to generated shared-library objects.
You only need to set &cv-link-SHF95FLAGS; if you need to define specific
user options for Fortran 95 files.
-You should normally set the &cv-link-SHFORTRANFLAGS; variable,
+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.
diff --git a/SCons/Tool/fortran.xml b/SCons/Tool/fortran.xml
index 4f0517b..5bb1bd2 100644
--- a/SCons/Tool/fortran.xml
+++ b/SCons/Tool/fortran.xml
@@ -102,7 +102,8 @@ FORTRAN dialect will be used. By default, this is <literal>['.fpp', '.FPP']</lit
<cvar name="FORTRANFLAGS">
<summary>
<para>
-General user-specified options that are passed to the Fortran compiler.
+General user-specified options for the FORTRAN dialect
+that are passed to the Fortran compiler.
Note that this variable does
<emphasis>not</emphasis>
contain
@@ -117,6 +118,16 @@ for the variables that expand those options.
</summary>
</cvar>
+<cvar name="FORTRANCOMMONFLAGS">
+<summary>
+<para>
+General user-specified options that are passed to the Fortran compiler.
+Similar to &cv-link-FORTRANFLAGS;,
+but this variable is applied to all dialects.
+</para>
+</summary>
+</cvar>
+
<cvar name="_FORTRANINCFLAGS">
<summary>
<para>
diff --git a/SCons/Tool/g77.py b/SCons/Tool/g77.py
index e61181e..aea419a 100644
--- a/SCons/Tool/g77.py
+++ b/SCons/Tool/g77.py
@@ -22,13 +22,11 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
-
Tool-specific initialization for g77.
There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
selection method.
-
"""
import SCons.Util
diff --git a/SCons/Tool/g77.xml b/SCons/Tool/g77.xml
index 40516ba..febfeb3 100644
--- a/SCons/Tool/g77.xml
+++ b/SCons/Tool/g77.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
-__COPYRIGHT__
+Copyright The SCons Foundation
This file is processed by the bin/SConsDoc.py module.
See its __doc__ string for a discussion of the format.
@@ -27,10 +27,31 @@ See its __doc__ string for a discussion of the format.
<summary>
<para>
Set construction variables for the &g77; Fortran compiler.
-Calls the &t-f77; Tool module
-to set variables.
</para>
</summary>
+<sets>
+<item>F77</item>
+<item>F77COM</item>
+<item>F77PPCOM</item>
+<item>F77FILESUFFIXES</item>
+<item>F77PPFILESUFFIXES</item>
+<item>FORTRAN</item>
+<item>FORTRANCOM</item>
+<item>FORTRANPPCOM</item>
+<item>SHF77</item>
+<item>SHF77COM</item>
+<item>SHF77PPCOM</item>
+<item>SHF77FLAGS</item>
+<item>SHFORTRAN</item>
+<item>SHFORTRANCOM</item>
+<item>SHFORTRANPPCOM</item>
+<item>SHFORTRANFLAGS</item>
+</sets>
+<uses>
+<item>F77FLAGS</item>
+<item>FORTRANFLAGS</item>
+<item>FORTRANCOMMONFLAGS</item>
+</uses>
</tool>
</sconsdoc>
diff --git a/SCons/Tool/gfortran.py b/SCons/Tool/gfortran.py
index c4ca295..3c7e8b5 100644
--- a/SCons/Tool/gfortran.py
+++ b/SCons/Tool/gfortran.py
@@ -22,17 +22,13 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
-
-Tool-specific initialization for gfortran, the GNU Fortran 95/Fortran
-2003 compiler.
+Tool-specific initialization for gfortran, the GNU Fortran compiler.
There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
selection method.
-
"""
-
import SCons.Util
from . import fortran
@@ -44,15 +40,15 @@ def generate(env):
fortran.generate(env)
for dialect in ['F77', 'F90', 'FORTRAN', 'F95', 'F03', 'F08']:
- env['%s' % dialect] = 'gfortran'
- env['SH%s' % dialect] = '$%s' % dialect
+ env[f'{dialect}'] = 'gfortran'
+ env[f'SH{dialect}'] = f'${dialect}'
if env['PLATFORM'] in ['cygwin', 'win32']:
- env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect)
+ env[f'SH{dialect}FLAGS'] = SCons.Util.CLVar(f'${dialect}FLAGS')
else:
- env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS -fPIC' % dialect)
+ env[f'SH{dialect}FLAGS'] = SCons.Util.CLVar(f'${dialect}FLAGS -fPIC')
- env['INC%sPREFIX' % dialect] = "-I"
- env['INC%sSUFFIX' % dialect] = ""
+ env[f'INC{dialect}PREFIX'] = "-I"
+ env[f'INC{dialect}SUFFIX'] = ""
env['FORTRANMODDIRPREFIX'] = "-J"
diff --git a/SCons/Tool/gfortran.xml b/SCons/Tool/gfortran.xml
index b5bad1a..95458fc 100644
--- a/SCons/Tool/gfortran.xml
+++ b/SCons/Tool/gfortran.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
-__COPYRIGHT__
+Copyright The SCons Foundation
This file is processed by the bin/SConsDoc.py module.
See its __doc__ string for a discussion of the format.
@@ -26,7 +26,8 @@ See its __doc__ string for a discussion of the format.
<tool name="gfortran">
<summary>
<para>
-Sets construction variables for the GNU F95/F2003 GNU compiler.
+Sets construction variables for the GNU Fortran compiler.
+Calls the &t-link-fortran; Tool module to set variables.
</para>
</summary>
<sets>
diff --git a/SCons/Tool/ifl.py b/SCons/Tool/ifl.py
index 865d2ba..5746950 100644
--- a/SCons/Tool/ifl.py
+++ b/SCons/Tool/ifl.py
@@ -1,15 +1,6 @@
-"""SCons.Tool.ifl
-
-Tool-specific initialization for the Intel Fortran compiler.
-
-There normally shouldn't be any need to import this module directly.
-It will usually be imported through the generic SCons.Tool.Tool()
-selection method.
-
-"""
-
+# MIT License
#
-# __COPYRIGHT__
+# 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
@@ -29,9 +20,13 @@ selection method.
# 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.
-#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+"""Tool-specific initialization for the Intel Fortran compiler.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+"""
import SCons.Defaults
from SCons.Scanner.Fortran import FortranScan
diff --git a/SCons/Tool/ifort.py b/SCons/Tool/ifort.py
index c8a6035..bf39b7f 100644
--- a/SCons/Tool/ifort.py
+++ b/SCons/Tool/ifort.py
@@ -22,17 +22,14 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
-
Tool-specific initialization for newer versions of the Intel Fortran Compiler
for Linux/Windows (and possibly Mac OS X).
There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
selection method.
-
"""
-
import SCons.Defaults
from SCons.Scanner.Fortran import FortranScan
from .FortranCommon import add_all_to_env
@@ -61,18 +58,18 @@ def generate(env):
fc = 'ifort'
for dialect in ['F77', 'F90', 'FORTRAN', 'F95']:
- env['%s' % dialect] = fc
- env['SH%s' % dialect] = '$%s' % dialect
+ env[f'{dialect}'] = fc
+ env[f'SH{dialect}'] = f'${dialect}'
if env['PLATFORM'] == 'posix':
- env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS -fPIC' % dialect)
+ env[f'SH{dialect}FLAGS'] = SCons.Util.CLVar(f'${dialect}FLAGS -fPIC')
if env['PLATFORM'] == 'win32':
# On Windows, the ifort compiler specifies the object on the
# command line with -object:, not -o. Massage the necessary
# command-line construction variables.
for dialect in ['F77', 'F90', 'FORTRAN', 'F95']:
- for var in ['%sCOM' % dialect, '%sPPCOM' % dialect,
- 'SH%sCOM' % dialect, 'SH%sPPCOM' % dialect]:
+ for var in [f'{dialect}COM', f'{dialect}PPCOM',
+ f'SH{dialect}COM', f'SH{dialect}PPCOM']:
env[var] = env[var].replace('-o $TARGET', '-object:$TARGET')
env['FORTRANMODDIRPREFIX'] = "/module:"
else:
diff --git a/SCons/Tool/lex.py b/SCons/Tool/lex.py
index d8d8de4..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("$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:
+ 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)
diff --git a/doc/man/scons.xml b/doc/man/scons.xml
index 4578d1c..3caa5ea 100644
--- a/doc/man/scons.xml
+++ b/doc/man/scons.xml
@@ -2612,28 +2612,35 @@ and specifically <link linkend='tool_modules'>Tool Modules</link>.
<refsect2 id='builder_methods'>
<title>Builder Methods</title>
-<para>You tell &scons; what to build
+<para>You tell &SCons; what to build
by calling <firstterm>Builders</firstterm>,
-functions which take
-particular action(s) to produce a particular result type
-(conventionally described by the builder name such as &b-Program;)
-when given source files of a particular type.
-Calling a builder defines one or more targets to the build system;
-whether the targets are actually built on a given
-invocation is determined by command-line options,
-target selection rules, and whether &SCons;
-determines the target(s) are out of date.
+functions which take particular action(s)
+to produce target(s) of a particular type
+(conventionally hinted at by the builder name, e.g. &Program;)
+from the specified source files.
+A builder call is a declaration: &SCons; enters the
+specified relationship into its internal dependency node graph,
+and only later makes the decision on whether anything is actually built,
+since this depends on command-line options,
+target selection rules, and whether the target(s) are
+out of date with respect to the sources.
</para>
<para>
&SCons;
-defines a number of builders, and you can also write your own.
-Builders are attached to a &consenv; as methods,
-and the available builder methods are listed as
+provides a number of builders, and you can also write your own
+(see <link linkend='builder_objects'>Builder Objects</link>).
+Builders are created dynamically at run-time,
+often (though not always) by tools which determine
+whether the external dependencies for the builder are satisfied,
+and which perform the necessary setup
+(see <link linkend='tools'>Tools</link>).
+Builders are attached to a &consenv; as methods.
+The available builder methods are registered as
key-value pairs in the
-<varname>BUILDERS</varname> attribute of the &consenv;.
-The available builders can be displayed like this
-for debugging purposes:
+&cv-link-BUILDERS; attribute of the &consenv;,
+so the available builders can be examined.
+This example displays them for debugging purposes:
</para>
<programlisting language="python">
@@ -2646,7 +2653,6 @@ Builder methods take two required arguments:
<parameter>target</parameter>
and
<parameter>source</parameter>.
-Either can be passed as a scalar or as a list.
The <parameter>target</parameter> and
<parameter>source</parameter> arguments
can be specified either as positional arguments,
@@ -2660,24 +2666,17 @@ Builder methods also take a variety of
keyword arguments, described below.
</para>
-<para>
-The builder <emphasis>may</emphasis> add other targets
-beyond those requested if indicated by an <firstterm>Emitter</firstterm>
-(see <xref linkend="builder_objects"/> and, for example,
-&cv-link-PROGEMITTER; for more information).
-</para>
-
<para>Because long lists of file names
-can lead to a lot of quoting,
-&scons;
+can lead to a lot of quoting in a builder call,
+&SCons;
supplies a &f-link-Split;
global function
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 <function>split</function>
-method, but succeeds even if the input isn't a string.)</para>
+strings of white-space characters as the delimiter
+(similar to the &Python; string <function>split</function>
+method, but succeeds even if the input isn't a string).</para>
<para>
The following are equivalent examples of calling the
@@ -2695,9 +2694,12 @@ env.Program('bar', source='bar.c foo.c'.split())
</programlisting>
<para>
-Python follows the POSIX pathname convention for path
-strings: if a string begins with the operating system pathname separator
-(on Windows both the slash and backslash separator work,
+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
+(on Windows both the slash and backslash separator are accepted,
and any leading drive specifier is ignored for
the determination) it is considered an absolute path,
otherwise it is a relative path.
@@ -2706,32 +2708,26 @@ it is searched for as a file in the current directory. If it
contains separator characters, the search follows down
from the starting point, which is the top of the directory tree for
an absolute path and the current directory for a relative path.
+The "current directory" in this context is the directory
+of the SConscript file currently being processed.
</para>
<para>
-&scons; recognizes a third way to specify
+&SCons; also recognizes a third way to specify
path strings: if the string begins with
the <emphasis role="bold">#</emphasis> character it is
<firstterm>top-relative</firstterm> - it works like a relative path but the
search follows down from the directory containing the top-level
&SConstruct; rather than
-from the current directory. The <emphasis role="bold">#</emphasis> is allowed
-to be followed by a pathname separator, which is ignored if
-found in that position.
+from the current directory. The <emphasis role="bold">#</emphasis>
+can optionally be followed by a pathname separator,
+which is ignored if found in that position.
Top-relative paths only work in places where &scons; will
interpret the path (see some examples below). To be
used in other contexts the string will need to be converted
to a relative or absolute path first.
</para>
-<para>
-<parameter>target</parameter> and <parameter>source</parameter>
-can be absolute, relative, or
-top-relative. Relative pathnames are searched considering the
-directory of the SConscript
-file currently being processed as the "current directory".
-</para>
-
<para>Examples:</para>
<programlisting language="python">
@@ -2786,14 +2782,12 @@ env.Program(source='bar.c')
env.Program('bar.c')
</programlisting>
-<para>As a convenience, a
+<para>The optional
<parameter>srcdir</parameter>
-keyword argument may be specified
-when calling a Builder.
-When specified,
+keyword argument specifies that
all source file strings that are not absolute paths
or top-relative paths
-will be interpreted relative to the specified
+shall be interpreted relative to the specified
<parameter>srcdir</parameter>.
The following example will build the
<filename>build/prog</filename>
@@ -2810,6 +2804,99 @@ and
env.Program('build/prog', ['f1.c', 'f2.c'], srcdir='src')
</programlisting>
+<para>The optional
+<parameter>parse_flags</parameter>
+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;.
+</para>
+
+<programlisting language="python">
+env.Program('hello', 'hello.c', parse_flags='-Iinclude -DEBUG -lm')
+</programlisting>
+
+<para>This example adds 'include' to
+the &cv-link-CPPPATH; &consvar;,
+'EBUG' to
+&cv-link-CPPDEFINES;,
+and 'm' to
+&cv-link-LIBS;.
+</para>
+
+<para>The optional
+<parameter>chdir</parameter>
+keyword argument
+specifies that the Builder's action(s)
+should be executed
+after changing directory.
+If the
+<parameter>chdir</parameter>
+argument is
+a path string or a directory Node,
+scons will change to the specified directory.
+If the
+<parameter>chdir</parameter>
+is not a string or Node
+and evaluates true,
+then &scons; will change to the
+target file's directory.</para>
+
+<warning>
+<para>
+Python only keeps one current directory
+location even if there are multiple threads.
+This means that use of the
+<parameter>chdir</parameter>
+argument
+will
+<emphasis>not</emphasis>
+work with the SCons
+<option>-j</option>
+option,
+because individual worker threads spawned
+by SCons interfere with each other
+when they start changing directory.</para>
+</warning>
+
+<programlisting language="python">
+# scons will change to the "sub" subdirectory
+# before executing the "cp" command.
+env.Command(
+ target='sub/dir/foo.out',
+ source='sub/dir/foo.in',
+ action="cp dir/foo.in dir/foo.out",
+ chdir='sub',
+)
+
+# Because chdir is not a string, scons will change to the
+# target's directory ("sub/dir") before executing the
+# "cp" command.
+env.Command('sub/dir/foo.out', 'sub/dir/foo.in', "cp foo.in foo.out", chdir=True)
+</programlisting>
+
+<para>Note that &SCons; will
+<emphasis>not</emphasis>
+automatically modify
+its expansion of
+&consvars; like &cv-link-TARGET;
+and &cv-link-SOURCE;
+when using the <parameter>chdir</parameter>
+keyword argument--that is,
+the expanded file names
+will still be relative to
+the top-level directory where the &SConstruct; was found,
+and consequently incorrect
+relative to the chdir directory.
+If you use the <parameter>chdir</parameter> keyword argument,
+you will typically need to supply a different
+command line using
+expansions like
+<literal>${TARGET.file}</literal>
+and
+<literal>${SOURCE.file}</literal>
+to use just the filename portion of the
+target and source.</para>
+
<para>Keyword arguments that are not specifically
recognized are treated as &consvar;
<firstterm>overrides</firstterm>,
@@ -2837,29 +2924,9 @@ env.SharedLibrary(
<para>Note that both the &cv-link-SHLIBSUFFIX;
and &cv-link-LIBSUFFIXES;
-variables must be set if you want &scons; to search automatically
+&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.</para>
-
-<para>The optional
-<parameter>parse_flags</parameter>
-keyword argument is recognized by builders.
-This works similarly to the
-&f-link-env-MergeFlags; method, where the argument value is
-broken into individual settings and merged into the appropriate &consvars;.
-</para>
-
-<programlisting language="python">
-env.Program('hello', 'hello.c', parse_flags='-Iinclude -DEBUG -lm')
-</programlisting>
-
-<para>This example adds 'include' to
-the &cv-link-CPPPATH; &consvar;,
-'EBUG' to
-&cv-link-CPPDEFINES;,
-and 'm' to
-&cv-link-LIBS;.
-</para>
+see the descriptions of these variables for more information.</para>
<para>Although the builder methods defined by
&scons;
@@ -2872,30 +2939,47 @@ Program('hello', 'hello.c')
SharedLibrary('word', 'word.cpp')
</programlisting>
-<para>If called this way, methods will internally use the
-&defenv; that consists of the tools and values that
+<para>If called this way, the builder will internally use the
+&DefEnv; that consists of the tools and values that
&scons;
has determined are appropriate for the local system.</para>
<para>Builder methods that can be called without an explicit
-environment (indicated in the listing of builders without
-a leading <varname>env.</varname>)
-may be called from custom Python modules that you
+environment (indicated in the listing of builders below
+without a leading <varname>env.</varname>)
+may be called from custom &Python; modules that you
import into an SConscript file by adding the following
-to the Python module:</para>
+to the &Python; module:</para>
<programlisting language="python">
from SCons.Script import *
</programlisting>
-<para>Builder methods return a <classname>NodeList</classname>,
-a list-like object whose elements are Nodes,
-&SCons;' internal representation of build targets or sources.
-See <xref linkend="node_objects"/> for more information.
+<para>
+A builder <emphasis>may</emphasis> add additional targets
+beyond those requested
+if an attached <firstterm>Emitter</firstterm> chooses to do so
+(see <xref linkend="builder_objects"/> for more information.
+&cv-link-PROGEMITTER; is an example).
+For example, the GNU linker takes a command-line argument
+<option>-Map=<replaceable>mapfile</replaceable></option>,
+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 provided for one.
+</para>
+
+<para>
+For this reason,
+builder methods always return a <classname>NodeList</classname>,
+a list-like object whose elements are Nodes.
+Nodes are the internal representation of build targets or sources
+(see <xref linkend="node_objects"/> for more information).
The returned <classname>NodeList</classname> object
can be passed to other builder methods as source(s)
-or passed to any &SCons; function or method
-where a filename would normally be accepted.
+or to other &SCons; functions or methods
+where a path string would normally be accepted.
</para>
<para> For example,
@@ -2912,7 +2996,7 @@ env.Program("prog", ['foo.c', bar_obj_list, 'main.c'])
makes for a more portable build
by avoiding having to specify
a platform-specific object suffix
-when calling the &Program; builder method.
+when calling the &b-link-Program; builder method.
</para>
<para>The <classname>NodeList</classname> object
@@ -2929,9 +3013,9 @@ Default(tgt)
lists passed as source and target, so they are free to
contain elements which are themselves lists, such as
<varname>bar_obj_list</varname>
-returned by the &StaticObject; call above.
+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:</para>
<programlisting language="python">
@@ -2943,7 +3027,7 @@ for obj in objects:
</programlisting>
<para>Or you can use the &f-link-Flatten;
-function supplied by &scons;
+function supplied by &SCons;
to create a list containing just the Nodes,
which may be more convenient:</para>
@@ -2955,20 +3039,20 @@ for obj in objects:
print(str(obj))
</programlisting>
-<para>&SCons; builder calls return
-a list-like object, not an actual Python list,
-so it is not appropriate to use the Python add
+<para>Since builder calls return
+a list-like object, not an actual &Python; list,
+it is not appropriate to use the &Python; add
operator (<literal>+</literal> or <literal>+=</literal>)
-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 <classname>NodeList</classname> 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
<function>extend</function>
method to make sure the list is updated in-place.
Example:</para>
@@ -2986,7 +3070,7 @@ object_files.extend(Object('bar.c'))
</programlisting>
<para>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
<function>str</function>
function:</para>
@@ -2997,69 +3081,11 @@ print("The path to bar_obj is:", str(bar_obj_list[0]))
<para>Note that because the Builder call returns a
<classname>NodeList</classname>,
-you have to access the first element in the list,
+you have to access the first element in the list
(<literal>bar_obj_list[0]</literal> in the example)
to get at the Node that actually represents
the object file.</para>
-<para>Builder calls support a
-<parameter>chdir</parameter>
-keyword argument that
-specifies that the Builder's action(s)
-should be executed
-after changing directory.
-If the
-<parameter>chdir</parameter>
-argument is
-a string or a directory Node,
-scons will change to the specified directory.
-If the
-<parameter>chdir</parameter>
-is not a string or Node
-and is non-zero,
-then scons will change to the
-target file's directory.</para>
-
-<programlisting language="python">
-# scons will change to the "sub" subdirectory
-# before executing the "cp" command.
-env.Command('sub/dir/foo.out', 'sub/dir/foo.in',
- "cp dir/foo.in dir/foo.out",
- chdir='sub')
-
-# Because chdir is not a string, scons will change to the
-# target's directory ("sub/dir") before executing the
-# "cp" command.
-env.Command('sub/dir/foo.out', 'sub/dir/foo.in',
- "cp foo.in foo.out",
- chdir=1)
-</programlisting>
-
-<para>Note that &SCons; will
-<emphasis>not</emphasis>
-automatically modify
-its expansion of
-&consvars; like
-<envar>$TARGET</envar>
-and
-<envar>$SOURCE</envar>
-when using the <parameter>chdir</parameter>
-keyword argument--that is,
-the expanded file names
-will still be relative to
-the top-level directory where &SConstruct; was found,
-and consequently incorrect
-relative to the chdir directory.
-If you use the <parameter>chdir</parameter> keyword argument,
-you will typically need to supply a different
-command line using
-expansions like
-<literal>${TARGET.file}</literal>
-and
-<literal>${SOURCE.file}</literal>
-to use just the filename portion of the
-targets and source.</para>
-
<para>
When trying to handle errors that may occur in a builder method,
consider that the corresponding Action is executed at a different
@@ -3073,13 +3099,22 @@ a useful exception message indicating the problem in the SConscript files -
programmatically recovering from build errors is rarely useful.
</para>
-<para>&scons;
-predefines the following builder methods.
+<para>
+The following builder methods are predefined in the
+&SCons; core software distribution.
Depending on the setup of a particular
&consenv; and on the type and software
installation status of the underlying system,
-not all builders may be available to that
-&consenv;.</para>
+not all builders may be available in that
+&consenv;.
+Since the function calling signature is the same for all builders:
+</para>
+<programlisting language="python">
+<function>Buildername</function>(<parameter>target, source, [key=val, ...]</parameter>)
+</programlisting>
+<para>
+it is omitted in this listing for brevity.
+</para>
<!-- '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -->
<!-- '\" BEGIN GENERATED BUILDER DESCRIPTIONS -->
@@ -5585,38 +5620,37 @@ and the list of sources for this builder.</para>
<programlisting language="python">
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 &lt; $TARGET &gt; $SOURCE",
- emitter = e)
+b = Builder("my_build &lt; $TARGET &gt; $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 &lt; $TARGET &gt; $SOURCE",
- emitter = [e, e2])
+b = Builder("my_build &lt; $TARGET &gt; $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 &lt; $TARGET &gt; $SOURCE",
- emitter='$MY_EMITTER')
+b = Builder("my_build &lt; $TARGET &gt; $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 &lt; $TARGET &gt; $SOURCE",
- emitter='$EMITTER_LIST')
+b = Builder("my_build &lt; $TARGET &gt; $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 &lt; $TARGET &gt; $SOURCE",
- emitter={'.suf1' : e_suf1,
- '.suf2' : e_suf2})
+ return target, source + ['another_source_file']
+
+b = Builder(
+ action="my_build &lt; $TARGET &gt; $SOURCE",
+ emitter={'.suf1': e_suf1, '.suf2': e_suf2}
+)
</programlisting>
</listitem>
</varlistentry>
@@ -5904,7 +5938,7 @@ you need to create the action object using &f-Action;.
returns an appropriate object for the action
represented by the type of the
<parameter>action</parameter> argument
-(the first positional parmeter):</para>
+(the first positional parameter):</para>
<itemizedlist>
<listitem>
@@ -6034,19 +6068,22 @@ The following argument types are accepted:
<itemizedlist>
<listitem>
-<para>If <parameter>output</parameter> is a string,
-substitution is performed on the string before it is printed.
-The string typically contains variables, notably
+<para>If the second argument is a string,
+or if the <parameter>cmdstr</parameter> keyword argument is supplied,
+the string defines what is printed.
+Substitution is performed on the string before it is printed.
+The string typically contains substitutable variables, notably
<literal>$TARGET(S)</literal> and <literal>$SOURCE(S)</literal>,
-or consists of just a single
-variable, which is optionally defined somewhere else.
+or consists of just a single variable
+which is optionally defined somewhere else.
&SCons; itself heavily uses the latter variant.</para>
</listitem>
<listitem>
-<para>If <parameter>output</parameter> is a function,
-the function will be called to obtain a string
-describing the action being executed.
+<para>If the second argument is a function,
+or if the <parameter>strfunction</parameter> keyword argument is supplied,
+the function will be called to obtain the string
+to be printed when the action is performed.
The function
must accept three keyword arguments:
<parameter>target</parameter>,
@@ -6054,22 +6091,26 @@ must accept three keyword arguments:
<parameter>env</parameter>,
with the same interpretation as for a callable
<parameter>action</parameter> argument above.
+The function is responsible for handling any required substitutions.
</para>
</listitem>
<listitem>
-<para>If <parameter>output</parameter>is <constant>None</constant>,
+<para>If the second argument is <constant>None</constant>,
+or if <literal>cmdstr=None</literal> is supplied,
output is suppressed entirely.</para>
</listitem>
</itemizedlist>
<para>
-Instead of using a positional argument,
-the <parameter>cmdstr</parameter>
-keyword argument may be used to specify the output string,
-or the <parameter>strfunction</parameter> keyword argument
-may be used to specify a function to return the output string.
-<literal>cmdstr=None</literal> suppresses output entirely.
+The <parameter>cmdstr</parameter> and
+<parameter>strfunction</parameter>
+keyword arguments may not both be supplied in a single call to &f-Action;
+</para>
+
+<para>
+Printing of action strings is affected by the setting of
+&cv-link-PRINT_CMD_LINE_FUNC;.
</para>
<para>Examples:</para>
diff --git a/test/Fortran/F77PATH.py b/test/Fortran/F77PATH.py
index 260782c..e594978 100644
--- a/test/Fortran/F77PATH.py
+++ b/test/Fortran/F77PATH.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# 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
@@ -20,9 +22,6 @@
# 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.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
@@ -39,30 +38,27 @@ test = TestSCons.TestSCons()
fc = 'f77'
if not test.detect_tool(fc):
- test.skip_test('Could not find a f77 tool; skipping test.\n')
-
-test.subdir('include',
- 'subdir',
- ['subdir', 'include'],
- 'foobar',
- 'inc2')
-
-
-
-test.write('SConstruct', """
-env = Environment(F77 = '%s',
- F77PATH = ['$FOO', '${TARGET.dir}', '${SOURCE.dir}'],
- FOO='include',
- F77FLAGS = '-x f77')
+ # gfortran names all variants the same, try it too
+ fc = 'gfortran'
+ if not test.detect_tool(fc):
+ test.skip_test('Could not find a f77 tool; skipping test.\n')
+
+test.subdir('include', 'subdir', ['subdir', 'include'], 'foobar', 'inc2')
+
+test.write('SConstruct', """\
+env = Environment(
+ F77='%s',
+ F77PATH=['$FOO', '${TARGET.dir}', '${SOURCE.dir}'],
+ FOO='include',
+ F77FLAGS='-x f77',
+)
obj = env.Object(target='foobar/prog', source='subdir/prog.f77')
env.Program(target='prog', source=obj)
SConscript('subdir/SConscript', "env")
VariantDir('variant', 'subdir', 0)
include = Dir('include')
-env = Environment(F77 = '%s',
- F77PATH=[include, '#foobar', '#subdir'],
- F77FLAGS = '-x f77')
+env = Environment(F77='%s', F77PATH=[include, '#foobar', '#subdir'], F77FLAGS='-x f77')
SConscript('variant/SConscript', "env")
""" % (fc, fc))
@@ -115,8 +111,6 @@ r"""
PRINT *, 'subdir/ttt.f77'
""")
-
-
test.run(arguments = args)
test.run(program = test.workpath(prog),
@@ -151,8 +145,6 @@ test.must_not_exist(test.workpath('variant', 'prog.f77'))
test.up_to_date(arguments = args)
-
-
test.write(['include', 'foo.f77'],
r"""
PRINT *, 'include/foo.f77 2'
@@ -193,9 +185,6 @@ test.must_not_exist(test.workpath('variant', 'prog.f77'))
test.up_to_date(arguments = args)
-
-
-#
test.write(['include', 'bar.f77'],
r"""
PRINT *, 'include/bar.f77 2'
@@ -235,22 +224,22 @@ test.must_not_exist(test.workpath('variant', 'prog.f77'))
test.up_to_date(arguments = args)
-
-
# Change F77PATH and make sure we don't rebuild because of it.
-test.write('SConstruct', """
-env = Environment(F77 = '%s',
- F77PATH = Split('inc2 include ${TARGET.dir} ${SOURCE.dir}'),
- F77FLAGS = '-x f77')
+test.write('SConstruct', """\
+env = Environment(
+ F77='%s',
+ F77PATH=Split('inc2 include ${TARGET.dir} ${SOURCE.dir}'),
+ F77FLAGS='-x f77',
+)
obj = env.Object(target='foobar/prog', source='subdir/prog.f77')
env.Program(target='prog', source=obj)
SConscript('subdir/SConscript', "env")
VariantDir('variant', 'subdir', 0)
include = Dir('include')
-env = Environment(F77 = '%s',
- F77PATH=['inc2', include, '#foobar', '#subdir'],
- F77FLAGS = '-x f77')
+env = Environment(
+ F77='%s', F77PATH=['inc2', include, '#foobar', '#subdir'], F77FLAGS='-x f77'
+)
SConscript('variant/SConscript', "env")
""" % (fc, fc))
@@ -294,20 +283,15 @@ test.run(program = test.workpath(variant_prog),
test.up_to_date(arguments = args)
-
-
# Check that a null-string F77PATH doesn't blow up.
-test.write('SConstruct', """
-env = Environment(tools = ['f77'], F77PATH = '', F77FLAGS = '-x f77')
-env.Object('foo', source = 'empty.f77')
-""")
+test.write('SConstruct', """\
+env = Environment(tools=['%s'], F77PATH='', F77FLAGS='-x f77')
+env.Object('foo', source='empty.f77')
+""" % fc)
test.write('empty.f77', '')
-
test.run(arguments = '.')
-
-
test.pass_test()
# Local Variables:
diff --git a/test/Fortran/F90PATH.py b/test/Fortran/F90PATH.py
index 341b241..58c6c90 100644
--- a/test/Fortran/F90PATH.py
+++ b/test/Fortran/F90PATH.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# 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
@@ -20,9 +22,6 @@
# 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.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
@@ -39,32 +38,29 @@ test = TestSCons.TestSCons()
fc = 'f90'
if not test.detect_tool(fc):
- test.skip_test('Could not find a f90 tool; skipping test.\n')
-
-test.subdir('include',
- 'subdir',
- ['subdir', 'include'],
- 'foobar',
- 'inc2')
-
+ # gfortran names all variants the same, try it too
+ fc = 'gfortran'
+ if not test.detect_tool(fc):
+ test.skip_test('Could not find a f90 tool; skipping test.\n')
+test.subdir('include', 'subdir', ['subdir', 'include'], 'foobar', 'inc2')
test.write('SConstruct', """
-env = Environment(F90 = r'%s',
- F90PATH = ['$FOO', '${TARGET.dir}', '${SOURCE.dir}'],
- LINK = '$F90',
- FOO='include')
+env = Environment(
+ F90=r'%s',
+ F90PATH=['$FOO', '${TARGET.dir}', '${SOURCE.dir}'],
+ LINK='$F90',
+ FOO='include',
+)
obj = env.Object(target='foobar/prog', source='subdir/prog.f90')
env.Program(target='prog', source=obj)
SConscript('subdir/SConscript', "env")
VariantDir('variant', 'subdir', 0)
include = Dir('include')
-env = Environment(F90 = r'%s',
- F90PATH=[include, '#foobar', '#subdir'],
- LINK = '$F90')
+env = Environment(F90=r'%s', F90PATH=[include, '#foobar', '#subdir'], LINK='$F90')
SConscript('variant/SConscript', "env")
-""" % (fc, fc, ))
+""" % (fc, fc))
test.write(['subdir', 'SConscript'],
"""
@@ -115,8 +111,6 @@ r"""
PRINT *, 'subdir/ttt.f90'
""")
-
-
test.run(arguments = args)
test.run(program = test.workpath(prog),
@@ -151,8 +145,6 @@ test.must_not_exist(test.workpath('variant', 'prog.f90'))
test.up_to_date(arguments = args)
-
-
test.write(['include', 'foo.f90'],
r"""
PRINT *, 'include/foo.f90 2'
@@ -193,9 +185,6 @@ test.must_not_exist(test.workpath('variant', 'prog.f90'))
test.up_to_date(arguments = args)
-
-
-#
test.write(['include', 'bar.f90'],
r"""
PRINT *, 'include/bar.f90 2'
@@ -238,27 +227,28 @@ test.up_to_date(arguments = args)
# Change F90PATH and make sure we don't rebuild because of it.
-test.write('SConstruct', """
-env = Environment(F90 = r'%s',
- F90PATH = Split('inc2 include ${TARGET.dir} ${SOURCE.dir}'),
- LINK = '$F90')
+test.write('SConstruct', """\
+env = Environment(
+ F90=r'%s',
+ F90PATH=Split('inc2 include ${TARGET.dir} ${SOURCE.dir}'),
+ LINK='$F90'
+)
obj = env.Object(target='foobar/prog', source='subdir/prog.f90')
env.Program(target='prog', source=obj)
SConscript('subdir/SConscript', "env")
VariantDir('variant', 'subdir', 0)
include = Dir('include')
-env = Environment(F90 = r'%s',
- F90PATH=['inc2', include, '#foobar', '#subdir'],
- LINK = '$F90')
+env = Environment(
+ F90=r'%s',
+ F90PATH=['inc2', include, '#foobar', '#subdir'],
+ LINK='$F90',
+)
SConscript('variant/SConscript', "env")
""" % (fc, fc))
test.up_to_date(arguments = args)
-
-
-#
test.write(['inc2', 'foo.f90'],
r"""
PRINT *, 'inc2/foo.f90 1'
@@ -296,8 +286,6 @@ test.run(program = test.workpath(variant_prog),
test.up_to_date(arguments = args)
-
-
test.pass_test()
# Local Variables:
diff --git a/test/Fortran/FORTRANCOMMONFLAGS.py b/test/Fortran/FORTRANCOMMONFLAGS.py
new file mode 100644
index 0000000..9030709
--- /dev/null
+++ b/test/Fortran/FORTRANCOMMONFLAGS.py
@@ -0,0 +1,132 @@
+#!/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 that while FORTRANFLAGS is not passed to another dialect,
+FORTRANCOMMONFLAGS is passed to both.
+"""
+
+import TestSCons
+
+_python_ = TestSCons._python_
+
+test = TestSCons.TestSCons()
+_exe = TestSCons._exe
+
+test.file_fixture('mylink.py')
+test.file_fixture(['fixture', 'myfortran_flags.py'])
+
+test.write('SConstruct', """
+env = Environment(
+ LINK=r'%(_python_)s mylink.py',
+ LINKFLAGS=[],
+ F90=r'%(_python_)s myfortran_flags.py g90',
+ F90FLAGS='-x',
+ FORTRAN=r'%(_python_)s myfortran_flags.py fortran',
+ FORTRANFLAGS='-y',
+ FORTRANCOMMONFLAGS='-z',
+)
+env.Program(target='test01', source='test01.f')
+env.Program(target='test02', source='test02.F')
+env.Program(target='test03', source='test03.for')
+env.Program(target='test04', source='test04.FOR')
+env.Program(target='test05', source='test05.ftn')
+env.Program(target='test06', source='test06.FTN')
+env.Program(target='test07', source='test07.fpp')
+env.Program(target='test08', source='test08.FPP')
+env.Program(target='test11', source='test11.f90')
+env.Program(target='test12', source='test12.F90')
+""" % locals())
+
+test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
+test.write('test02.F', "This is a .F file.\n#link\n#fortran\n")
+test.write('test03.for', "This is a .for file.\n#link\n#fortran\n")
+test.write('test04.FOR', "This is a .FOR file.\n#link\n#fortran\n")
+test.write('test05.ftn', "This is a .ftn file.\n#link\n#fortran\n")
+test.write('test06.FTN', "This is a .FTN file.\n#link\n#fortran\n")
+test.write('test07.fpp', "This is a .fpp file.\n#link\n#fortran\n")
+test.write('test08.FPP', "This is a .FPP file.\n#link\n#fortran\n")
+test.write('test11.f90', "This is a .f90 file.\n#link\n#g90\n")
+test.write('test12.F90', "This is a .F90 file.\n#link\n#g90\n")
+
+test.run(arguments = '.', stderr = None)
+
+test.must_match('test01' + _exe, " -c -z -y\nThis is a .f file.\n")
+test.must_match('test02' + _exe, " -c -z -y\nThis is a .F file.\n")
+test.must_match('test03' + _exe, " -c -z -y\nThis is a .for file.\n")
+test.must_match('test04' + _exe, " -c -z -y\nThis is a .FOR file.\n")
+test.must_match('test05' + _exe, " -c -z -y\nThis is a .ftn file.\n")
+test.must_match('test06' + _exe, " -c -z -y\nThis is a .FTN file.\n")
+test.must_match('test07' + _exe, " -c -z -y\nThis is a .fpp file.\n")
+test.must_match('test08' + _exe, " -c -z -y\nThis is a .FPP file.\n")
+test.must_match('test11' + _exe, " -c -z -x\nThis is a .f90 file.\n")
+test.must_match('test12' + _exe, " -c -z -x\nThis is a .F90 file.\n")
+
+
+fc = 'f90'
+g90 = test.detect_tool(fc)
+if g90:
+ test.file_fixture('wrapper.py')
+
+ test.write('SConstruct', """
+foo = Environment(F90='%(fc)s')
+f90 = foo.Dictionary('F90')
+bar = foo.Clone(F90=r'%(_python_)s wrapper.py ' + f90)
+foo.Program(target='foo', source='foo.f90')
+bar.Program(target='bar', source='bar.f90')
+""" % locals())
+
+ test.write('foo.f90', r"""
+ PROGRAM FOO
+ PRINT *,'foo.f90'
+ END
+""")
+
+ test.write('bar.f90', r"""
+ PROGRAM BAR
+ PRINT *,'bar.f90'
+ END
+""")
+
+ test.run(arguments='foo' + _exe, stderr=None)
+ test.run(program=test.workpath('foo'), stdout=" foo.f90\n")
+ test.must_not_exist('wrapper.out')
+
+ import sys
+
+ if sys.platform[:5] == 'sunos':
+ test.run(arguments='bar' + _exe, stderr=None)
+ else:
+ test.run(arguments='bar' + _exe)
+ test.run(program=test.workpath('bar'), stdout=" bar.f90\n")
+ test.must_match('wrapper.out', "wrapper.py\n")
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Fortran/FORTRANFILESUFFIXES2.py b/test/Fortran/FORTRANFILESUFFIXES2.py
index a57dd2a..15abd2d 100644
--- a/test/Fortran/FORTRANFILESUFFIXES2.py
+++ b/test/Fortran/FORTRANFILESUFFIXES2.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# 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
@@ -20,14 +22,11 @@
# 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.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import TestSCons
_python_ = TestSCons._python_
-_exe = TestSCons._exe
+_exe = TestSCons._exe
test = TestSCons.TestSCons()
@@ -35,28 +34,30 @@ test.file_fixture('mylink.py')
test.file_fixture(['fixture', 'myfortran.py'])
# Test non default file suffix: .f, .f90 and .f95 for FORTRAN
-test.write('SConstruct', """
-env = Environment(LINK = r'%(_python_)s mylink.py',
- LINKFLAGS = [],
- F77 = r'%(_python_)s myfortran.py g77',
- FORTRAN = r'%(_python_)s myfortran.py fortran',
- FORTRANFILESUFFIXES = ['.f', '.f95', '.f90', '.ffake'],
- tools = ['default', 'fortran'])
-#print(env.Dump())
-env.Program(target = 'test01', source = 'test01.f')
-env.Program(target = 'test02', source = 'test02.f90')
-env.Program(target = 'test03', source = 'test03.f95')
-env.Program(target = 'test04', source = 'test04.ffake')
-env.Program(target = 'test05', source = 'test05.f77')
+test.write('SConstruct', """\
+DefaultEnvironment(tools=[])
+env = Environment(
+ LINK=r'%(_python_)s mylink.py',
+ LINKFLAGS=[],
+ F77=r'%(_python_)s myfortran.py g77',
+ FORTRAN=r'%(_python_)s myfortran.py fortran',
+ FORTRANFILESUFFIXES=['.f', '.f95', '.f90', '.ffake'],
+ tools=['default', 'fortran'],
+)
+env.Program(target='test01', source='test01.f')
+env.Program(target='test02', source='test02.f90')
+env.Program(target='test03', source='test03.f95')
+env.Program(target='test04', source='test04.ffake')
+env.Program(target='test05', source='test05.f77')
""" % locals())
-test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
-test.write('test02.f90', "This is a .f90 file.\n#link\n#fortran\n")
+test.write('test01.f', "This is a .f file.\n#link\n#fortran\n")
+test.write('test02.f90', "This is a .f90 file.\n#link\n#fortran\n")
test.write('test03.f95', "This is a .f95 file.\n#link\n#fortran\n")
test.write('test04.ffake', "This is a .ffake file.\n#link\n#fortran\n")
test.write('test05.f77', "This is a .f77 file.\n#link\n#g77\n")
-test.run(arguments = '.', stderr = None)
+test.run(arguments='.', stderr=None)
test.must_match('test01' + _exe, "This is a .f file.\n")
test.must_match('test02' + _exe, "This is a .f90 file.\n")
diff --git a/test/Fortran/FORTRANPATH.py b/test/Fortran/FORTRANPATH.py
index d80a825..3a62c45 100644
--- a/test/Fortran/FORTRANPATH.py
+++ b/test/Fortran/FORTRANPATH.py
@@ -37,28 +37,26 @@ test = TestSCons.TestSCons()
fc = 'f77'
if not test.detect_tool(fc):
- test.skip_test('Could not find a f77 tool; skipping test.\n')
-
-test.subdir('include',
- 'subdir',
- ['subdir', 'include'],
- 'foobar',
- 'inc2')
-
-
-
-test.write('SConstruct', """
-env = Environment(FORTRAN = '%s',
- FORTRANPATH = ['$FOO', '${TARGET.dir}', '${SOURCE.dir}'],
- FOO='include')
+ # gfortran names all variants the same, try it too
+ fc = 'gfortran'
+ if not test.detect_tool(fc):
+ test.skip_test('Could not find a f77 tool; skipping test.\n')
+
+test.subdir('include', 'subdir', ['subdir', 'include'], 'foobar', 'inc2')
+
+test.write('SConstruct', """\
+env = Environment(
+ FORTRAN='%s',
+ FORTRANPATH=['$FOO', '${TARGET.dir}', '${SOURCE.dir}'],
+ FOO='include'
+)
obj = env.Object(target='foobar/prog', source='subdir/prog.f')
env.Program(target='prog', source=obj)
SConscript('subdir/SConscript', "env")
VariantDir('variant', 'subdir', 0)
include = Dir('include')
-env = Environment(FORTRAN = '%s',
- FORTRANPATH=[include, '#foobar', '#subdir'])
+env = Environment(FORTRAN='%s', FORTRANPATH=[include, '#foobar', '#subdir'])
SConscript('variant/SConscript', "env")
""" % (fc, fc))
@@ -151,8 +149,6 @@ test.must_not_exist(test.workpath('variant', 'prog.f'))
test.up_to_date(arguments = args)
-
-
test.write(['include', 'foo.f'],
r"""
PRINT *, 'include/foo.f 2'
@@ -197,9 +193,6 @@ test.must_not_exist(test.workpath('variant', 'prog.f'))
test.up_to_date(arguments = args)
-
-
-#
test.write(['include', 'bar.f'],
r"""
PRINT *, 'include/bar.f 2'
@@ -247,25 +240,26 @@ test.up_to_date(arguments = args)
# Change FORTRANPATH and make sure we don't rebuild because of it.
-test.write('SConstruct', """
-env = Environment(FORTRAN = '%s',
- FORTRANPATH = Split('inc2 include ${TARGET.dir} ${SOURCE.dir}'))
+test.write('SConstruct', """\
+env = Environment(
+ FORTRAN='%s',
+ FORTRANPATH=Split('inc2 include ${TARGET.dir} ${SOURCE.dir}'),
+)
obj = env.Object(target='foobar/prog', source='subdir/prog.f')
env.Program(target='prog', source=obj)
SConscript('subdir/SConscript', "env")
VariantDir('variant', 'subdir', 0)
include = Dir('include')
-env = Environment(FORTRAN = '%s',
- FORTRANPATH=['inc2', include, '#foobar', '#subdir'])
+env = Environment(
+ FORTRAN='%s',
+ FORTRANPATH=['inc2', include, '#foobar', '#subdir'],
+)
SConscript('variant/SConscript', "env")
""" % (fc, fc))
test.up_to_date(arguments = args)
-
-
-#
test.write(['inc2', 'foo.f'],
r"""
PRINT *, 'inc2/foo.f 1'
@@ -308,8 +302,6 @@ test.run(program = test.workpath(variant_prog),
test.up_to_date(arguments = args)
-
-
# Check that a null-string FORTRANPATH doesn't blow up.
test.write('SConstruct', """
env = Environment(FORTRANPATH = '')
diff --git a/test/Fortran/fixture/myfortran.py b/test/Fortran/fixture/myfortran.py
index 08d1489..6b4e5ef 100644
--- a/test/Fortran/fixture/myfortran.py
+++ b/test/Fortran/fixture/myfortran.py
@@ -1,14 +1,17 @@
import getopt
import sys
+
print(sys.argv)
comment = ('#' + sys.argv[1]).encode()
-length = len(comment)
+
opts, args = getopt.getopt(sys.argv[2:], 'cf:o:K:')
for opt, arg in opts:
- if opt == '-o': out = arg
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-for l in infile.readlines():
- if l[:length] != comment:
- outfile.write(l)
+ if opt == '-o':
+ out = arg
+
+with open(args[0], 'rb') as infile, open(out, 'wb') as outfile:
+ for l in infile:
+ if not l.startswith(comment):
+ outfile.write(l)
+
sys.exit(0)
diff --git a/test/Fortran/fixture/myfortran_flags.py b/test/Fortran/fixture/myfortran_flags.py
index b972e35..2b433ea 100644
--- a/test/Fortran/fixture/myfortran_flags.py
+++ b/test/Fortran/fixture/myfortran_flags.py
@@ -1,16 +1,19 @@
import getopt
import sys
+
comment = ('#' + sys.argv[1]).encode()
-opts, args = getopt.getopt(sys.argv[2:], 'cf:o:xy')
+
+opts, args = getopt.getopt(sys.argv[2:], 'cf:o:xyz')
optstring = ''
length = len(comment)
for opt, arg in opts:
if opt == '-o': out = arg
elif opt not in ('-f', '-K'): optstring = optstring + ' ' + opt
-infile = open(args[0], 'rb')
-outfile = open(out, 'wb')
-outfile.write((optstring + "\n").encode())
-for l in infile.readlines():
- if l[:length] != comment:
- outfile.write(l)
+
+with open(args[0], 'rb') as infile, open(out, 'wb') as outfile:
+ outfile.write((optstring + "\n").encode())
+ for l in infile:
+ if not l.startswith(comment):
+ outfile.write(l)
+
sys.exit(0)
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