diff options
author | William Deegan <bill@baddogconsulting.com> | 2019-10-08 01:44:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-08 01:44:22 (GMT) |
commit | 43cebd68db3696a4a7fdd2d38a81842d18d6d2cd (patch) | |
tree | a34d8ba5c57dc97eb9e4e9b11a8507fcf20ff329 | |
parent | 581a6912938f3143b2c31dcb78ecc9928da124df (diff) | |
parent | b161cf3f51e376a82208081e3f83dd96e2a4d6bf (diff) | |
download | SCons-43cebd68db3696a4a7fdd2d38a81842d18d6d2cd.zip SCons-43cebd68db3696a4a7fdd2d38a81842d18d6d2cd.tar.gz SCons-43cebd68db3696a4a7fdd2d38a81842d18d6d2cd.tar.bz2 |
Merge branch 'master' into CmdStringHolder
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 < ${SOURCE.file} > ${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 < ${SOURCE.file} > ${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 . > $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 > foo.out <literallayout class="monospaced"> echo BAR > 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 < $SOURCES > $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 < $SOURCES > .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() |