summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Deegan <bill@baddogconsulting.com>2019-10-08 01:44:22 (GMT)
committerGitHub <noreply@github.com>2019-10-08 01:44:22 (GMT)
commit43cebd68db3696a4a7fdd2d38a81842d18d6d2cd (patch)
treea34d8ba5c57dc97eb9e4e9b11a8507fcf20ff329
parent581a6912938f3143b2c31dcb78ecc9928da124df (diff)
parentb161cf3f51e376a82208081e3f83dd96e2a4d6bf (diff)
downloadSCons-43cebd68db3696a4a7fdd2d38a81842d18d6d2cd.zip
SCons-43cebd68db3696a4a7fdd2d38a81842d18d6d2cd.tar.gz
SCons-43cebd68db3696a4a7fdd2d38a81842d18d6d2cd.tar.bz2
Merge branch 'master' into CmdStringHolder
-rw-r--r--.appveyor.yml2
-rw-r--r--bench/bench.py38
-rw-r--r--bench/env.__setitem__.py2
-rw-r--r--bench/timeit.py298
-rw-r--r--bin/calibrate.py10
-rw-r--r--doc/man/scons.xml421
-rw-r--r--doc/scons.mod1
-rw-r--r--doc/user/install.xml70
-rw-r--r--doc/user/output.xml2
-rwxr-xr-xsrc/CHANGES.txt8
-rw-r--r--src/engine/SCons/Conftest.py4
-rw-r--r--src/engine/SCons/Environment.xml149
-rw-r--r--src/engine/SCons/Script/SConsOptions.py20
-rw-r--r--src/engine/SCons/Tool/__init__.xml30
-rw-r--r--src/engine/SCons/Tool/install.xml16
-rw-r--r--src/engine/SCons/Tool/suncxx.py4
-rw-r--r--test/Configure/config-h.py27
-rw-r--r--test/Deprecated/debug-dtree.py120
-rw-r--r--test/Deprecated/debug-stree.py139
-rw-r--r--test/Deprecated/debug-tree.py160
-rw-r--r--test/Errors/execute-a-directory.py12
-rw-r--r--test/Errors/non-executable-file.py10
-rw-r--r--test/Interactive/shell.py4
-rw-r--r--test/Interactive/tree.py17
-rw-r--r--test/Interactive/version.py6
-rw-r--r--test/Java/JARFLAGS.py6
-rw-r--r--test/Java/JAVABOOTCLASSPATH.py4
-rw-r--r--test/Libs/SharedLibrary.py17
-rw-r--r--test/Removed/debug-dtree.py57
-rw-r--r--test/Removed/debug-nomemoizer.py (renamed from test/Deprecated/debug-nomemoizer.py)28
-rw-r--r--test/Removed/debug-stree.py57
-rw-r--r--test/Removed/debug-tree.py64
-rw-r--r--test/Scanner/CrossLanguageNoExtension.py4
-rw-r--r--test/Scanner/FindPathDirs.py6
-rw-r--r--test/Scanner/Scanner.py6
-rw-r--r--test/Scanner/dictionary.py8
-rw-r--r--test/Scanner/exception.py6
-rw-r--r--test/Scanner/generated.py6
-rw-r--r--test/Scanner/multi-env.py2
-rw-r--r--test/Scanner/no-Dir-node.py2
-rw-r--r--test/Scanner/source_scanner-dict.py10
-rw-r--r--test/Scanner/unicode.py2
-rw-r--r--test/explain/basic.py6
-rw-r--r--test/explain/save-info.py2
-rw-r--r--test/import.py4
-rw-r--r--test/option--tree.py7
-rw-r--r--test/option-v.py4
-rw-r--r--test/packaging/rpm/explicit-target.py2
-rw-r--r--test/packaging/rpm/multipackage.py4
-rw-r--r--test/packaging/rpm/package.py2
-rw-r--r--test/runtest/xml/output.py8
-rw-r--r--test/srcchange.py8
-rw-r--r--test/timestamp-fallback.py27
-rw-r--r--timings/README.txt2
-rw-r--r--timings/hundred/TimeSCons-run.py3
55 files changed, 790 insertions, 1144 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 5805f5f..a18f295 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -226,7 +226,7 @@ build_script:
# Windows run the tests
# NOTE: running powershell from cmd on purpose because it formats the output
# correctly
- - cmd: powershell -Command "& { if($env:COVERAGE -eq 1) { coverage run -p --rcfile=$($env:COVERAGE_PROCESS_START) runtest.py -j 2 --exclude-list exclude_list.txt -f build_tests.txt } else { C:\\%WINPYTHON%\\python.exe runtest.py -j 2 --exclude-list exclude_list.txt -f build_tests.txt }; if($LastExitCode -eq 2 -Or $LastExitCode -eq 0) { $host.SetShouldExit(0 )} else {$host.SetShouldExit(1)}}"
+ - cmd: powershell -Command "& { if($env:COVERAGE -eq 1) { coverage run -p --rcfile=$($env:COVERAGE_PROCESS_START) runtest.py -j 2 -t --exclude-list exclude_list.txt -f build_tests.txt } else { C:\\%WINPYTHON%\\python.exe runtest.py -j 2 -t --exclude-list exclude_list.txt -f build_tests.txt }; if($LastExitCode -eq 2 -Or $LastExitCode -eq 0) { $host.SetShouldExit(0 )} else {$host.SetShouldExit(1)}}"
# linux run the tests
# unset JAVA_TOOL_OPTIONS because newer java prints this to stderr
diff --git a/bench/bench.py b/bench/bench.py
index 3f7dbc6..aad0fb4 100644
--- a/bench/bench.py
+++ b/bench/bench.py
@@ -56,12 +56,26 @@ Runs = 10
FunctionPrefix = 'Func'
-# The function used to get the current time. The default of time.time is
-# good on most UNIX systems, but time.clock (selectable via the --clock
-# option) is better on Windows and some other UNIX systems.
-
-Now = time.time
+# Comment from Python2 timeit module:
+# The difference in default timer function is because on Windows,
+# clock() has microsecond granularity but time()'s granularity is 1/60th
+# of a second; on Unix, clock() has 1/100th of a second granularity and
+# time() is much more precise. On either platform, the default timer
+# functions measure wall clock time, not the CPU time. This means that
+# other processes running on the same computer may interfere with the
+# timing. The best thing to do when accurate timing is necessary is to
+# repeat the timing a few times and use the best time. The -i option is
+# good for this.
+# On Python3, a new time.perf_counter function picks the best available
+# timer, so we use that if we can, else fall back as per above.
+try:
+ Now = time.perf_counter
+except AttributeError:
+ if sys.platform == 'win32':
+ Now = time.clock
+ else:
+ Now = time.time
opts, args = getopt.getopt(sys.argv[1:], 'hi:r:',
['clock', 'func=', 'help',
@@ -69,7 +83,11 @@ opts, args = getopt.getopt(sys.argv[1:], 'hi:r:',
for o, a in opts:
if o in ['--clock']:
- Now = time.clock
+ try:
+ Now = time.clock
+ except AttributeError:
+ sys.stderr.write("time.clock unavailable on this Python\n")
+ sys.exit(1)
elif o in ['--func']:
FunctionPrefix = a
elif o in ['-h', '--help']:
@@ -87,15 +105,15 @@ if len(args) != 1:
sys.stderr.write(Usage)
sys.exit(1)
-
-exec(open(args[0], 'r').read())
-
+with open(args[0], 'r') as f:
+ exec(f.read())
try:
FunctionList
except NameError:
function_names = sorted([x for x in list(locals().keys()) if x[:4] == FunctionPrefix])
- l = [locals()[f] for f in function_names]
+ lvars = locals()
+ l = [lvars[f] for f in function_names]
FunctionList = [f for f in l if isinstance(f, types.FunctionType)]
IterationList = [None] * Iterations
diff --git a/bench/env.__setitem__.py b/bench/env.__setitem__.py
index 510dcc7..ed0888e 100644
--- a/bench/env.__setitem__.py
+++ b/bench/env.__setitem__.py
@@ -289,7 +289,7 @@ else:
# that the timer will use to get at these classes.
class_names = []
-for n in locals().keys():
+for n in list(locals().keys()):
#if n.startswith('env_'):
if n[:4] == 'env_':
class_names.append(n)
diff --git a/bench/timeit.py b/bench/timeit.py
deleted file mode 100644
index 7db0dd4..0000000
--- a/bench/timeit.py
+++ /dev/null
@@ -1,298 +0,0 @@
-#! /usr/bin/env python
-
-"""Tool for measuring execution time of small code snippets.
-
-This module avoids a number of common traps for measuring execution
-times. See also Tim Peters' introduction to the Algorithms chapter in
-the Python Cookbook, published by O'Reilly.
-
-Library usage: see the Timer class.
-
-Command line usage:
- python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement]
-
-Options:
- -n/--number N: how many times to execute 'statement' (default: see below)
- -r/--repeat N: how many times to repeat the timer (default 3)
- -s/--setup S: statement to be executed once initially (default 'pass')
- -t/--time: use time.time() (default on Unix)
- -c/--clock: use time.clock() (default on Windows)
- -v/--verbose: print raw timing results; repeat for more digits precision
- -h/--help: print this usage message and exit
- statement: statement to be timed (default 'pass')
-
-A multi-line statement may be given by specifying each line as a
-separate argument; indented lines are possible by enclosing an
-argument in quotes and using leading spaces. Multiple -s options are
-treated similarly.
-
-If -n is not given, a suitable number of loops is calculated by trying
-successive powers of 10 until the total time is at least 0.2 seconds.
-
-The difference in default timer function is because on Windows,
-clock() has microsecond granularity but time()'s granularity is 1/60th
-of a second; on Unix, clock() has 1/100th of a second granularity and
-time() is much more precise. On either platform, the default timer
-functions measure wall clock time, not the CPU time. This means that
-other processes running on the same computer may interfere with the
-timing. The best thing to do when accurate timing is necessary is to
-repeat the timing a few times and use the best time. The -r option is
-good for this; the default of 3 repetitions is probably enough in most
-cases. On Unix, you can use clock() to measure CPU time.
-
-Note: there is a certain baseline overhead associated with executing a
-pass statement. The code here doesn't try to hide it, but you should
-be aware of it. The baseline overhead can be measured by invoking the
-program without arguments. The baseline overhead differs between
-Python versions!
-"""
-from __future__ import division, print_function
-
-try:
- import gc
-except ImportError:
- class _fake_gc(object):
- def isenabled(self):
- return None
- def enable(self):
- pass
- def disable(self):
- pass
- gc = _fake_gc()
-import sys
-import time
-try:
- import itertools
-except ImportError:
- # Must be an older Python version (see timeit() below)
- itertools = None
-
-__all__ = ["Timer"]
-
-dummy_src_name = "<timeit-src>"
-default_number = 1000000
-default_repeat = 3
-
-if sys.platform == "win32":
- # On Windows, the best timer is time.clock()
- default_timer = time.clock
-else:
- # On most other platforms the best timer is time.time()
- default_timer = time.time
-
-# Don't change the indentation of the template; the reindent() calls
-# in Timer.__init__() depend on setup being indented 4 spaces and stmt
-# being indented 8 spaces.
-template = """
-def inner(_it, _timer):
- %(setup)s
- _t0 = _timer()
- for _i in _it:
- %(stmt)s
- _t1 = _timer()
- return _t1 - _t0
-"""
-
-def reindent(src, indent):
- """Helper to reindent a multi-line statement."""
- return src.replace("\n", "\n" + " "*indent)
-
-class Timer(object):
- """Class for timing execution speed of small code snippets.
-
- The constructor takes a statement to be timed, an additional
- statement used for setup, and a timer function. Both statements
- default to 'pass'; the timer function is platform-dependent (see
- module doc string).
-
- To measure the execution time of the first statement, use the
- timeit() method. The repeat() method is a convenience to call
- timeit() multiple times and return a list of results.
-
- The statements may contain newlines, as long as they don't contain
- multi-line string literals.
- """
-
- def __init__(self, stmt="pass", setup="pass", timer=default_timer):
- """Constructor. See class doc string."""
- self.timer = timer
- stmt = reindent(stmt, 8)
- setup = reindent(setup, 4)
- src = template % {'stmt': stmt, 'setup': setup}
- self.src = src # Save for traceback display
- code = compile(src, dummy_src_name, "exec")
- ns = {}
- exec(code, globals(), ns)
- self.inner = ns["inner"]
-
- def print_exc(self, file=None):
- """Helper to print a traceback from the timed code.
-
- Typical use:
-
- t = Timer(...) # outside the try/except
- try:
- t.timeit(...) # or t.repeat(...)
- except:
- t.print_exc()
-
- The advantage over the standard traceback is that source lines
- in the compiled template will be displayed.
-
- The optional file argument directs where the traceback is
- sent; it defaults to sys.stderr.
- """
- import linecache, traceback
- linecache.cache[dummy_src_name] = (len(self.src),
- None,
- self.src.split("\n"),
- dummy_src_name)
- traceback.print_exc(file=file)
-
- def timeit(self, number=default_number):
- """Time 'number' executions of the main statement.
-
- To be precise, this executes the setup statement once, and
- then returns the time it takes to execute the main statement
- a number of times, as a float measured in seconds. The
- argument is the number of times through the loop, defaulting
- to one million. The main statement, the setup statement and
- the timer function to be used are passed to the constructor.
- """
- if itertools:
- it = itertools.repeat(None, number)
- else:
- it = [None] * number
- gcold = gc.isenabled()
- gc.disable()
- timing = self.inner(it, self.timer)
- if gcold:
- gc.enable()
- return timing
-
- def repeat(self, repeat=default_repeat, number=default_number):
- """Call timeit() a few times.
-
- This is a convenience function that calls the timeit()
- repeatedly, returning a list of results. The first argument
- specifies how many times to call timeit(), defaulting to 3;
- the second argument specifies the timer argument, defaulting
- to one million.
-
- Note: it's tempting to calculate mean and standard deviation
- from the result vector and report these. However, this is not
- very useful. In a typical case, the lowest value gives a
- lower bound for how fast your machine can run the given code
- snippet; higher values in the result vector are typically not
- caused by variability in Python's speed, but by other
- processes interfering with your timing accuracy. So the min()
- of the result is probably the only number you should be
- interested in. After that, you should look at the entire
- vector and apply common sense rather than statistics.
- """
- r = []
- for i in range(repeat):
- t = self.timeit(number)
- r.append(t)
- return r
-
-def main(args=None):
- """Main program, used when run as a script.
-
- The optional argument specifies the command line to be parsed,
- defaulting to sys.argv[1:].
-
- The return value is an exit code to be passed to sys.exit(); it
- may be None to indicate success.
-
- When an exception happens during timing, a traceback is printed to
- stderr and the return value is 1. Exceptions at other times
- (including the template compilation) are not caught.
- """
- if args is None:
- args = sys.argv[1:]
- import getopt
- try:
- opts, args = getopt.getopt(args, "n:s:r:tcvh",
- ["number=", "setup=", "repeat=",
- "time", "clock", "verbose", "help"])
- except getopt.error as err:
- print(err)
- print("use -h/--help for command line help")
- return 2
- timer = default_timer
- stmt = "\n".join(args) or "pass"
- number = 0 # auto-determine
- setup = []
- repeat = default_repeat
- verbose = 0
- precision = 3
- for o, a in opts:
- if o in ("-n", "--number"):
- number = int(a)
- if o in ("-s", "--setup"):
- setup.append(a)
- if o in ("-r", "--repeat"):
- repeat = int(a)
- if repeat <= 0:
- repeat = 1
- if o in ("-t", "--time"):
- timer = time.time
- if o in ("-c", "--clock"):
- timer = time.clock
- if o in ("-v", "--verbose"):
- if verbose:
- precision = precision + 1
- verbose = precision + 1
- if o in ("-h", "--help"):
- print(__doc__)
- return 0
- setup = "\n".join(setup) or "pass"
- # Include the current directory, so that local imports work (sys.path
- # contains the directory of this script, rather than the current
- # directory)
- import os
- sys.path.insert(0, os.curdir)
- t = Timer(stmt, setup, timer)
- if number == 0:
- # determine number so that 0.2 <= total time < 2.0
- for i in range(1, 10):
- number = 10**i
- try:
- x = t.timeit(number)
- except:
- t.print_exc()
- return 1
- if verbose:
- print("%d loops -> %.*g secs" % (number, precision, x))
- if x >= 0.2:
- break
- try:
- r = t.repeat(repeat, number)
- except:
- t.print_exc()
- return 1
- best = min(r)
- if verbose:
- print("raw times:", ' '.join(["%.*g" % (precision, x) for x in r]))
- print("%d loops," % number, end=' ')
- usec = best * 1e6 / number
- if usec < 1000:
- print("best of %d: %.*g usec per loop" % (repeat, precision, usec))
- else:
- msec = usec / 1000
- if msec < 1000:
- print("best of %d: %.*g msec per loop" % (repeat, precision, msec))
- else:
- sec = msec / 1000
- print("best of %d: %.*g sec per loop" % (repeat, precision, sec))
- return None
-
-if __name__ == "__main__":
- sys.exit(main())
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/bin/calibrate.py b/bin/calibrate.py
index 3f9104e..be06a54 100644
--- a/bin/calibrate.py
+++ b/bin/calibrate.py
@@ -28,8 +28,8 @@ import re
import subprocess
import sys
-variable_re = re.compile('^VARIABLE: (.*)$', re.M)
-elapsed_re = re.compile('^ELAPSED: (.*)$', re.M)
+variable_re = re.compile(r'^VARIABLE: (.*)$', re.M)
+elapsed_re = re.compile(r'^ELAPSED: (.*)$', re.M)
def main(argv=None):
if argv is None:
@@ -60,7 +60,8 @@ def main(argv=None):
while good < 3:
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
+ stderr=subprocess.STDOUT,
+ universal_newlines=True)
output = p.communicate()[0]
vm = variable_re.search(output)
em = elapsed_re.search(output)
@@ -70,12 +71,13 @@ def main(argv=None):
print(output)
raise
print("run %3d: %7.3f: %s" % (run, elapsed, ' '.join(vm.groups())))
- if opts.min < elapsed and elapsed < opts.max:
+ if opts.min < elapsed < opts.max:
good += 1
else:
good = 0
for v in vm.groups():
var, value = v.split('=', 1)
+ # TODO: this sometimes converges slowly, better algorithm?
value = int((int(value) * opts.max) // elapsed)
os.environ[var] = str(value)
run += 1
diff --git a/doc/man/scons.xml b/doc/man/scons.xml
index faec455..9065f25 100644
--- a/doc/man/scons.xml
+++ b/doc/man/scons.xml
@@ -727,17 +727,6 @@ files, as well as unlinking old targets before building them.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>--debug=dtree</term>
- <listitem>
-<para>A synonym for the newer
-<option>--tree=derived</option>
-option.
-This will be deprecated in some future release
-and ultimately removed.</para>
-
- </listitem>
- </varlistentry>
- <varlistentry>
<term>--debug=explain</term>
<listitem>
<para>Print an explanation of precisely why
@@ -793,13 +782,6 @@ and before and after building targets.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>--debug=nomemoizer</term>
- <listitem>
-<para>A deprecated option preserved for backwards compatibility.</para>
-
- </listitem>
- </varlistentry>
- <varlistentry>
<term>--debug=objects</term>
<listitem>
<para>Prints a list of the various objects
@@ -856,17 +838,6 @@ when encountering an otherwise unexplained error.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>--debug=stree</term>
- <listitem>
-<para>A synonym for the newer
-<option>--tree=all,status</option>
-option.
-This will be deprecated in some future release
-and ultimately removed.</para>
-
- </listitem>
- </varlistentry>
- <varlistentry>
<term>--debug=time</term>
<listitem>
<para>Prints various time profiling information:</para>
@@ -923,17 +894,6 @@ should take place in parallel.)
</listitem>
</varlistentry>
<varlistentry>
- <term>--debug=tree</term>
- <listitem>
-<para>A synonym for the newer
-<option>--tree=all</option>
-option.
-This will be deprecated in some future release
-and ultimately removed.</para>
-
- </listitem>
- </varlistentry>
- <varlistentry>
<term>--diskcheck=<emphasis>types</emphasis></term>
<listitem>
<para>Enable specific checks for
@@ -1120,6 +1080,18 @@ This implies
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>--install-sandbox=<replaceable>path</replaceable></term>
+ <listitem>
+<para>
+When using the &Install; functions, prepend <replaceable>path</replaceable>
+to the installation paths such that all installed files will be placed
+underneath <replaceable>path</replaceable>.
+</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>--interactive</term>
<listitem>
@@ -1921,7 +1893,7 @@ These warnings are enabled by default.</para>
<option>--debug=object</option>
feature not working when
<command>scons</command>
-is run with the python
+is run with the Python
<option>-O</option>
option or from optimized Python (.pyo) modules.</para>
@@ -2048,7 +2020,7 @@ env['BAR'] = 'bar'
<para>As a convenience,
construction variables may also be set or modified by the
-<emphasis>parse_flags</emphasis>
+<emphasis role="bold">parse_flags</emphasis>
keyword argument, which applies the
&f-link-env-MergeFlags;
method (described below) to the argument value
@@ -2228,7 +2200,7 @@ def exists(env):
return True
# in SConstruct:
-env = Environment(tools = ['default', ('my_tool', {'arg1': 'abc'})],
+env = Environment(tools=['default', ('my_tool', {'arg1': 'abc'})],
toolpath=['tools'])
</programlisting>
@@ -2247,7 +2219,7 @@ With a nested tool name the dot represents a directory seperator</para>
<programlisting>
# namespaced builder
-env = Environment(ENV = os.environ, tools = ['SubDir1.SubDir2.SomeTool'])
+env = Environment(ENV=os.environ, tools=['SubDir1.SubDir2.SomeTool'])
env.SomeTool(targets, sources)
# Search Paths
@@ -2293,75 +2265,104 @@ env.SomeTool(targets, sources)
<refsect2 id='builder_methods'><title>Builder Methods</title>
-<para>Build rules are specified by calling a construction
-environment's builder methods.
-The arguments to the builder methods are
-<emphasis role="bold">target</emphasis>
-(a list of targets to be built,
-usually file names)
+<para>You tell <program>scons</program> what to build
+by calling Builders, functions which know to take a
+particular action when given files of a particular type
+to produce a particular result type. <program>scons</program>
+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
+key-value pairs in the
+<envar>BUILDERS</envar> attribute of the &consenv;.
+The available builders can be displayed like this
+for debugging purposes:
+</para>
+
+<literallayout class="monospaced">
+print("Builders:", list(env['BUILDERS']))
+</literallayout>
+
+<para>
+Builder methods always take two arguments:
+<replaceable>target</replaceable>
+(a target or a list of targets to be built)
and
-<emphasis role="bold">source</emphasis>
-(a list of sources to be built,
-usually file names).</para>
+<replaceable>source</replaceable>
+(a source or list of sources to be used as input
+when building),
+although in some circumstances,
+the target argument can actually be omitted (see below).
+Builder methods also take a variety of
+keyword arguments, described below.
+</para>
<para>Because long lists of file names
can lead to a lot of quoting,
<command>scons</command>
-supplies a
-<emphasis role="bold">Split()</emphasis>
+supplies a &Split;
global function
and a same-named environment method
that split a single string
into a list, separated on
strings of white-space characters.
-(These are similar to the split() member function of Python strings
-but work even if the input isn't a string.)</para>
+(These are similar to the Python string <function>split</function>
+method, but work even if the input isn't a string.)</para>
-<para>Like all Python arguments,
-the target and source arguments to a builder method
-can be specified either with or without
-the "target" and "source" keywords.
-When the keywords are omitted,
-the target is first,
-followed by the source.
-The following are equivalent examples of calling the Program builder method:</para>
+<para>
+The target and source arguments to a builder method
+can be specified either as positional arguments,
+in which case the target comes first, or as
+keyword arguments, using <parameter>target=</parameter>
+and <parameter>source=</parameter>.
+The following are equivalent examples of calling the
+&Program; builder method:
+</para>
<literallayout class="monospaced">
env.Program('bar', ['bar.c', 'foo.c'])
env.Program('bar', Split('bar.c foo.c'))
env.Program('bar', env.Split('bar.c foo.c'))
-env.Program(source = ['bar.c', 'foo.c'], target = 'bar')
-env.Program(target = 'bar', Split('bar.c foo.c'))
-env.Program(target = 'bar', env.Split('bar.c foo.c'))
-env.Program('bar', source = 'bar.c foo.c'.split())
+env.Program(source=['bar.c', 'foo.c'], target='bar')
+env.Program(target='bar', source=Split('bar.c foo.c'))
+env.Program(target='bar', source=env.Split('bar.c foo.c'))
+env.Program('bar', source='bar.c foo.c'.split())
</literallayout>
-<para>Target and source file names
-that are not absolute path names
-(that is, do not begin with
-<emphasis role="bold">/</emphasis>
-on POSIX systems
-or
-<emphasis role="bold">\</emphasis>
-on Windows systems,
-with or without
-an optional drive letter)
-are interpreted relative to the directory containing the
-<emphasis role="bold">SConscript</emphasis>
-file being read.
-An initial
-<emphasis role="bold">#</emphasis>
-(hash mark)
-on a path name means that the rest of the file name
-is interpreted relative to
-the directory containing
-the top-level
-<emphasis role="bold">SConstruct</emphasis>
-file,
-even if the
-<emphasis role="bold">#</emphasis>
-is followed by a directory separator character
-(slash or backslash).</para>
+<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,
+and any leading drive specifier is ignored for
+the determination) it is considered an absolute path,
+otherwise it is a relative path.
+If the path string contains no separator characters,
+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.
+</para>
+<para>
+<command>scons</command> recognizes a third way to specify
+path strings: if the string begins with
+the <emphasis role="bold">#</emphasis> character it is
+top-relative - it works like a relative path but the
+search follows down from the directory containing the top-level
+<emphasis role="bold">SConstruct</emphasis> rather than
+from the current directory (the # is allowed
+to 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>
+Target and source pathnames can be absolute, relative, or
+top-relative. Relative pathnames are searched considering the
+directory of the <emphasis role="bold">SConscript</emphasis>
+file currently being processed as the "current directory".
+</para>
<para>Examples:</para>
@@ -2403,12 +2404,12 @@ executable program
or
<emphasis role="bold">bar.exe</emphasis>
(on Windows systems)
-from the bar.c source file:</para>
+from the <filename>bar.c</filename> source file:</para>
<literallayout class="monospaced">
-env.Program(target = 'bar', source = 'bar.c')
-env.Program('bar', source = 'bar.c')
-env.Program(source = 'bar.c')
+env.Program(target='bar', source='bar.c')
+env.Program('bar', source='bar.c')
+env.Program(source='bar.c')
env.Program('bar.c')
</literallayout>
@@ -2418,28 +2419,31 @@ keyword argument may be specified
when calling a Builder.
When specified,
all source file strings that are not absolute paths
+or top-relative paths
will be interpreted relative to the specified
<emphasis role="bold">srcdir</emphasis>.
The following example will build the
-<emphasis role="bold">build/prog</emphasis>
+<filename>build/prog</filename>
(or
-<emphasis role="bold">build/prog.exe</emphasis>
+<filename>build/prog.exe</filename>
on Windows)
program from the files
-<emphasis role="bold">src/f1.c</emphasis>
+<filename>src/f1.c</filename>
and
-<emphasis role="bold">src/f2.c</emphasis>:</para>
+<filename>src/f2.c</filename>:
+</para>
<literallayout class="monospaced">
env.Program('build/prog', ['f1.c', 'f2.c'], srcdir='src')
</literallayout>
-<para>It is possible to override or add construction variables when calling a
-builder method by passing additional keyword arguments.
-These overridden or added
-variables will only be in effect when building the target, so they will not
-affect other parts of the build. For example, if you want to add additional
-libraries for just one program:</para>
+<para>It is possible to <emphasis>override</emphasis> (replace or add)
+construction variables when calling a
+builder method by passing them as keyword arguments.
+These overrides
+will only be in effect when building that target, and will not
+affect other parts of the build. For example, if you want to specify
+some libraries needed by just one program:</para>
<literallayout class="monospaced">
env.Program('hello', 'hello.c', LIBS=['gl', 'glut'])
@@ -2459,7 +2463,7 @@ for dependencies on the non-standard library names;
see the descriptions of these variables, below, for more information.)</para>
<para>It is also possible to use the
-<emphasis>parse_flags</emphasis>
+<emphasis role="bold">parse_flags</emphasis>
keyword argument in an override,
to merge command-line style arguments
into the appropriate construction variables
@@ -2504,8 +2508,7 @@ from SCons.Script import *
</literallayout>
<para>All builder methods return a list-like object
-containing Nodes that
-represent the target or targets that will be built.
+containing Nodes that will be built.
A
<emphasis>Node</emphasis>
is an internal SCons object
@@ -2517,9 +2520,8 @@ 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.
For example, if it were necessary
-to add a specific
-<option>-D</option>
-flag when compiling one specific object file:</para>
+to add a specific preprocessor define
+when compiling one specific object file:</para>
<literallayout class="monospaced">
bar_obj_list = env.StaticObject('bar.c', CPPDEFINES='-DBAR')
@@ -2530,14 +2532,14 @@ env.Program(source = ['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.</para>
+when calling the &Program; builder method.</para>
-<para>Note that Builder calls will automatically "flatten"
+<para>Note that builder calls will automatically "flatten"
the source and target file lists,
-so it's all right to have the bar_obj list
-return by the StaticObject() call
+so it's all right to have the <literal>bar_obj_list</literal>
+returned by the &StaticObject; call
in the middle of the source file list.
-If you need to manipulate a list of lists returned by Builders
+If you need to manipulate a list of lists returned by builders
directly using Python,
you can either build the list by hand:</para>
@@ -2549,8 +2551,7 @@ for object in objects:
print(str(object))
</literallayout>
-<para>Or you can use the
-<emphasis role="bold">Flatten</emphasis>()
+<para>Or you can use the &Flatten;
function supplied by scons
to create a list containing just the Nodes,
which may be more convenient:</para>
@@ -2563,23 +2564,23 @@ for object in objects:
print(str(object))
</literallayout>
-<para>Note also that because Builder calls return
+<para>Note also that because builder calls return
a list-like object, not an actual Python list,
you should
<emphasis>not</emphasis>
-use the Python
-<emphasis role="bold">+=</emphasis>
-operator to append Builder results to a Python list.
+use the Python add
+operator (<literal>+</literal> or <literal>+=</literal>)
+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,
but will instead create a new Node-list object
containing the concatenation of the list
-elements and the Builder results.
+elements and the builder results.
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
-<markup>.extend()</markup>
+Instead, use the Python list
+<function>extend</function>
method to make sure the list is updated in-place.
Example:</para>
@@ -2592,7 +2593,7 @@ object_files = []
#
# It will not update the object_files list in place.
#
-# Instead, use the .extend() method:
+# Instead, use the list extend method:
object_files.extend(Object('bar.c'))
</literallayout>
@@ -2609,7 +2610,7 @@ print("The path to bar_obj is:", str(bar_obj_list[0]))
<para>Note again that because the Builder call returns a list,
we have to access the first element in the list
-<emphasis role="bold">(bar_obj_list[0])</emphasis>
+(<literal>(bar_obj_list[0])</literal>)
to get at the Node that actually represents
the object file.</para>
@@ -2672,7 +2673,12 @@ to use just the filename portion of the
targets and source.</para>
<para><command>scons</command>
-provides the following builder methods:</para>
+predefined the following builder methods.
+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>
<!-- '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -->
<!-- '\" BEGIN GENERATED BUILDER DESCRIPTIONS -->
@@ -4409,7 +4415,7 @@ functions return
and
<emphasis>Dir</emphasis>
Nodes, respectively.
-python objects, respectively.
+Python objects, respectively.
Those objects have several user-visible attributes
and methods that are often useful:</para>
@@ -4566,7 +4572,7 @@ incl = Dir('include')
f = incl.File('header.h')
# Get a Node for a subdirectory within a directory
-dist = Dir('project-3.2.1)
+dist = Dir('project-3.2.1')
src = dist.Dir('src')
# Get a Node for a file in the same directory
@@ -5426,17 +5432,15 @@ a = Action(build_it, varlist=['XXX'])
</programlisting>
<para>The
-<emphasis role="bold">Action</emphasis>()
+&Action;
global function
can be passed the following
optional keyword arguments
to modify the Action object's behavior:</para>
-
-<para><emphasis role="bold">chdir</emphasis>
-The
-<emphasis role="bold">chdir</emphasis>
-keyword argument specifies that
+<para>
+<replaceable>chdir</replaceable>
+specifies that
scons will execute the action
after changing to the specified directory.
If the
@@ -5481,15 +5485,9 @@ a = Action("build &lt; ${SOURCE.file} &gt; ${TARGET.file}",
chdir=1)
</literallayout>
-
-<para><emphasis role="bold">exitstatfunc</emphasis>
-The
-<emphasis role="bold">Action</emphasis>()
-global function
-also takes an
-<emphasis role="bold">exitstatfunc</emphasis>
-keyword argument
-which specifies a function
+<para>
+<replaceable>exitstatfunc</replaceable>
+specifies a function
that is passed the exit status
(or return value)
from the specified action
@@ -5511,11 +5509,9 @@ a = Action("build &lt; ${SOURCE.file} &gt; ${TARGET.file}",
</programlisting>
-<para><emphasis role="bold">batch_key</emphasis>
-The
-<emphasis role="bold">batch_key</emphasis>
-keyword argument can be used
-to specify that the Action can create multiple target files
+<para>
+<replaceable>batch_key</replaceable>
+specifies that the Action can create multiple target files
by processing multiple independent source files simultaneously.
(The canonical example is "batch compilation"
of multiple object files
@@ -5524,7 +5520,7 @@ to a single invocation of a compiler
such as Microsoft's Visual C / C++ compiler.)
If the
<emphasis role="bold">batch_key</emphasis>
-argument is any non-False, non-callable Python value,
+argument evaluates True and is not a callable object,
the configured Action object will cause
<command>scons</command>
to collect all targets built with the Action object
@@ -5556,7 +5552,7 @@ will be used to identify different
for batch building.
A
<emphasis role="bold">batch_key</emphasis>
-function must take the following arguments:</para>
+function must accept the following arguments:</para>
<variablelist>
<varlistentry>
@@ -5688,7 +5684,7 @@ sequences of file manipulation
without relying
on platform-specific
external commands:
-that</para>
+</para>
<literallayout class="monospaced">
env = Environment(TMPBUILD = '/tmp/builddir')
env.Command('foo.out', 'foo.in',
@@ -5848,13 +5844,13 @@ env.Command('marker', 'input_file',
<para>Before executing a command,
<command>scons</command>
-performs construction variable interpolation on the strings that make up
-the command line of builders.
-Variables are introduced by a
-<emphasis role="bold">$</emphasis>
+performs construction variable interpolation on the string that makes up
+the command line of the builder.
+Variables are introduced in such strings by a
+<literal>$</literal>
prefix.
-Besides construction variables, scons provides the following
-variables for each command execution:</para>
+Besides regular construction variables, scons provides the following
+special variables for each command execution:</para>
<variablelist>
<varlistentry>
@@ -5923,15 +5919,19 @@ from sources that have
<emphasis>not</emphasis>
changed since the target was last built.</para>
-<para>(Note that the above variables are reserved
-and may not be set in a construction environment.)</para>
-
</listitem>
</varlistentry>
</variablelist>
-<para>For example, given the construction variable CC='cc', targets=['foo'], and
-sources=['foo.c', 'bar.c']:</para>
+<para>Note that the above variables are reserved
+and may not be set in a construction environment.</para>
+
+<para>For example, given the construction variables
+<literal>CC='cc'</literal>,
+<literal>targets=['foo']</literal>
+and
+<literal>sources=['foo.c', 'bar.c']</literal>:
+</para>
<literallayout class="monospaced">
action='$CC -c -o $TARGET $SOURCES'
@@ -5943,8 +5943,10 @@ action='$CC -c -o $TARGET $SOURCES'
cc -c -o foo foo.c bar.c
</literallayout>
-<para>Variable names may be surrounded by curly braces ({})
-to separate the name from the trailing characters.
+<para>Variable names may be surrounded by curly braces
+<emphasis role="bold">{ }</emphasis>
+to separate the name from surrounding characters which
+are not part of the name.
Within the curly braces, a variable name may have
a Python slice subscript appended to select one
or more items from a list.
@@ -6107,20 +6109,42 @@ may be a callable Python function
associated with a
construction variable in the environment.
The function should
-take four arguments:
-<emphasis>target</emphasis>
-- a list of target nodes,
-<emphasis>source</emphasis>
-- a list of source nodes,
-<emphasis>env</emphasis>
-- the construction environment,
-<emphasis>for_signature</emphasis>
-- a Boolean value that specifies
+accept four arguments:
+</para>
+<variablelist>
+ <varlistentry>
+ <term><replaceable>target</replaceable></term>
+ <listitem>
+<para>a list of target nodes</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>source</replaceable></term>
+ <listitem>
+<para>a list of source nodes</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>env</replaceable></term>
+ <listitem>
+<para>the construction environment</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><replaceable>for_signature</replaceable></term>
+ <listitem>
+<para>a Boolean value that specifies
whether the function is being called
-for generating a build signature.
+for generating a build signature. </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
SCons will insert whatever
the called function returns
-into the expanded string:</para>
+into the expanded string:
+</para>
<programlisting>
def foo(target, source, env, for_signature):
@@ -6201,9 +6225,12 @@ echo Last build occurred . &gt; $TARGET
<refsect2 id='python_code_substitution'><title>Python Code Substitution</title>
-<para>Any python code within
-<emphasis role="bold">${</emphasis>-<emphasis role="bold">}</emphasis>
-pairs gets evaluated by python 'eval', with the python globals set to
+<para>
+Any Python code within curly braces
+<emphasis role="bold">{ }</emphasis>
+and introduced by the variable prefix <emphasis role="bold">$</emphasis>
+gets evaluated by the Python <function>eval</function> statement,
+with the Python globals set to
the current environment's set of construction variables.
So in the following case:</para>
<literallayout class="monospaced">
@@ -6219,14 +6246,20 @@ echo FOO &gt; foo.out
<literallayout class="monospaced">
echo BAR &gt; foo.out
</literallayout>
-<para>according to the current value of env['COND'] when the command is
-executed. The evaluation occurs when the target is being
-built, not when the SConscript is being read. So if env['COND'] is changed
+<para>according to the current value of <literal>env['COND']</literal>
+when the command is executed.
+The evaluation takes place when the target is being
+built, not when the SConscript is being read. So if
+<literal>env['COND']</literal> is changed
later in the SConscript, the final value will be used.</para>
-<para>Here's a more interesting example. Note that all of COND, FOO, and
-BAR are environment variables, and their values are substituted into
-the final command. FOO is a list, so its elements are interpolated
+<para>Here's a more interesting example. Note that all of
+<envar>COND</envar>,
+<envar>FOO</envar>,
+and
+<envar>BAR</envar> are construction variables,
+and their values are substituted into the final command.
+<envar>FOO</envar> is a list, so its elements are interpolated
separated by spaces.</para>
<literallayout class="monospaced">
@@ -6574,9 +6607,10 @@ do this, in part,
by sharing an ability to interpret UNIX-like path names.
For example, the Cygwin tools
will internally translate a Cygwin path name
-like /cygdrive/c/mydir
+like <filename>/cygdrive/c/mydir</filename>
to an equivalent Windows pathname
-of C:/mydir (equivalent to C:\mydir).</para>
+of <filename>C:/mydir</filename> (equivalent to <filename>C:\mydir</filename>).
+</para>
<para>Versions of Python
that are built for native Windows execution,
@@ -6584,7 +6618,8 @@ such as the python.org and ActiveState versions,
do not have the Cygwin path name semantics.
This means that using a native Windows version of Python
to build compiled programs using Cygwin tools
-(such as gcc, bison, and flex)
+(such as <command>gcc</command>, <command>bison</command>,
+and <command>flex</command>)
may yield unpredictable results.
"Mixing and matching" in this way
can be made to work,
diff --git a/doc/scons.mod b/doc/scons.mod
index 77fa39b..71e996d 100644
--- a/doc/scons.mod
+++ b/doc/scons.mod
@@ -212,6 +212,7 @@
<!ENTITY Import "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Import</function>">
<!ENTITY Install "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Install</function>">
<!ENTITY InstallAs "<function xmlns='http://www.scons.org/dbxsd/v1.0'>InstallAs</function>">
+<!ENTITY InstallVersionedLib "<function xmlns='http://www.scons.org/dbxsd/v1.0'>InstallVersionedLib</function>">
<!ENTITY Link "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Link</function>">
<!ENTITY ListOption "<function xmlns='http://www.scons.org/dbxsd/v1.0'>ListOption</function>">
<!ENTITY ListVariable "<function xmlns='http://www.scons.org/dbxsd/v1.0'>ListVariable</function>">
diff --git a/doc/user/install.xml b/doc/user/install.xml
index 8c224d4..db87521 100644
--- a/doc/user/install.xml
+++ b/doc/user/install.xml
@@ -2,7 +2,7 @@
<!DOCTYPE sconsdoc [
<!ENTITY % scons SYSTEM "../scons.mod">
%scons;
-
+
<!ENTITY % builders-mod SYSTEM "../generated/builders.mod">
%builders-mod;
<!ENTITY % functions-mod SYSTEM "../generated/functions.mod">
@@ -11,7 +11,7 @@
%tools-mod;
<!ENTITY % variables-mod SYSTEM "../generated/variables.mod">
%variables-mod;
-
+
]>
<chapter id="chap-install"
@@ -50,7 +50,7 @@
Once a program is built,
it is often appropriate to install it in another
directory for public use.
- You use the &Install; method
+ You use the &Install; method
to arrange for a program, or any other file,
to be copied into a destination directory:
@@ -226,7 +226,7 @@ int main() { printf("Hello, world!\n"); }
<para>
- Lastly, if you have multiple files that all
+ If you have multiple files that all
need to be installed with different file names,
you can either call the &InstallAs; function
multiple times, or as a shorthand,
@@ -268,4 +268,66 @@ int main() { printf("Goodbye, world!\n"); }
</section>
+ <section>
+ <title>Installing a Shared Library</title>
+
+ <para>
+ If a shared library is created with the
+ &cv-link-SHLIBVERSION; variable set,
+ &scons; will create symbolic links as needed based on that
+ variable. To properly install such a library including the
+ symbolic links, use the &InstallVersionedLib; function.
+ </para>
+
+ <para>
+ For example, on a Linux system, this instruction:
+ </para>
+
+ <sconstruct>
+foo = env.SharedLibrary(target="foo", source="foo.c", SHLIBVERSION="1.2.3")
+ </sconstruct>
+
+ <para>
+ Will produce a shared library
+ <filename>libfoo.so.1.2.3</filename>
+ and symbolic links
+ <filename>libfoo.so</filename> and
+ <filename>libfoo.so.1</filename>
+ which point to
+ <filename>libfoo.so.1.2.3</filename>.
+ You can use the Node returned by the &SharedLibrary;
+ builder in order to install the library and its
+ symbolic links in one go without having to list
+ them individually:
+ </para>
+
+ <sconstruct>
+env.InstallVersionedLib(target="lib", source=foo)
+ </sconstruct>
+
+<!-- didn't get this to illustrate what I expected: example reports
+ installing lib without version, while manual effort has it:
+
+ <scons_example name="install_ex6">
+ <file name="SConstruct" printme="1">
+env = Environment()
+foo = env.SharedLibrary(target="foo", source="foo.c", SHLIBVERSION="1.2.3")
+ins = env.InstallVersionedLib(target="lib", source=foo)
+env.Alias('install', ins)
+ </file>
+ <file name="foo.c">
+int call_foo() {
+ printf("Hello world");
+ return(0);
+}
+ </file>
+ </scons_example>
+
+ <scons_output example="install_ex6" suffix="1">
+ <scons_output_command>scons -Q install</scons_output_command>
+ </scons_output>
+-->
+
+ </section>
+
</chapter>
diff --git a/doc/user/output.xml b/doc/user/output.xml
index ca4707d..f9e1a98 100644
--- a/doc/user/output.xml
+++ b/doc/user/output.xml
@@ -309,7 +309,7 @@ Linking foo
<scons_example name="output_COMSTR-VERBOSE">
<file name="SConstruct" printme="1">
env = Environment()
-if ARGUMENTS.get('VERBOSE') != "1':
+if ARGUMENTS.get('VERBOSE') != '1':
env['CCCOMSTR'] = "Compiling $TARGET"
env['LINKCOMSTR'] = "Linking $TARGET"
env.Program('foo.c')
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index e3d057e..0a30bfa 100755
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -16,7 +16,15 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
- Replace instances of string find method with "in" checks where
the index from find() was not used.
- CmdStringHolder fix from issue #3428
+ - Turn previously deprecated debug options into failures:
+ --debug=tree, --debug=dtree, --debug=stree, --debug=nomemoizer.
+ From Jacek Kuczera:
+ - Fix CheckFunc detection code for Visual 2019. Some functions
+ (e.g. memmove) were incorrectly recognized as not available.
+
+ From Jakub Kulik
+ - Fix subprocess result bytes not being decoded in SunOS/Solaris related tools.
RELEASE 3.1.1 - Mon, 07 Aug 2019 20:09:12 -0500
diff --git a/src/engine/SCons/Conftest.py b/src/engine/SCons/Conftest.py
index 1163aa3..c24adf8 100644
--- a/src/engine/SCons/Conftest.py
+++ b/src/engine/SCons/Conftest.py
@@ -290,6 +290,10 @@ char %s();""" % function_name
#include <assert.h>
%(hdr)s
+#if _MSC_VER && !__INTEL_COMPILER
+ #pragma function(%(name)s)
+#endif
+
int main(void) {
#if defined (__stub_%(name)s) || defined (__stub___%(name)s)
fail fail fail
diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml
index 5137bad..a635108 100644
--- a/src/engine/SCons/Environment.xml
+++ b/src/engine/SCons/Environment.xml
@@ -148,9 +148,9 @@ appending to this list,
although the more flexible approach
is to associate scanners
with a specific Builder.
-See the sections "Builder Objects"
-and "Scanner Objects,"
-below, for more information.
+See the manpage sections "Builder Objects"
+and "Scanner Objects"
+for more information.
</para>
</summary>
</cvar>
@@ -160,7 +160,8 @@ below, for more information.
<para>
A reserved variable name
that may not be set or used in a construction environment.
-(See "Variable Substitution," below.)
+(See the manpage section "Variable Substitution"
+for more information).
</para>
</summary>
</cvar>
@@ -170,7 +171,8 @@ that may not be set or used in a construction environment.
<para>
A reserved variable name
that may not be set or used in a construction environment.
-(See "Variable Substitution," below.)
+(See the manpage section "Variable Substitution"
+for more information).
</para>
</summary>
</cvar>
@@ -180,7 +182,8 @@ that may not be set or used in a construction environment.
<para>
A reserved variable name
that may not be set or used in a construction environment.
-(See "Variable Substitution," below.)
+(See the manpage section "Variable Substitution"
+for more information).
</para>
</summary>
</cvar>
@@ -190,7 +193,8 @@ that may not be set or used in a construction environment.
<para>
A reserved variable name
that may not be set or used in a construction environment.
-(See "Variable Substitution," below.)
+(See the manpage section "Variable Substitution"
+for more information).
</para>
</summary>
</cvar>
@@ -200,7 +204,8 @@ that may not be set or used in a construction environment.
<para>
A reserved variable name
that may not be set or used in a construction environment.
-(See "Variable Substitution," below.)
+(See the manpage section "Variable Substitution"
+for more information).
</para>
</summary>
</cvar>
@@ -210,7 +215,8 @@ that may not be set or used in a construction environment.
<para>
A reserved variable name
that may not be set or used in a construction environment.
-(See "Variable Substitution," below.)
+(See the manpage section "Variable Substitution"
+for more information).
</para>
</summary>
</cvar>
@@ -220,7 +226,8 @@ that may not be set or used in a construction environment.
<para>
A reserved variable name
that may not be set or used in a construction environment.
-(See "Variable Substitution," below.)
+(See the manpage section "Variable Substitution"
+for more information).
</para>
</summary>
</cvar>
@@ -230,7 +237,8 @@ that may not be set or used in a construction environment.
<para>
A reserved variable name
that may not be set or used in a construction environment.
-(See "Variable Substitution," below.)
+(See the manpage section "Variable Substitution"
+for more information).
</para>
</summary>
</cvar>
@@ -255,8 +263,8 @@ that are part of this construction environment.
Creates an Action object for
the specified
<varname>action</varname>.
-See the section "Action Objects,"
-below, for a complete explanation of the arguments and behavior.
+See the manpage section "Action Objects"
+for a complete explanation of the arguments and behavior.
</para>
<para>
@@ -359,7 +367,8 @@ has been built.
The specified action(s) may be
an Action object, or anything that
can be converted into an Action object
-(see below).
+See the manpage section "Action Objects"
+for a complete explanation.
</para>
<para>
@@ -386,7 +395,8 @@ is built.
The specified action(s) may be
an Action object, or anything that
can be converted into an Action object
-(see below).
+See the manpage section "Action Objects"
+for a complete explanation.
</para>
<para>
@@ -512,7 +522,7 @@ Otherwise, the construction variable
and the value of the keyword argument
are both coerced to lists,
and the lists are added together.
-(See also the Prepend method, below.)
+(See also the &Prepend; method).
</para>
<para>
@@ -634,8 +644,8 @@ or
Creates a Builder object for
the specified
<varname>action</varname>.
-See the section "Builder Objects,"
-below, for a complete explanation of the arguments and behavior.
+See the manpage section "Builder Objects"
+for a complete explanation of the arguments and behavior.
</para>
<para>
@@ -898,11 +908,15 @@ wx_env = env.Clone(parse_flags='!wx-config --cflags --cxxflags')
<builder name="Command">
<summary>
<para>
-The &b-Command; "Builder" is actually implemented
-as a function that looks like a Builder,
-but actually takes an additional argument of the action
-from which the Builder should be made.
-See the &f-link-Command; function description
+The &b-Command; "Builder" is actually
+a function that looks like a Builder,
+but takes a required third argument, which is the
+action to take to construct the target
+from the source, used for "one-off" builds
+where a full builder is not needed.
+Thus it does not follow the builder
+calling rules described at the start of this section.
+See instead the &f-link-Command; function description
for the calling syntax and details.
</para>
</summary>
@@ -947,7 +961,7 @@ same-named existing construction variables.
An action can be an external command,
specified as a string,
or a callable Python object;
-see "Action Objects," below,
+see the manpage section "Action Objects"
for more complete information.
Also note that a string specifying an external command
may be preceded by an
@@ -971,7 +985,7 @@ env.Command('foo.out', 'foo.in',
env.Command('bar.out', 'bar.in',
["rm -f $TARGET",
"$BAR_BUILD &lt; $SOURCES &gt; $TARGET"],
- ENV = {'PATH' : '/usr/local/bin/'})
+ ENV={'PATH': '/usr/local/bin/'})
def rename(env, target, source):
import os
@@ -979,7 +993,7 @@ def rename(env, target, source):
env.Command('baz.out', 'baz.in',
["$BAZ_BUILD &lt; $SOURCES &gt; .tmp",
- rename ])
+ rename])
</example_commands>
<para>
@@ -988,14 +1002,14 @@ Note that the
function will usually assume, by default,
that the specified targets and/or sources are Files,
if no other part of the configuration
-identifies what type of entry it is.
+identifies what type of entries they are.
If necessary, you can explicitly specify
that targets or source nodes should
-be treated as directoriese
+be treated as directories
by using the
&f-link-Dir;
or
-<function>env.Dir</function>()
+<function>env.Dir</function>
functions.
</para>
@@ -1011,9 +1025,9 @@ env.Command(env.Dir('$DISTDIR')), None, make_distdir)
</example_commands>
<para>
-(Also note that SCons will usually
+Also note that SCons will usually
automatically create any directory necessary to hold a target file,
-so you normally don't need to create directories by hand.)
+so you normally don't need to create directories by hand.
</para>
</summary>
</scons_function>
@@ -1029,8 +1043,8 @@ so you normally don't need to create directories by hand.)
<para>
Creates a Configure object for integrated
functionality similar to GNU autoconf.
-See the section "Configure Contexts,"
-below, for a complete explanation of the arguments and behavior.
+See the manpage section "Configure Contexts"
+for a complete explanation of the arguments and behavior.
</para>
</summary>
</scons_function>
@@ -1375,7 +1389,8 @@ would supply a string as a directory name
to a Builder method or function.
Directory Nodes have attributes and methods
that are useful in many situations;
-see "File and Directory Nodes," below.
+see manpage section "File and Directory Nodes"
+for more information.
</para>
</summary>
</scons_function>
@@ -1458,8 +1473,8 @@ Executes an Action object.
The specified
<varname>action</varname>
may be an Action object
-(see the section "Action Objects,"
-below, for a complete explanation of the arguments and behavior),
+(see manpage section "Action Objects"
+for a complete explanation of the arguments and behavior),
or it may be a command-line string,
list of commands,
or executable Python function,
@@ -1532,7 +1547,8 @@ would supply a string as a file name
to a Builder method or function.
File Nodes have attributes and methods
that are useful in many situations;
-see "File and Directory Nodes," below.
+see manpage section "File and Directory Nodes"
+for more information.
</para>
</summary>
</scons_function>
@@ -2190,7 +2206,7 @@ and the construction variables they affect
are as specified for the
&f-link-env-ParseFlags;
method (which this method calls).
-See that method's description, below,
+See that method's description
for a table of options and construction variables.
</para>
</summary>
@@ -2658,8 +2674,8 @@ env.Requires('foo', 'file-that-must-be-built-before-foo')
Creates a Scanner object for
the specified
<varname>function</varname>.
-See the section "Scanner Objects,"
-below, for a complete explanation of the arguments and behavior.
+See manpage section "Scanner Objects"
+for a complete explanation of the arguments and behavior.
</para>
</summary>
</scons_function>
@@ -3650,30 +3666,51 @@ SConscript(dirs='doc', variant_dir='build/doc', duplicate=0)
Searches for the specified executable
<varname>program</varname>,
returning the full path name to the program
-if it is found,
-and returning None if not.
-Searches the specified
-<varname>path</varname>,
-the value of the calling environment's PATH
-(<literal>env['ENV']['PATH']</literal>),
-or the user's current external PATH
-(<literal>os.environ['PATH']</literal>)
-by default.
+if it is found, else <literal>None</literal>.
+Searches the value of the
+<varname>path</varname> keyword argument,
+or if <literal>None</literal> (the default)
+the value of the calling environment's <envar>PATH</envar>
+(<literal>env['ENV']['PATH']</literal>).
+If <varname>path</varname> is <literal>None</literal> and
+the <literal>env['ENV']['PATH']</literal> key does not exist,
+the user's current external <envar>PATH</envar>
+(<literal>os.environ['PATH']</literal>) is used as fallback.
+</para>
+<para>
On Windows systems, searches for executable
-programs with any of the file extensions
-listed in the specified
-<varname>pathext</varname>,
-the calling environment's PATHEXT
-(<literal>env['ENV']['PATHEXT']</literal>)
-or the user's current PATHEXT
+programs with any of the file extensions listed in the
+<varname>pathext</varname> keyword argument,
+or if <literal>None</literal> (the default)
+the calling environment's <envar>PATHEXT</envar>
+(<literal>env['ENV']['PATHEXT']</literal>).
+The user's current external <envar>PATHEXT</envar>
(<literal>os.environ['PATHEXT']</literal>)
-by default.
+is used as a fallback if <varname>pathext</varname> is
+<literal>None</literal>
+and the key <literal>env['ENV']['PATHEXT']</literal>
+does not exist.
+</para>
+<para>
Will not select any
path name or names
in the specified
<varname>reject</varname>
list, if any.
</para>
+<note>
+<para>
+If you would prefer to search
+the user's current external <envar>PATH</envar>
+(<literal>os.environ['PATH']</literal>)
+by default,
+consider using the function <literal>SCons.Util.WhereIs</literal> instead.
+Note that <literal>SCons.Util.WhereIs</literal>
+does not expand environment variables automatically
+(no implicit <literal>env.subst</literal> for its arguments).
+</para>
+</note>
+
</summary>
</scons_function>
diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py
index c45cb01..add1150 100644
--- a/src/engine/SCons/Script/SConsOptions.py
+++ b/src/engine/SCons/Script/SConsOptions.py
@@ -584,9 +584,15 @@ def Parser(version):
help="Print build actions for files from CacheDir.")
def opt_invalid(group, value, options):
+ """report an invalid option from a group"""
errmsg = "`%s' is not a valid %s option type, try:\n" % (value, group)
return errmsg + " %s" % ", ".join(options)
+ def opt_invalid_rm(group, value, msg):
+ """report an invalid option from a group: recognized but removed"""
+ errmsg = "`%s' is not a valid %s option type " % (value, group)
+ return errmsg + msg
+
config_options = ["auto", "force" ,"cache"]
opt_config_help = "Controls Configure subsystem: %s." \
@@ -604,9 +610,11 @@ def Parser(version):
help="Search up directory tree for SConstruct, "
"build all Default() targets.")
- deprecated_debug_options = {
+ deprecated_debug_options = {}
+
+ removed_debug_options = {
"dtree" : '; please use --tree=derived instead',
- "nomemoizer" : ' and has no effect',
+ "nomemoizer" : '; there is no replacement',
"stree" : '; please use --tree=all,status instead',
"tree" : '; please use --tree=all instead',
}
@@ -618,11 +626,12 @@ def Parser(version):
def opt_debug(option, opt, value__, parser,
debug_options=debug_options,
- deprecated_debug_options=deprecated_debug_options):
+ deprecated_debug_options=deprecated_debug_options,
+ removed_debug_options=removed_debug_options):
for value in value__.split(','):
if value in debug_options:
parser.values.debug.append(value)
- elif value in list(deprecated_debug_options.keys()):
+ elif value in deprecated_debug_options:
parser.values.debug.append(value)
try:
parser.values.delayed_warnings
@@ -632,6 +641,9 @@ def Parser(version):
w = "The --debug=%s option is deprecated%s." % (value, msg)
t = (SCons.Warnings.DeprecatedDebugOptionsWarning, w)
parser.values.delayed_warnings.append(t)
+ elif value in removed_debug_options:
+ msg = removed_debug_options[value]
+ raise OptionValueError(opt_invalid_rm('debug', value, msg))
else:
raise OptionValueError(opt_invalid('debug', value, debug_options))
diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml
index 69cc597..b6e5a43 100644
--- a/src/engine/SCons/Tool/__init__.xml
+++ b/src/engine/SCons/Tool/__init__.xml
@@ -468,7 +468,7 @@ as C++ files.
Used to override &cv-link-SHLIBVERSION;/&cv-link-LDMODULEVERSION; when
generating versioned import library for a shared library/loadable module. If
undefined, the &cv-link-SHLIBVERSION;/&cv-link-LDMODULEVERSION; is used to
-determine the version of versioned import library.
+determine the version of versioned import library.
</para>
</summary>
</cvar>
@@ -476,7 +476,10 @@ determine the version of versioned import library.
<cvar name="LIBEMITTER">
<summary>
<para>
-TODO
+Contains the emitter specification for the
+&b-link-StaticLibrary; builder.
+The manpage section "Builder Objects" contains
+general information on specifying emitters.
</para>
</summary>
</cvar>
@@ -494,10 +497,24 @@ format as &cv-link-SHLIBVERSION;.
</summary>
</cvar>
+<cvar name="LDMODULEEMITTER">
+<summary>
+<para>
+Contains the emitter specification for the
+&b-link-LoadableModule; builder.
+The manpage section "Builder Objects" contains
+general information on specifying emitters.
+</para>
+</summary>
+</cvar>
+
<cvar name="SHLIBEMITTER">
<summary>
<para>
-TODO
+Contains the emitter specification for the
+&b-link-SharedLibrary; builder.
+The manpage section "Builder Objects" contains
+general information on specifying emitters.
</para>
</summary>
</cvar>
@@ -505,7 +522,10 @@ TODO
<cvar name="PROGEMITTER">
<summary>
<para>
-TODO
+Contains the emitter specification for the
+&b-link-Program; builder.
+The manpage section "Builder Objects" contains
+general information on specifying emitters.
</para>
</summary>
</cvar>
@@ -514,7 +534,7 @@ TODO
<summary>
<para>
When this construction variable is defined, a versioned shared library
-is created by &b-link-SharedLibrary; builder. This activates the
+is created by the &b-link-SharedLibrary; builder. This activates the
&cv-link-_SHLIBVERSIONFLAGS; and thus modifies the &cv-link-SHLINKCOM; as
required, adds the version number to the library name, and creates the symlinks
that are needed. &cv-link-SHLIBVERSION; versions should exist as alpha-numeric,
diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml
index 6ae3e30..74169b3 100644
--- a/src/engine/SCons/Tool/install.xml
+++ b/src/engine/SCons/Tool/install.xml
@@ -52,6 +52,22 @@ a builder.
<example_commands>
env.Install('/usr/local/bin', source = ['foo', 'bar'])
</example_commands>
+
+<para>
+If the <option>--install-sandbox</option> command line
+option is given, the target directory will be prefixed
+by the directory path specified.
+This is useful to test installs without installing to
+a "live" location in the system.
+</para>
+
+<para>
+See also &FindInstalledFiles;.
+For more thoughts on installation, see the User Guide
+(particularly the section on Command-Line Targets
+and the chapters on Installing Files and on Alias Targets).
+</para>
+
</summary>
</builder>
diff --git a/src/engine/SCons/Tool/suncxx.py b/src/engine/SCons/Tool/suncxx.py
index 9ac8d32..090df7d 100644
--- a/src/engine/SCons/Tool/suncxx.py
+++ b/src/engine/SCons/Tool/suncxx.py
@@ -74,7 +74,7 @@ def get_package_info(package_name, pkginfo, pkgchk):
except EnvironmentError:
pass
else:
- pkginfo_contents = p.communicate()[0]
+ pkginfo_contents = p.communicate()[0].decode()
version_re = re.compile(r'^ *VERSION:\s*(.*)$', re.M)
version_match = version_re.search(pkginfo_contents)
if version_match:
@@ -88,7 +88,7 @@ def get_package_info(package_name, pkginfo, pkgchk):
except EnvironmentError:
pass
else:
- pkgchk_contents = p.communicate()[0]
+ pkgchk_contents = p.communicate()[0].decode()
pathname_re = re.compile(r'^Pathname:\s*(.*/bin/CC)$', re.M)
pathname_match = pathname_re.search(pkgchk_contents)
if pathname_match:
diff --git a/test/Configure/config-h.py b/test/Configure/config-h.py
index a5c1998..405f259 100644
--- a/test/Configure/config-h.py
+++ b/test/Configure/config-h.py
@@ -46,25 +46,27 @@ env.AppendENVPath('PATH', os.environ['PATH'])
conf = Configure(env, config_h = 'config.h')
r1 = conf.CheckFunc('printf')
r2 = conf.CheckFunc('noFunctionCall')
-r3 = conf.CheckType('int')
-r4 = conf.CheckType('noType')
-r5 = conf.CheckCHeader('stdio.h', '<>')
-r6 = conf.CheckCHeader('hopefullynoc-header.h')
-r7 = conf.CheckCXXHeader('vector', '<>')
-r8 = conf.CheckCXXHeader('hopefullynocxx-header.h')
+r3 = conf.CheckFunc('memmove')
+r4 = conf.CheckType('int')
+r5 = conf.CheckType('noType')
+r6 = conf.CheckCHeader('stdio.h', '<>')
+r7 = conf.CheckCHeader('hopefullynoc-header.h')
+r8 = conf.CheckCXXHeader('vector', '<>')
+r9 = conf.CheckCXXHeader('hopefullynocxx-header.h')
env = conf.Finish()
conf = Configure(env, config_h = 'config.h')
-r9 = conf.CheckLib('%(lib)s', 'sin')
-r10 = conf.CheckLib('hopefullynolib', 'sin')
-r11 = conf.CheckLibWithHeader('%(lib)s', 'math.h', 'c')
-r12 = conf.CheckLibWithHeader('%(lib)s', 'hopefullynoheader2.h', 'c')
-r13 = conf.CheckLibWithHeader('hopefullynolib2', 'math.h', 'c')
+r10 = conf.CheckLib('%(lib)s', 'sin')
+r11 = conf.CheckLib('hopefullynolib', 'sin')
+r12 = conf.CheckLibWithHeader('%(lib)s', 'math.h', 'c')
+r13 = conf.CheckLibWithHeader('%(lib)s', 'hopefullynoheader2.h', 'c')
+r14 = conf.CheckLibWithHeader('hopefullynolib2', 'math.h', 'c')
env = conf.Finish()
""" % locals())
expected_read_str = """\
Checking for C function printf()... yes
Checking for C function noFunctionCall()... no
+Checking for C function memmove()... yes
Checking for C type int... yes
Checking for C type noType... no
Checking for C header file stdio.h... yes
@@ -96,6 +98,9 @@ expected_config_h = ("""\
/* Define to 1 if the system has the function `noFunctionCall'. */
/* #undef HAVE_NOFUNCTIONCALL */
+/* Define to 1 if the system has the function `memmove'. */
+#define HAVE_MEMMOVE 1
+
/* Define to 1 if the system has the type `int'. */
#define HAVE_INT 1
diff --git a/test/Deprecated/debug-dtree.py b/test/Deprecated/debug-dtree.py
deleted file mode 100644
index 1e7366f..0000000
--- a/test/Deprecated/debug-dtree.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# 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.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-"""
-Test that the --debug=dtree option correctly prints just the explicit
-dependencies (sources or Depends()) of a target.
-"""
-
-import TestSCons
-
-test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
-
-test.write('SConstruct', """
-env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx')
-env.Program('foo', Split('foo.c bar.c'))
-""")
-
-test.write('foo.c', r"""
-#include <stdio.h>
-#include <stdlib.h>
-#include "foo.h"
-int main(int argc, char *argv[])
-{
- argv[argc++] = "--";
- printf("f1.c\n");
- exit (0);
-}
-""")
-
-test.write('bar.c', """
-#include "bar.h"
-int local = 1;
-""")
-
-test.write('foo.h', """
-#ifndef FOO_H
-#define FOO_H
-#include "bar.h"
-#endif
-""")
-
-test.write('bar.h', """
-#ifndef BAR_H
-#define BAR_H
-#include "foo.h"
-#endif
-""")
-
-expect = """
-scons: warning: The --debug=dtree option is deprecated; please use --tree=derived instead.
-"""
-
-stderr = TestSCons.re_escape(expect) + TestSCons.file_expr
-
-dtree1 = """
-+-foo.xxx
- +-foo.ooo
- +-bar.ooo
-"""
-
-test.run(arguments = "--debug=dtree foo.xxx",
- stderr = stderr)
-test.must_contain_all_lines(test.stdout(), [dtree1])
-
-dtree2 = """
-+-.
- +-bar.ooo
- +-foo.ooo
- +-foo.xxx
- +-foo.ooo
- +-bar.ooo
-"""
-test.run(arguments = "--debug=dtree .",
- stderr = stderr)
-test.must_contain_all_lines(test.stdout(), [dtree2])
-
-# Make sure we print the debug stuff even if there's a build failure.
-test.write('bar.h', """
-#ifndef BAR_H
-#define BAR_H
-#include "foo.h"
-#endif
-THIS SHOULD CAUSE A BUILD FAILURE
-""")
-
-test.run(arguments = "--debug=dtree foo.xxx",
- status = 2,
- stderr = None)
-test.must_contain_all_lines(test.stdout(), [dtree1])
-
-test.pass_test()
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Deprecated/debug-stree.py b/test/Deprecated/debug-stree.py
deleted file mode 100644
index 907dedf..0000000
--- a/test/Deprecated/debug-stree.py
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# 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.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-"""
-Test that the --debug=stree option prints a dependency tree with output
-that indicates the state of various Node status flags.
-"""
-
-import TestSCons
-
-test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
-
-CC = test.detect('CC')
-LINK = test.detect('LINK')
-if LINK is None: LINK = CC
-
-test.write('SConstruct', """
-env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx')
-env.Program('foo', Split('foo.c bar.c'))
-""")
-
-test.write('foo.c', r"""
-#include <stdio.h>
-#include <stdlib.h>
-#include "foo.h"
-int main(int argc, char *argv[])
-{
- argv[argc++] = "--";
- printf("f1.c\n");
- exit (0);
-}
-""")
-
-test.write('bar.c', """
-#include "bar.h"
-int local = 1;
-""")
-
-test.write('foo.h', """
-#ifndef FOO_H
-#define FOO_H
-#include "bar.h"
-#endif
-""")
-
-test.write('bar.h', """
-#ifndef BAR_H
-#define BAR_H
-#include "foo.h"
-#endif
-""")
-
-expect = """
-scons: warning: The --debug=stree option is deprecated; please use --tree=all,status instead.
-"""
-
-stderr = TestSCons.re_escape(expect) + TestSCons.file_expr
-
-stree = """
-[E B C ]+-foo.xxx
-[E B C ] +-foo.ooo
-[E C ] | +-foo.c
-[E C ] | +-foo.h
-[E C ] | +-bar.h
-[E C ] | +-%(CC)s
-[E B C ] +-bar.ooo
-[E C ] | +-bar.c
-[E C ] | +-bar.h
-[E C ] | +-foo.h
-[E C ] | +-%(CC)s
-[E C ] +-%(LINK)s
-""" % locals()
-
-test.run(arguments = "--debug=stree foo.xxx",
- stderr = stderr)
-test.fail_test(test.stdout().count(stree) != 1)
-
-stree2 = """
- E = exists
- R = exists in repository only
- b = implicit builder
- B = explicit builder
- S = side effect
- P = precious
- A = always build
- C = current
- N = no clean
- H = no cache
-
-[ B ]+-foo.xxx
-[ B ] +-foo.ooo
-[E C ] | +-foo.c
-[E C ] | +-foo.h
-[E C ] | +-bar.h
-[E C ] | +-%(CC)s
-[ B ] +-bar.ooo
-[E C ] | +-bar.c
-[E C ] | +-bar.h
-[E C ] | +-foo.h
-[E C ] | +-%(CC)s
-[E C ] +-%(LINK)s
-""" % locals()
-
-test.run(arguments = '-c foo.xxx')
-
-test.run(arguments = "--no-exec --debug=stree foo.xxx",
- stderr = stderr)
-test.fail_test(test.stdout().count(stree2) != 1)
-
-test.pass_test()
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Deprecated/debug-tree.py b/test/Deprecated/debug-tree.py
deleted file mode 100644
index 51ff7f2..0000000
--- a/test/Deprecated/debug-tree.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env python
-#
-# __COPYRIGHT__
-#
-# 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.
-#
-
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-"""
-Test that the --debug=tree option prints a tree representation of the
-complete dependencies of a target.
-"""
-
-import TestSCons
-
-test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
-
-CC = test.detect('CC')
-LINK = test.detect('LINK')
-if LINK is None: LINK = CC
-
-test.write('SConstruct', """
-env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx')
-env.Program('Foo', Split('Foo.c Bar.c'))
-""")
-
-# N.B.: We use upper-case file names (Foo* and Bar*) so that the sorting
-# order with our upper-case SConstruct file is the same on case-sensitive
-# (UNIX/Linux) and case-insensitive (Windows) systems.
-
-test.write('Foo.c', r"""
-#include <stdio.h>
-#include <stdlib.h>
-#include "Foo.h"
-int main(int argc, char *argv[])
-{
- argv[argc++] = "--";
- printf("f1.c\n");
- exit (0);
-}
-""")
-
-test.write('Bar.c', """
-#include "Bar.h"
-int local = 1;
-""")
-
-test.write('Foo.h', """
-#ifndef FOO_H
-#define FOO_H
-#include "Bar.h"
-#endif
-""")
-
-test.write('Bar.h', """
-#ifndef BAR_H
-#define BAR_H
-#include "Foo.h"
-#endif
-""")
-
-expect = """
-scons: warning: The --debug=tree option is deprecated; please use --tree=all instead.
-"""
-
-stderr = TestSCons.re_escape(expect) + TestSCons.file_expr
-
-tree1 = """
-+-Foo.xxx
- +-Foo.ooo
- | +-Foo.c
- | +-Foo.h
- | +-Bar.h
- | +-%(CC)s
- +-Bar.ooo
- | +-Bar.c
- | +-Bar.h
- | +-Foo.h
- | +-%(CC)s
- +-%(LINK)s
-""" % locals()
-
-test.run(arguments = "--debug=tree Foo.xxx",
- stderr = stderr)
-test.must_contain_all_lines(test.stdout(), tree1)
-
-tree2 = """
-+-.
- +-Bar.c
- +-Bar.h
- +-Bar.ooo
- | +-Bar.c
- | +-Bar.h
- | +-Foo.h
- | +-%(CC)s
- +-Foo.c
- +-Foo.h
- +-Foo.ooo
- | +-Foo.c
- | +-Foo.h
- | +-Bar.h
- | +-%(CC)s
- +-Foo.xxx
- | +-Foo.ooo
- | | +-Foo.c
- | | +-Foo.h
- | | +-Bar.h
- | | +-%(CC)s
- | +-Bar.ooo
- | | +-Bar.c
- | | +-Bar.h
- | | +-Foo.h
- | | +-%(CC)s
- | +-%(LINK)s
- +-SConstruct
-""" % locals()
-
-test.run(arguments = "--debug=tree .",
- stderr = stderr)
-test.must_contain_all_lines(test.stdout(), tree2)
-
-# Make sure we print the debug stuff even if there's a build failure.
-test.write('Bar.h', """
-#ifndef BAR_H
-#define BAR_H
-#include "Foo.h"
-#endif
-THIS SHOULD CAUSE A BUILD FAILURE
-""")
-
-test.run(arguments = "--debug=tree Foo.xxx",
- status = 2,
- stderr = None)
-test.must_contain_all_lines(test.stdout(), tree1)
-
-test.pass_test()
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Errors/execute-a-directory.py b/test/Errors/execute-a-directory.py
index 1d2036e..95fa7b6 100644
--- a/test/Errors/execute-a-directory.py
+++ b/test/Errors/execute-a-directory.py
@@ -55,34 +55,34 @@ Bad command or file name
unrecognized = """\
'.+' is not recognized as an internal or external command,
operable program or batch file.
-scons: \*\*\* \[%s\] Error 1
+scons: \\*\\*\\* \\[%s\\] Error 1
"""
unspecified = """\
The name specified is not recognized as an
internal or external command, operable program or batch file.
-scons: \*\*\* \[%s\] Error 1
+scons: \\*\\*\\* \\[%s\\] Error 1
"""
cannot_execute = """\
(sh: )*.+: cannot execute
-scons: \*\*\* \[%s\] Error %s
+scons: \\*\\*\\* \\[%s\\] Error %s
"""
permission_denied = """\
.+: (p|P)ermission denied
-scons: \*\*\* \[%s\] Error %s
+scons: \\*\\*\\* \\[%s\\] Error %s
"""
is_a_directory = """\
.+: (i|I)s a directory
-scons: \*\*\* \[%s\] Error %s
+scons: \\*\\*\\* \\[%s\\] Error %s
"""
konnte_nicht_gefunden_werden = """\
Der Befehl ".+" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
-scons: \*\*\* \[%s\] Error %s
+scons: \\*\\*\\* \\[%s\\] Error %s
"""
test.description_set("Incorrect STDERR:\n%s\n" % test.stderr())
diff --git a/test/Errors/non-executable-file.py b/test/Errors/non-executable-file.py
index e1b8f4e..0e00c77 100644
--- a/test/Errors/non-executable-file.py
+++ b/test/Errors/non-executable-file.py
@@ -44,29 +44,29 @@ Bad command or file name
unrecognized = """\
'.+' is not recognized as an internal or external command,
operable program or batch file.
-scons: \*\*\* \[%s\] Error 1
+scons: \\*\\*\\* \\[%s\\] Error 1
"""
unspecified = """\
The name specified is not recognized as an
internal or external command, operable program or batch file.
-scons: \*\*\* \[%s\] Error 1
+scons: \\*\\*\\* \\[%s\\] Error 1
"""
cannot_execute = """\
(sh: )*.+: cannot execute
-scons: \*\*\* \[%s\] Error %s
+scons: \\*\\*\\* \\[%s\\] Error %s
"""
permission_denied = """\
.+: (p|P)ermission denied
-scons: \*\*\* \[%s\] Error %s
+scons: \\*\\*\\* \\[%s\\] Error %s
"""
konnte_nicht_gefunden_werden = """\
Der Befehl ".+" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
-scons: \*\*\* \[%s\] Error %s
+scons: \\*\\*\\* \\[%s\\] Error %s
"""
test.write('SConstruct', r"""
diff --git a/test/Interactive/shell.py b/test/Interactive/shell.py
index 40df86f..dd13504 100644
--- a/test/Interactive/shell.py
+++ b/test/Interactive/shell.py
@@ -89,8 +89,8 @@ if sys.platform == 'win32':
else:
no_such_error = 'scons: no_such_command: No such file or directory'
-expect_stdout = """\
-scons>>> Copy\("foo.out", "foo.in"\)
+expect_stdout = \
+r"""scons>>> Copy\("foo.out", "foo.in"\)
Touch\("1"\)
scons>>> hello from shell_command.py
scons>>> ![^"]+ ".*"
diff --git a/test/Interactive/tree.py b/test/Interactive/tree.py
index 61faa22..c10962a 100644
--- a/test/Interactive/tree.py
+++ b/test/Interactive/tree.py
@@ -69,23 +69,6 @@ test.must_match(test.workpath('foo.out'), "foo.in 2\n")
-scons.send("build --debug=tree foo.out\n")
-
-expect_stdout = """\
-scons>>> Copy("foo.out", "foo.in")
-scons>>> Touch("1")
-scons>>> Copy("foo.out", "foo.in")
-+-foo.out
- +-foo.in
-scons>>> Touch("2")
-scons>>> scons: `foo.out' is up to date.
-scons>>>
-"""
-
-test.finish(scons, stdout = expect_stdout)
-
-
-
test.pass_test()
# Local Variables:
diff --git a/test/Interactive/version.py b/test/Interactive/version.py
index d0f362a..88416ad 100644
--- a/test/Interactive/version.py
+++ b/test/Interactive/version.py
@@ -40,7 +40,7 @@ test.write('SConstruct', "")
# Standard copyright marker is mangled so it doesn't get replaced
# by the packaging build.
copyright_line = """\
-(_{2}COPYRIGHT__|Copyright \\(c\\) 2001[-\d, ]+ The SCons Foundation)
+(_{2}COPYRIGHT__|Copyright \\(c\\) 2001[-\\d, ]+ The SCons Foundation)
"""
expect1 = """\
@@ -53,8 +53,8 @@ scons>>>
scons>>>
"""
-test.run(arguments = '-Q --interactive',
- stdin = "version\nexit\n")
+test.run(arguments='-Q --interactive',
+ stdin="version\nexit\n")
# Windows may or may not print a line for the script version
# depending on whether it's invoked through scons.py or scons.bat.
diff --git a/test/Java/JARFLAGS.py b/test/Java/JARFLAGS.py
index 39a0a6c..6983bf7 100644
--- a/test/Java/JARFLAGS.py
+++ b/test/Java/JARFLAGS.py
@@ -59,10 +59,10 @@ public class Example1
""")
expect = test.wrap_stdout("""\
-javac -d classes -sourcepath src src.Example1\.java
-jar cvf test.jar -C classes src.Example1\.class
+javac -d classes -sourcepath src src.Example1\\.java
+jar cvf test.jar -C classes src.Example1\\.class
.*
-adding: src.Example1\.class.*
+adding: src.Example1\\.class.*
""" % locals())
diff --git a/test/Java/JAVABOOTCLASSPATH.py b/test/Java/JAVABOOTCLASSPATH.py
index 196cc54..8aaf869 100644
--- a/test/Java/JAVABOOTCLASSPATH.py
+++ b/test/Java/JAVABOOTCLASSPATH.py
@@ -84,8 +84,8 @@ public class Example2
bootclasspath = os.pathsep.join(['dir1', 'dir2'])
expect = """\
-javac -bootclasspath %(bootclasspath)s -d class -sourcepath com com.Example1\.java
-javac -bootclasspath %(bootclasspath)s -d class -sourcepath com com.Example2\.java
+javac -bootclasspath %(bootclasspath)s -d class -sourcepath com com.Example1\\.java
+javac -bootclasspath %(bootclasspath)s -d class -sourcepath com com.Example2\\.java
""" % locals()
test.run(arguments = '-Q -n .', stdout = expect, match=TestSCons.match_re)
diff --git a/test/Libs/SharedLibrary.py b/test/Libs/SharedLibrary.py
index cc3fa66..9e22cfa 100644
--- a/test/Libs/SharedLibrary.py
+++ b/test/Libs/SharedLibrary.py
@@ -223,20 +223,17 @@ if sys.platform == 'cygwin':
if sys.platform == 'win32' or sys.platform.find('irix') != -1:
- test.run(arguments = '-f SConstructFoo')
+ test.run(arguments='-f SConstructFoo')
else:
- test.run(arguments = '-f SConstructFoo', status=2, stderr='''\
-scons: \*\*\* \[.*\] Source file: foo\..* is static and is not compatible with shared target: .*
-''',
- match=TestSCons.match_re_dotall)
+ expect = r"scons: \*\*\* \[.*\] Source file: foo\..* is static and is not compatible with shared target: .*"
+ test.run(arguments='-f SConstructFoo', status=2, stderr=expect,
+ match=TestSCons.match_re_dotall)
# Run it again to make sure that we still get the error
# even though the static objects already exist.
- test.run(arguments = '-f SConstructFoo', status=2, stderr='''\
-scons: \*\*\* \[.*\] Source file: foo\..* is static and is not compatible with shared target: .*
-''',
- match=TestSCons.match_re_dotall)
+ test.run(arguments='-f SConstructFoo', status=2, stderr=expect,
+ match=TestSCons.match_re_dotall)
-test.run(arguments = '-f SConstructFoo2',
+test.run(arguments='-f SConstructFoo2',
stderr=TestSCons.noisy_ar,
match=TestSCons.match_re_dotall)
diff --git a/test/Removed/debug-dtree.py b/test/Removed/debug-dtree.py
new file mode 100644
index 0000000..a016f96
--- /dev/null
+++ b/test/Removed/debug-dtree.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that the --debug=dtree option fails with expected exception
+"""
+
+import os
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+
+test.write('SConstruct', "")
+
+expect = r"""usage: scons [OPTION] [TARGET] ...
+
+SCons Error: `dtree' is not a valid debug option type ; please use --tree=derived instead
+"""
+
+test.run(arguments='-Q --debug=dtree', status=2, stderr=expect)
+
+os.environ['SCONSFLAGS'] = '--debug=dtree'
+test.run(arguments="-H", status=2, stderr=expect)
+
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Deprecated/debug-nomemoizer.py b/test/Removed/debug-nomemoizer.py
index 6d05cb2..a830a88 100644
--- a/test/Deprecated/debug-nomemoizer.py
+++ b/test/Removed/debug-nomemoizer.py
@@ -25,30 +25,28 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
-Test calling the (deprecated) --debug=nomemoizer option.
+Test that the --debug=nomemoizer option fails with expected exception
"""
+import os
+
import TestSCons
-test = TestSCons.TestSCons(match = TestSCons.match_re)
+test = TestSCons.TestSCons()
+
-test.write('SConstruct', """
-def cat(target, source, env):
- with open(str(target[0]), 'wb') as ofp, open(str(source[0]), 'rb') as ifp:
- ofp.write(ifp.read())
-env = Environment(BUILDERS={'Cat':Builder(action=Action(cat))})
-env.Cat('file.out', 'file.in')
-""")
+test.write('SConstruct', "")
-test.write('file.in', "file.in\n")
+expect=r"""usage: scons [OPTION] [TARGET] ...
+
+SCons Error: `nomemoizer' is not a valid debug option type ; there is no replacement
+"""
-expect = """
-scons: warning: The --debug=nomemoizer option is deprecated and has no effect.
-""" + TestSCons.file_expr
+test.run(arguments='-Q --debug=nomemoizer', status=2, stderr=expect)
-test.run(arguments = "--debug=nomemoizer", stderr = expect)
+os.environ['SCONSFLAGS'] = '--debug=nomemoizer'
+test.run(arguments="-H", status=2, stderr=expect)
-test.must_match('file.out', "file.in\n")
test.pass_test()
diff --git a/test/Removed/debug-stree.py b/test/Removed/debug-stree.py
new file mode 100644
index 0000000..60ce4f2
--- /dev/null
+++ b/test/Removed/debug-stree.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that the --debug=stree option fails with expected exception
+"""
+
+import os
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+
+test.write('SConstruct', "")
+
+expect = r"""usage: scons [OPTION] [TARGET] ...
+
+SCons Error: `stree' is not a valid debug option type ; please use --tree=all,status instead
+"""
+
+test.run(arguments='-Q --debug=stree', status=2, stderr=expect)
+
+os.environ['SCONSFLAGS'] = '--debug=stree'
+test.run(arguments="-H", status=2, stderr=expect)
+
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Removed/debug-tree.py b/test/Removed/debug-tree.py
new file mode 100644
index 0000000..06287de
--- /dev/null
+++ b/test/Removed/debug-tree.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# 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.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""
+Test that the --debug=tree option fails with expected exception
+Check command-line, SCONSFLAGS and interactive
+"""
+
+import os
+
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+
+test.write('SConstruct', "")
+
+expect = r"""usage: scons [OPTION] [TARGET] ...
+
+SCons Error: `tree' is not a valid debug option type ; please use --tree=all instead
+"""
+
+test.run(arguments='-Q --debug=tree', status=2, stderr=expect)
+
+os.environ['SCONSFLAGS'] = '--debug=tree'
+test.run(arguments="-H", status=2, stderr=expect)
+
+
+# moved test from test/Interactive/tree.py
+scons = test.start(arguments = '-Q --interactive')
+scons.send("build --debug=tree\n")
+test.finish(scons, status=2, stderr=expect)
+
+
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/test/Scanner/CrossLanguageNoExtension.py b/test/Scanner/CrossLanguageNoExtension.py
index 0016ca5..fa38d2f 100644
--- a/test/Scanner/CrossLanguageNoExtension.py
+++ b/test/Scanner/CrossLanguageNoExtension.py
@@ -34,7 +34,7 @@ test = TestSCons.TestSCons()
# for nodes that do not have mappings from their scanner_key
# to a scanner instance
-test.write('SConstruct', """
+test.write('SConstruct', r"""
import re
include_re = re.compile(r'^include\s+(\S+)$', re.M)
@@ -77,7 +77,7 @@ env2.Append(SCANNERS = [ k2scan2 ] )
env2.Command( 'k2', 'foo.k', Copy( '$TARGET', '$SOURCE' ) )
""")
-test.write('foo.k',
+test.write('foo.k',
"""foo.k 1 line 1
include xxx.k
include yyy
diff --git a/test/Scanner/FindPathDirs.py b/test/Scanner/FindPathDirs.py
index 34eb779..3f5204a 100644
--- a/test/Scanner/FindPathDirs.py
+++ b/test/Scanner/FindPathDirs.py
@@ -71,7 +71,7 @@ test.write('SConstruct', """\
SConscript('SConscript')
""")
-test.write('SConscript', """\
+test.write('SConscript', r"""
import os.path
import re
@@ -86,7 +86,7 @@ def kfile_scan(node, env, path, arg):
for inc in includes:
for dir in path:
file = str(dir) + os.sep + inc
- if os.path.exists(file):
+ if os.path.exists(file):
results.append(file)
break
return results
@@ -109,7 +109,7 @@ env.Command('foo', 'foo.k', r'%(_python_)s build.py "$KPATH" $SOURCES $TARGET')
-test.write('foo.k',
+test.write('foo.k',
"""foo.k 1 line 1
include xxx
include yyy
diff --git a/test/Scanner/Scanner.py b/test/Scanner/Scanner.py
index 272f26a..7e39134 100644
--- a/test/Scanner/Scanner.py
+++ b/test/Scanner/Scanner.py
@@ -60,7 +60,7 @@ test.write('SConstruct', """
SConscript('SConscript')
""", mode='w')
-test.write('SConscript', """
+test.write('SConscript', r"""
import re
include_re = re.compile(r'^include\s+(\S+)\s*$', re.M)
@@ -137,7 +137,7 @@ Alias('make_ork', ork)
""" % locals(),mode='w')
-test.write('foo.k',
+test.write('foo.k',
"""foo.k 1 line 1
include xxx
include yyy
@@ -151,7 +151,7 @@ bar.in 1 line 3
include zzz
""", mode='w')
-test.write('junk.k2',
+test.write('junk.k2',
"""include yyy
junk.k2 1 line 2
junk.k2 1 line 3
diff --git a/test/Scanner/dictionary.py b/test/Scanner/dictionary.py
index efe3cd2..f80c7e5 100644
--- a/test/Scanner/dictionary.py
+++ b/test/Scanner/dictionary.py
@@ -61,7 +61,7 @@ test.write('SConstruct', """
SConscript('SConscript')
""")
-test.write('SConscript', """
+test.write('SConscript', r"""
import re
include1_re = re.compile(r'^include1\s+(\S+)$', re.M)
@@ -100,7 +100,7 @@ env.Command('bbb', 'bbb.k2', r'%(_python_)s build.py $SOURCES $TARGET')
env.Command('ccc', 'ccc.k3', r'%(_python_)s build.py $SOURCES $TARGET')
""" % locals())
-test.write('aaa.k1',
+test.write('aaa.k1',
"""aaa.k1 1
line 2
include1 xxx
@@ -109,7 +109,7 @@ include3 zzz
line 6
""")
-test.write('bbb.k2',
+test.write('bbb.k2',
"""bbb.k2 1
line 2
include1 xxx
@@ -118,7 +118,7 @@ include3 zzz
line 6
""")
-test.write('ccc.k3',
+test.write('ccc.k3',
"""ccc.k3 1
line 2
include1 xxx
diff --git a/test/Scanner/exception.py b/test/Scanner/exception.py
index ec19842..90791cb 100644
--- a/test/Scanner/exception.py
+++ b/test/Scanner/exception.py
@@ -37,7 +37,7 @@ test.write('SConstruct', """
SConscript('SConscript')
""")
-test.write('SConscript', """
+test.write('SConscript', r"""
import re
include_re = re.compile(r'^include\s+(\S+)$', re.M)
@@ -82,14 +82,14 @@ bar_in = File('bar.in')
env.Cat('bar', bar_in)
""")
-test.write('foo.k',
+test.write('foo.k',
"""foo.k 1 line 1
include xxx
include yyy
foo.k 1 line 4
""")
-test.write('bar.in',
+test.write('bar.in',
"""include yyy
bar.in 1 line 2
bar.in 1 line 3
diff --git a/test/Scanner/generated.py b/test/Scanner/generated.py
index 5e808e1..f0fb0cc 100644
--- a/test/Scanner/generated.py
+++ b/test/Scanner/generated.py
@@ -188,7 +188,7 @@ env = env.Clone() # Yes, clobber intentionally
""")
-test.write(['src', 'lib_geng', 'SConscript'], """\
+test.write(['src', 'lib_geng', 'SConscript'], r"""
# --- Begin SConscript boilerplate ---
import sys
import Mylib
@@ -280,7 +280,7 @@ env.Command(generated_hdrs.split(),
cmd_generated)
recurse_env.Command([lib_fullname] + lib_objs,
lib_srcs + (generated_hdrs + " " + static_hdrs).split(),
- cmd_justlib)
+ cmd_justlib)
""")
test.write(['src', 'lib_geng', 'MAKE-HEADER.py'], """\
@@ -395,7 +395,7 @@ int g_1()
test.write(['src', 'lib_geng', 'libg_2.c'], """\
#include <libg_w.h>
-#include <libg_gx.h>
+#include <libg_gx.h>
#include <libg_gy.h>
#include <libg_gz.h>
diff --git a/test/Scanner/multi-env.py b/test/Scanner/multi-env.py
index 1cc85d0..e9c231d 100644
--- a/test/Scanner/multi-env.py
+++ b/test/Scanner/multi-env.py
@@ -37,7 +37,7 @@ _python_ = TestSCons._python_
test = TestSCons.TestSCons()
-test.write('SConstruct', """
+test.write('SConstruct', r"""
import re
include_re = re.compile(r'^include\s+(\S+)$', re.M)
diff --git a/test/Scanner/no-Dir-node.py b/test/Scanner/no-Dir-node.py
index a230ea6..ef90934 100644
--- a/test/Scanner/no-Dir-node.py
+++ b/test/Scanner/no-Dir-node.py
@@ -89,7 +89,7 @@ Command('list.out', 'subdir', foo, source_scanner = DirScanner)
SConscript('subdir/SConscript')
""")
-test.write(['subdir', 'SConscript'], """\
+test.write(['subdir', 'SConscript'], r"""
import SCons.Scanner
kscan = SCons.Scanner.Classic(name = 'kfile',
suffixes = ['.k'],
diff --git a/test/Scanner/source_scanner-dict.py b/test/Scanner/source_scanner-dict.py
index f719f00..115c19e 100644
--- a/test/Scanner/source_scanner-dict.py
+++ b/test/Scanner/source_scanner-dict.py
@@ -65,7 +65,7 @@ test.write('SConstruct', """
SConscript('SConscript')
""")
-test.write('SConscript', """
+test.write('SConscript', r"""
import re
include1_re = re.compile(r'^include1\s+(\S+)$', re.M)
@@ -101,7 +101,7 @@ env.Build('ccc', 'ccc.k3')
env.Build('ddd', ['ddd.k4', 'aaa.k1', 'bbb.k2', 'ccc.k3'])
""" % locals())
-test.write('aaa.k1',
+test.write('aaa.k1',
"""aaa.k1 1
line 2
include1 xxx
@@ -110,7 +110,7 @@ include3 zzz
line 6
""")
-test.write('bbb.k2',
+test.write('bbb.k2',
"""bbb.k2 1
line 2
include1 xxx
@@ -119,7 +119,7 @@ include3 zzz
line 6
""")
-test.write('ccc.k3',
+test.write('ccc.k3',
"""ccc.k3 1
line 2
include1 xxx
@@ -128,7 +128,7 @@ include3 zzz
line 6
""")
-test.write('ddd.k4',
+test.write('ddd.k4',
"""ddd.k4 1
line 2
line 3
diff --git a/test/Scanner/unicode.py b/test/Scanner/unicode.py
index 227c72e..0edd5b6 100644
--- a/test/Scanner/unicode.py
+++ b/test/Scanner/unicode.py
@@ -77,7 +77,7 @@ with open(sys.argv[2], 'w') as ofp:
sys.exit(0)
""")
-test.write('SConstruct', """
+test.write('SConstruct', r"""
import re
include_re = re.compile(r'^include\s+(\S+)$', re.M)
diff --git a/test/explain/basic.py b/test/explain/basic.py
index 1e42d33..46ce6bc 100644
--- a/test/explain/basic.py
+++ b/test/explain/basic.py
@@ -51,7 +51,7 @@ inc_bbb_k = test.workpath('inc', 'bbb.k')
-test.write(cat_py, r"""\
+test.write(cat_py, r"""
from __future__ import print_function
import sys
@@ -81,7 +81,7 @@ sys.exit(0)
""")
-SConstruct_contents = """\
+SConstruct_contents = r"""
DefaultEnvironment(tools=[])
import re
@@ -130,7 +130,7 @@ AlwaysBuild(file6)
env.Cat('subdir/file7', 'subdir/file7.in')
env.OneCat('subdir/file8', ['subdir/file7.in', env.Value(%(test_value)s)] )
env.OneCat('subdir/file9', ['subdir/file7.in', env.Value(7)] )
-""" % valueDict )
+""" % valueDict)
test_value = '"first"'
WriteInitialTest( locals() )
diff --git a/test/explain/save-info.py b/test/explain/save-info.py
index 383822c..24ebb88 100644
--- a/test/explain/save-info.py
+++ b/test/explain/save-info.py
@@ -70,7 +70,7 @@ with open(sys.argv[1], 'w') as ofp:
sys.exit(0)
""")
-test.write(['src', 'SConstruct'], """\
+test.write(['src', 'SConstruct'], r"""
DefaultEnvironment(tools=[])
import re
diff --git a/test/import.py b/test/import.py
index 9799850..2725705 100644
--- a/test/import.py
+++ b/test/import.py
@@ -114,8 +114,8 @@ scons: warning: Can't find Intel compiler top dir for version='None', abi='[^']*
""" + TestSCons.file_expr
# Intel no license directory warning
-intel_license_warning = re.escape("""
-scons: warning: Intel license dir was not found. Tried using the INTEL_LICENSE_FILE environment variable (), the registry () and the default path (C:\Program Files\Common Files\Intel\Licenses). Using the default path as a last resort.
+intel_license_warning = re.escape(
+r"""scons: warning: Intel license dir was not found. Tried using the INTEL_LICENSE_FILE environment variable (), the registry () and the default path (C:\Program Files\Common Files\Intel\Licenses). Using the default path as a last resort.
""") + TestSCons.file_expr
intel_warnings = [
diff --git a/test/option--tree.py b/test/option--tree.py
index 0bf2c06..1b34176 100644
--- a/test/option--tree.py
+++ b/test/option--tree.py
@@ -45,13 +45,6 @@ SCons Error: `foofoo' is not a valid --tree option type, try:
""",
status=2)
-test.run(arguments='--debug=tree',
- stderr="""
-scons: warning: The --debug=tree option is deprecated; please use --tree=all instead.
-.*
-""",
- status=0, match=TestSCons.match_re_dotall)
-
# Test that unicode characters can be printed (escaped) with the --tree option
test.write('SConstruct',
diff --git a/test/option-v.py b/test/option-v.py
index 4a67df0..ed8c4e5 100644
--- a/test/option-v.py
+++ b/test/option-v.py
@@ -35,7 +35,7 @@ test.write('SConstruct', "")
# Standard copyright marker is mangled so it doesn't get replaced
# by the packaging build.
copyright_line = """\
-(_{2}COPYRIGHT__|Copyright \\(c\\) 2001[-\d, ]+ The SCons Foundation)
+(_{2}COPYRIGHT__|Copyright \\(c\\) 2001[-\\d, ]+ The SCons Foundation)
"""
# Windows may or may not print a line for the script version
@@ -64,7 +64,7 @@ if not test.match_re(stdout, expect1) and not test.match_re(stdout, expect2):
test.fail_test()
test.pass_test()
-
+
# Local Variables:
# tab-width:4
diff --git a/test/packaging/rpm/explicit-target.py b/test/packaging/rpm/explicit-target.py
index 48b5c83..fba0237 100644
--- a/test/packaging/rpm/explicit-target.py
+++ b/test/packaging/rpm/explicit-target.py
@@ -67,7 +67,7 @@ env.Package( NAME = 'foo',
LICENSE = 'gpl',
SUMMARY = 'balalalalal',
X_RPM_GROUP = 'Application/fu',
- X_RPM_INSTALL = r'%(_python_)s %(scons)s --debug=tree --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"',
+ X_RPM_INSTALL = r'%(_python_)s %(scons)s --tree=all --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"',
DESCRIPTION = 'this should be really really long',
source = [ prog ],
target = "my_rpm_package.rpm",
diff --git a/test/packaging/rpm/multipackage.py b/test/packaging/rpm/multipackage.py
index 2f106f4..4a29a40 100644
--- a/test/packaging/rpm/multipackage.py
+++ b/test/packaging/rpm/multipackage.py
@@ -67,7 +67,7 @@ env.Package( NAME = 'foo',
LICENSE = 'gpl',
SUMMARY = 'balalalalal',
X_RPM_GROUP = 'Application/fu',
- X_RPM_INSTALL = r'%(_python_)s %(scons)s --debug=tree --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"',
+ X_RPM_INSTALL = r'%(_python_)s %(scons)s --tree=all --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"',
DESCRIPTION = 'this should be really really long',
source = [ prog ],
SOURCE_URL = 'http://foo.org/foo-1.2.3.tar.gz'
@@ -80,7 +80,7 @@ env.Package( NAME = 'foo2',
LICENSE = 'gpl',
SUMMARY = 'balalalalal',
X_RPM_GROUP = 'Application/fu',
- X_RPM_INSTALL = r'%(_python_)s %(scons)s --debug=tree --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"',
+ X_RPM_INSTALL = r'%(_python_)s %(scons)s --tree=all --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"',
DESCRIPTION = 'this should be really really long',
source = [ prog ],
)
diff --git a/test/packaging/rpm/package.py b/test/packaging/rpm/package.py
index 23ebe05..0ef5fad 100644
--- a/test/packaging/rpm/package.py
+++ b/test/packaging/rpm/package.py
@@ -66,7 +66,7 @@ env.Package( NAME = 'foo',
LICENSE = 'gpl',
SUMMARY = 'balalalalal',
X_RPM_GROUP = 'Application/fu',
- X_RPM_INSTALL = r'%(_python_)s %(scons)s --debug=tree --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"',
+ X_RPM_INSTALL = r'%(_python_)s %(scons)s --tree=all --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"',
DESCRIPTION = 'this should be really really long',
source = [ prog ],
SOURCE_URL = 'http://foo.org/foo-1.2.3.tar.gz'
diff --git a/test/runtest/xml/output.py b/test/runtest/xml/output.py
index 88bca04..cd20dbd 100644
--- a/test/runtest/xml/output.py
+++ b/test/runtest/xml/output.py
@@ -65,7 +65,7 @@ expect = """\
</stdout>
<stderr>FAILING TEST STDERR
</stderr>
- <time>\\d+\.\d</time>
+ <time>\\d+\\.\\d</time>
</test>
<test>
<file_name>%(test_no_result_py)s</file_name>
@@ -75,7 +75,7 @@ expect = """\
</stdout>
<stderr>NO RESULT TEST STDERR
</stderr>
- <time>\\d+\.\d</time>
+ <time>\\d+\\.\\d</time>
</test>
<test>
<file_name>%(test_pass_py)s</file_name>
@@ -85,9 +85,9 @@ expect = """\
</stdout>
<stderr>PASSING TEST STDERR
</stderr>
- <time>\\d+\.\d</time>
+ <time>\\d+\\.\\d</time>
</test>
- <time>\\d+\.\d</time>
+ <time>\\d+\\.\\d</time>
</results>
""" % locals()
diff --git a/test/srcchange.py b/test/srcchange.py
index e396fb8..f1f67c1 100644
--- a/test/srcchange.py
+++ b/test/srcchange.py
@@ -42,13 +42,13 @@ _python_ = TestSCons._python_
test = TestSCons.TestSCons()
-test.write('getrevision', """
+test.write('getrevision', r"""
from __future__ import print_function
-with open('revnum.in','r') as f:
+with open('revnum.in', 'r') as f:
print(f.read().strip(), end='')
""")
-test.write('SConstruct', """
+test.write('SConstruct', r"""
import re
def subrevision(target, source ,env):
@@ -63,7 +63,7 @@ SubRevision = Action(subrevision)
env=Environment()
content_env=env.Clone()
-content_env.Command('revision.in', [], r'%(_python_)s getrevision > $TARGET')
+content_env.Command('revision.in', [], '%(_python_)s getrevision > $TARGET')
content_env.AlwaysBuild('revision.in')
env.Precious('main.c')
env.Command('main.c', 'revision.in', SubRevision)
diff --git a/test/timestamp-fallback.py b/test/timestamp-fallback.py
index f4e2e4d..2dd50a2 100644
--- a/test/timestamp-fallback.py
+++ b/test/timestamp-fallback.py
@@ -25,11 +25,14 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
"""
-Verify falling back to 'timestamp' behavior if there is no native
-hashlib and no underlying md5 module available.
+Verify falling back to 'timestamp' behavior if there is no md5
+module. Formerly checked for hashlib first, but that has been
+standard library since 2.5; test is kept in case one of those
+rare no-md5 Pythons comes into play (some entities ban the use
+of md5 as unsafe, although SCons does not use it in a security context.
"""
-import imp
+import sys
import os
import TestSCons
@@ -37,24 +40,14 @@ import TestSCons
test = TestSCons.TestSCons()
try:
- file, name, desc = imp.find_module('hashlib')
+ from hashlib import md5
except ImportError:
pass
else:
- msg = "This version of Python has a 'hashlib' module.\n" + \
- "Skipping test of falling back to timestamps.\n"
+ msg = "The 'md5' algorithm is built in to hashlib in this version of Python.\n" + \
+ "Cannot test falling back to timestamps.\n"
test.skip_test(msg)
-try:
- file, name, desc = imp.find_module('md5')
-except ImportError:
- pass
-else:
- if desc[2] == imp.C_BUILTIN:
- msg = "The 'md5' module is built in to this version of Python.\n" + \
- "Cannot test falling back to timestamps.\n"
- test.skip_test(msg)
-
test.write('md5.py', r"""
raise ImportError
""")
@@ -66,7 +59,7 @@ DefaultEnvironment(tools=[])
def build(env, target, source):
with open(str(target[0]), 'wt') as ofp, open(str(source[0]), 'rt') as ifp:
- opf.write(ifp.read())
+ ofp.write(ifp.read())
B = Builder(action = build)
env = Environment(tools = [], BUILDERS = { 'B' : B })
diff --git a/timings/README.txt b/timings/README.txt
index 9921208..e71471c 100644
--- a/timings/README.txt
+++ b/timings/README.txt
@@ -91,7 +91,7 @@ hierarchy, you use a normal runtest.py invocation to run the timings
configuration:
$ python runtest.py timings/Configuration/TimeSCons-run.py
-
+
This runs the entire timing configuration, which actually runs SCons
itself three times:
diff --git a/timings/hundred/TimeSCons-run.py b/timings/hundred/TimeSCons-run.py
index 3d5b02f..3bee58a 100644
--- a/timings/hundred/TimeSCons-run.py
+++ b/timings/hundred/TimeSCons-run.py
@@ -47,7 +47,8 @@ import TestSCons
test = TestSCons.TimeSCons(variables={'TARGET_COUNT':139})
for t in range(test.variables['TARGET_COUNT']):
- open('source_%04d' % t, 'wb' ).write('contents\n')
+ with open('source_%04d' % t, 'w') as f:
+ f.write('contents\n')
test.main()