From d9f49c49338f544e3694b6f6a514667cc13a15de Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 3 Aug 2019 07:57:32 -0600 Subject: Update bench and timings dirs for Py3 Minor changes for compatibility. Cannot currently run these tests effectively: 1. One of the bench runs doesn't work on Py3 yet. is_types.py fails with: ``` Traceback (most recent call last): File "bench.py", line 91, in exec(open(args[0], 'r').read()) File "", line 16, in AttributeError: module 'types' has no attribute 'InstanceType' ``` The test fundamentally depends on checking if a type is an instance as part of what's being timed; the problem is types.InstanceType was only meaningful for old-style classes where all instances have the same type. Since that can't happen in Python 3 with new-style classes only, types.InstanceType has been removed entirely. Is it worth trying to figure out how to rejigger the test? 2. The calibrarions on the timings configs are horribly wrong for the local machine (10x too small), but not sure what to calibrate them for. 3. The calibration algorithm sometimes goes off base. The objective is to converge on something just under 10 seconds, and hit it three times in a row. In this snippet #25 got close, then we keep iterating and get further away in #27, #29, #31, #33 (this particular calibration eventually hit it's three with runs #55-57. ``` run 25: 9.207: TARGET_COUNT=1019 run 26: 11.026: TARGET_COUNT=1106 run 27: 8.630: TARGET_COUNT=1003 run 28: 12.046: TARGET_COUNT=1162 run 29: 8.240: TARGET_COUNT=964 run 30: 12.062: TARGET_COUNT=1169 run 31: 8.232: TARGET_COUNT=969 run 32: 12.470: TARGET_COUNT=1177 run 33: 8.185: TARGET_COUNT=943 ``` 4. Running any of the timings fails with stdout mismatch, as there is (unexpected?) timing output. Example CPPPATH - see the second line of the captured output for the extra data. Is this new data emitted by debug=time that the timings code is not expecting? ``` /home/mats/.pyenv/versions/python-3.7.3/bin/python /home/mats/github/scons/src/script/scons.py DIR_COUNT=813 --debug=memory,time . STDOUT ========================================================================= 1,6c1,14 < scons:\ Reading\ SConscript\ files\ \.\.\.\ < scons:\ done\ reading\ SConscript\ files\.\ < scons:\ Building\ targets\ \.\.\.\ < scons:\ `\.'\ is\ up\ to\ date\.\ < scons:\ done\ building\ targets\.\ < .* --- > scons: Reading SConscript files ... > SConscript:/tmp/testcmd.256448.xbxk_gj1/SConstruct took 107.051 ms > scons: done reading SConscript files. > scons: Building targets ... > scons: `.' is up to date. > scons: done building targets. > Memory before reading SConscript files: 139239424 > Memory after reading SConscript files: 145399808 > Memory before building targets: 145399808 > Memory after building targets: 148684800 > Total build time: 0.311640 seconds > Total SConscript file execution time: 0.107460 seconds > Total SCons execution time: 0.204180 seconds > Total command execution time: 0.000000 seconds FAILED test of /home/mats/github/scons/src/script/scons.py ... from line 53 of timings/CPPPATH/TimeSCons-run.py ``` 5. CPPPATH timing config runs into a command-line length problem if calibrating. Might be a testcase for using a file for long command lines even in the gcc case? ``` run 1: 0.490: DIR_COUNT=813 1/1 (100.00%) /home/mats/.pyenv/versions/python-3.7.3/bin/python timings/CPPPATH/TimeSCons-run.py /home/mats/github/scons/src/script/scons.py returned 2 STDOUT ========================================================================= scons: Reading SConscript files ... SConscript:/tmp/testcmd.253125.kkqcvz12/SConstruct took 1186.979 ms scons: done reading SConscript files. scons: Building targets ... gcc -o foo.o -c -Iinc_0000 -Iinc_0001 -Iinc_0002 ... incredibly long line chopped ... Iinc_16574 -Iinc_16575 -Iinc_16576 -Iinc_16577 -Iinc_16578 -Iinclude foo.c scons: building terminated because of errors. Memory before reading SConscript files: 139243520 Memory after reading SConscript files: 233705472 Memory before building targets: 233705472 Memory after building targets: 255672320 Total build time: 5.079720 seconds Total SConscript file execution time: 1.189501 seconds Total SCons execution time: 3.890219 seconds Total command execution time: 0.000000 seconds FAILED test of /home/mats/github/scons/src/script/scons.py ... from line 53 of timings/CPPPATH/TimeSCons-run.py STDERR ========================================================================= scons: *** [foo.o] sh: Argument list too long Traceback (most recent call last): File "bin/calibrate.py", line 88, in sys.exit(main()) File "bin/calibrate.py", line 69, in main elapsed = float(em.group(1)) AttributeError: 'NoneType' object has no attribute 'group' ``` Signed-off-by: Mats Wichmann --- bench/bench.py | 3 ++- bench/env.__setitem__.py | 2 +- bin/calibrate.py | 10 ++++++---- timings/README.txt | 2 +- timings/hundred/TimeSCons-run.py | 3 ++- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/bench/bench.py b/bench/bench.py index 3f7dbc6..7a4083b 100644 --- a/bench/bench.py +++ b/bench/bench.py @@ -95,7 +95,8 @@ 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/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/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() -- cgit v0.12 From 5e7d0bdccd7369c5b54ff09b005627fab4f80866 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 31 Aug 2019 04:36:18 -0600 Subject: More bench tweaks [ci skip] - prefer time.perf_counter if available - catch case where time.clock unavail - lift comment from timeit on why different clock routins - get rid of timeit.py so use the stdlib version Signed-off-by: Mats Wichmann --- bench/bench.py | 35 +++++-- bench/timeit.py | 298 -------------------------------------------------------- 2 files changed, 26 insertions(+), 307 deletions(-) delete mode 100644 bench/timeit.py diff --git a/bench/bench.py b/bench/bench.py index 7a4083b..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,9 +105,8 @@ 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 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 = "" -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: -- cgit v0.12 From 4cad178b1b9f0cfef7fca3dbbc48c69052532b95 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 8 Sep 2019 10:03:20 -0600 Subject: [fix #2444) update env.Whereis docu [ci skip] Apply the patch in the issue, and further tweak the wording. Signed-off-by: Mats Wichmann --- src/engine/SCons/Environment.xml | 53 ++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 5137bad..f222620 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -3650,30 +3650,51 @@ SConscript(dirs='doc', variant_dir='build/doc', duplicate=0) Searches for the specified executable program, returning the full path name to the program -if it is found, -and returning None if not. -Searches the specified -path, -the value of the calling environment's PATH -(env['ENV']['PATH']), -or the user's current external PATH -(os.environ['PATH']) -by default. +if it is found, else None. +Searches the value of the +path keyword argument, +or if None (the default) +the value of the calling environment's PATH +(env['ENV']['PATH']). +If path is None and +the env['ENV']['PATH'] key does not exist, +the user's current external PATH +(os.environ['PATH']) is used as fallback. + + On Windows systems, searches for executable -programs with any of the file extensions -listed in the specified -pathext, -the calling environment's PATHEXT -(env['ENV']['PATHEXT']) -or the user's current PATHEXT +programs with any of the file extensions listed in the +pathext keyword argument, +or if None (the default) +the calling environment's PATHEXT +(env['ENV']['PATHEXT']). +The user's current external PATHEXT (os.environ['PATHEXT']) -by default. +is used as a fallback if pathext is +None +and the key env['ENV']['PATHEXT'] +does not exist. + + Will not select any path name or names in the specified reject list, if any. + + +If you would prefer to search +the user's current external PATH +(os.environ['PATH']) +by default, +consider using the function SCons.Util.WhereIs instead. +Note that SCons.Util.WhereIs +does not expand environment variables automatically +(no implicit env.subst for its arguments). + + + -- cgit v0.12 From a04eb12f7a47992d1e352b3126479ef9a3f28eee Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 1 Sep 2019 13:30:53 -0600 Subject: Builder and Variable Subst doc updates [ci skip] Work on Builder Methods and Variable Substitution man sections - some wording tweaks, do some formatting markup a little more consistently, etc. Tweak the wording for the Command builder, a description shared between manpage and userguide. Closes #3030: Environment.xml had many references to detail sections elsewhere, like "see XXX section below," which don't work well - this xml is generated into both the manpage and the user guide, and the locality of saying "below" is incorrect for the latter since those sections are only in the manpage. Essentially these are changed to say "see the manpage section XXX". Adding clickable links is of course also possible, but I recall there was some objection to cross-document links, so I didn't do that. Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 362 +++++++++++++++++++++++---------------- src/engine/SCons/Environment.xml | 96 ++++++----- 2 files changed, 267 insertions(+), 191 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index faec455..c1773c7 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -1921,7 +1921,7 @@ These warnings are enabled by default. feature not working when scons -is run with the python +is run with the Python option or from optimized Python (.pyo) modules. @@ -2048,7 +2048,7 @@ env['BAR'] = 'bar' As a convenience, construction variables may also be set or modified by the -parse_flags +parse_flags keyword argument, which applies the &f-link-env-MergeFlags; method (described below) to the argument value @@ -2228,7 +2228,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']) @@ -2247,7 +2247,7 @@ With a nested tool name the dot represents a directory seperator # 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 +2293,104 @@ env.SomeTool(targets, sources) Builder Methods -Build rules are specified by calling a construction -environment's builder methods. -The arguments to the builder methods are -target -(a list of targets to be built, -usually file names) +You tell scons 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. scons +defines a number of builders, and you can also write your own. +Builders are attached to a &consenv; as methods, +and the available builder methods are listed as +key-value pairs in the +BUILDERS attribute of the &consenv;. +The available builders can be displayed like this +for debugging purposes: + + + +print("Builders:", list(env['BUILDERS'])) + + + +Builder methods always take two arguments: +target +(a target or a list of targets to be built) and -source -(a list of sources to be built, -usually file names). +source +(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. + Because long lists of file names can lead to a lot of quoting, scons -supplies a -Split() +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.) +(These are similar to the Python string split +method, but work even if the input isn't a string.) -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: + +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 target= +and source=. +The following are equivalent examples of calling the +&Program; builder method: + 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()) -Target and source file names -that are not absolute path names -(that is, do not begin with -/ -on POSIX systems -or -\ -on Windows systems, -with or without -an optional drive letter) -are interpreted relative to the directory containing the -SConscript -file being read. -An initial -# -(hash mark) -on a path name means that the rest of the file name -is interpreted relative to -the directory containing -the top-level -SConstruct -file, -even if the -# -is followed by a directory separator character -(slash or backslash). + +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. + + +scons recognizes a third way to specify +path strings: if the string begins with +the # character it is +top-relative - it works like a relative path but the +search follows down from the directory containing the top-level +SConstruct rather than +from the current directory (the # 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. + + + +Target and source pathnames can be absolute, relative, or +top-relative. Relative pathnames are searched considering the +directory of the SConscript +file currently being processed as the "current directory". + Examples: @@ -2403,12 +2432,12 @@ executable program or bar.exe (on Windows systems) -from the bar.c source file: +from the bar.c source file: -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') @@ -2418,28 +2447,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 srcdir. The following example will build the -build/prog +build/prog (or -build/prog.exe +build/prog.exe on Windows) program from the files -src/f1.c +src/f1.c and -src/f2.c: +src/f2.c: + env.Program('build/prog', ['f1.c', 'f2.c'], srcdir='src') -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: +It is possible to override (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: env.Program('hello', 'hello.c', LIBS=['gl', 'glut']) @@ -2459,7 +2491,7 @@ for dependencies on the non-standard library names; see the descriptions of these variables, below, for more information.) It is also possible to use the -parse_flags +parse_flags keyword argument in an override, to merge command-line style arguments into the appropriate construction variables @@ -2504,8 +2536,7 @@ from SCons.Script import * 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 Node is an internal SCons object @@ -2517,9 +2548,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 - -flag when compiling one specific object file: +to add a specific preprocessor define +when compiling one specific object file: bar_obj_list = env.StaticObject('bar.c', CPPDEFINES='-DBAR') @@ -2530,14 +2560,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. +when calling the &Program; builder method. -Note that Builder calls will automatically "flatten" +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 bar_obj_list +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: @@ -2549,8 +2579,7 @@ for object in objects: print(str(object)) -Or you can use the -Flatten() +Or you can use the &Flatten; function supplied by scons to create a list containing just the Nodes, which may be more convenient: @@ -2563,23 +2592,23 @@ for object in objects: print(str(object)) -Note also that because Builder calls return +Note also that because builder calls return a list-like object, not an actual Python list, you should not -use the Python -+= -operator to append Builder results to a Python list. +use the Python add +operator (+ or +=) +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 -.extend() +Instead, use the Python list +extend method to make sure the list is updated in-place. Example: @@ -2592,7 +2621,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')) @@ -2609,7 +2638,7 @@ print("The path to bar_obj is:", str(bar_obj_list[0])) Note again that because the Builder call returns a list, we have to access the first element in the list -(bar_obj_list[0]) +((bar_obj_list[0])) to get at the Node that actually represents the object file. @@ -2672,7 +2701,12 @@ to use just the filename portion of the targets and source. scons -provides the following builder methods: +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;. @@ -4409,7 +4443,7 @@ functions return and Dir Nodes, respectively. -python objects, respectively. +Python objects, respectively. Those objects have several user-visible attributes and methods that are often useful: @@ -5426,17 +5460,15 @@ a = Action(build_it, varlist=['XXX']) The -Action() +&Action; global function can be passed the following optional keyword arguments to modify the Action object's behavior: - -chdir -The -chdir -keyword argument specifies that + +chdir +specifies that scons will execute the action after changing to the specified directory. If the @@ -5481,15 +5513,9 @@ a = Action("build < ${SOURCE.file} > ${TARGET.file}", chdir=1) - -exitstatfunc -The -Action() -global function -also takes an -exitstatfunc -keyword argument -which specifies a function + +exitstatfunc +specifies a function that is passed the exit status (or return value) from the specified action @@ -5511,11 +5537,9 @@ a = Action("build < ${SOURCE.file} > ${TARGET.file}", -batch_key -The -batch_key -keyword argument can be used -to specify that the Action can create multiple target files + +batch_key +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 +5548,7 @@ to a single invocation of a compiler such as Microsoft's Visual C / C++ compiler.) If the batch_key -argument is any non-False, non-callable Python value, +argument evaluates True and is not a callable object, the configured Action object will cause scons to collect all targets built with the Action object @@ -5556,7 +5580,7 @@ will be used to identify different for batch building. A batch_key -function must take the following arguments: +function must accept the following arguments: @@ -5688,7 +5712,7 @@ sequences of file manipulation without relying on platform-specific external commands: -that + env = Environment(TMPBUILD = '/tmp/builddir') env.Command('foo.out', 'foo.in', @@ -5848,13 +5872,13 @@ env.Command('marker', 'input_file', Before executing a command, scons -performs construction variable interpolation on the strings that make up -the command line of builders. -Variables are introduced by a -$ +performs construction variable interpolation on the string that makes up +the command line of the builder. +Variables are introduced in such strings by a +$ prefix. -Besides construction variables, scons provides the following -variables for each command execution: +Besides regular construction variables, scons provides the following +special variables for each command execution: @@ -5923,15 +5947,19 @@ from sources that have not changed since the target was last built. -(Note that the above variables are reserved -and may not be set in a construction environment.) - -For example, given the construction variable CC='cc', targets=['foo'], and -sources=['foo.c', 'bar.c']: +Note that the above variables are reserved +and may not be set in a construction environment. + +For example, given the construction variables +CC='cc', +targets=['foo'] +and +sources=['foo.c', 'bar.c']: + action='$CC -c -o $TARGET $SOURCES' @@ -5944,7 +5972,8 @@ cc -c -o foo foo.c bar.c Variable names may be surrounded by curly braces ({}) -to separate the name from the trailing characters. +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 +6136,42 @@ may be a callable Python function associated with a construction variable in the environment. The function should -take four arguments: -target -- a list of target nodes, -source -- a list of source nodes, -env -- the construction environment, -for_signature -- a Boolean value that specifies +accept four arguments: + + + + target + +a list of target nodes + + + + source + +a list of source nodes + + + + env + +the construction environment + + + + for_signature + +a Boolean value that specifies whether the function is being called -for generating a build signature. +for generating a build signature. + + + + + SCons will insert whatever the called function returns -into the expanded string: +into the expanded string: + def foo(target, source, env, for_signature): @@ -6201,9 +6252,10 @@ echo Last build occurred . > $TARGET Python Code Substitution -Any python code within -${-} -pairs gets evaluated by python 'eval', with the python globals set to +Any Python code within +curly braces (and introduced by the variable prefix $) +gets evaluated by the Python eval statement, +with the Python globals set to the current environment's set of construction variables. So in the following case: @@ -6219,14 +6271,20 @@ echo FOO > foo.out echo BAR > foo.out -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 +according to the current value of env['COND'] +when the command is executed. +The evaluation takes place when the target is being +built, not when the SConscript is being read. So if +env['COND'] is changed later in the SConscript, the final value will be used. -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 +Here's a more interesting example. Note that all of +COND, +FOO, +and +BAR are construction variables, +and their values are substituted into the final command. +FOO is a list, so its elements are interpolated separated by spaces. @@ -6574,9 +6632,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 /cygdrive/c/mydir to an equivalent Windows pathname -of C:/mydir (equivalent to C:\mydir). +of C:/mydir (equivalent to C:\mydir). + Versions of Python that are built for native Windows execution, @@ -6584,7 +6643,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 gcc, bison, +and flex) may yield unpredictable results. "Mixing and matching" in this way can be made to work, diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index f222620..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. @@ -160,7 +160,8 @@ below, for more information. 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). @@ -170,7 +171,8 @@ that may not be set or used in a construction environment. 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). @@ -180,7 +182,8 @@ that may not be set or used in a construction environment. 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). @@ -190,7 +193,8 @@ that may not be set or used in a construction environment. 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). @@ -200,7 +204,8 @@ that may not be set or used in a construction environment. 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). @@ -210,7 +215,8 @@ that may not be set or used in a construction environment. 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). @@ -220,7 +226,8 @@ that may not be set or used in a construction environment. 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). @@ -230,7 +237,8 @@ that may not be set or used in a construction environment. 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). @@ -255,8 +263,8 @@ that are part of this construction environment. Creates an Action object for the specified action. -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. @@ -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. @@ -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. @@ -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). @@ -634,8 +644,8 @@ or Creates a Builder object for the specified action. -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. @@ -898,11 +908,15 @@ wx_env = env.Clone(parse_flags='!wx-config --cflags --cxxflags') -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. @@ -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]) @@ -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 -env.Dir() +env.Dir functions. @@ -1011,9 +1025,9 @@ env.Command(env.Dir('$DISTDIR')), None, make_distdir) -(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. @@ -1029,8 +1043,8 @@ so you normally don't need to create directories by hand.) 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. @@ -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. @@ -1458,8 +1473,8 @@ Executes an Action object. The specified action 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. @@ -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. @@ -2658,8 +2674,8 @@ env.Requires('foo', 'file-that-must-be-built-before-foo') Creates a Scanner object for the specified function. -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. -- cgit v0.12 From 83eb72eeadd7585a4cf69dd7f560be7995480db5 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 10 Sep 2019 08:18:38 -0600 Subject: [PR #3437] review comment - add back curly braces Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index c1773c7..fea9d89 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -2308,7 +2308,7 @@ for debugging purposes: print("Builders:", list(env['BUILDERS'])) - + Builder methods always take two arguments: @@ -5971,7 +5971,8 @@ action='$CC -c -o $TARGET $SOURCES' cc -c -o foo foo.c bar.c -Variable names may be surrounded by curly braces ({}) +Variable names may be surrounded by curly braces +{ } to separate the name from surrounding characters which are not part of the name. Within the curly braces, a variable name may have @@ -6252,8 +6253,10 @@ echo Last build occurred . > $TARGET Python Code Substitution -Any Python code within -curly braces (and introduced by the variable prefix $) + +Any Python code within curly braces +{ } +and introduced by the variable prefix $ gets evaluated by the Python eval statement, with the Python globals set to the current environment's set of construction variables. -- cgit v0.12 From 2781e4e52b0910c408b0ffc7c0bc1b511a42a754 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 11 Sep 2019 10:57:57 -0600 Subject: Remove deprecated debug options These options have been deprecated since 2007. They were originally announced to be disabled in SCons 2.0.0, but that didn't happen. Left the deprecated-debug-options behavior is in, but the dictionary of such options is now empty, and there's a new dict of removed options, and presence in that dict raises an exception. The four tests that were in test/Deprecated move to a new directory test/Removed and are simplified just to make sure invocation errors scons out. (git interprets most of these as remove/add for some reason) These appear to have been already removed from docs, so no doc impact. Signed-off-by: Mats Wichmann --- src/CHANGES.txt | 1 + src/engine/SCons/Script/SConsOptions.py | 20 +++- test/Deprecated/debug-dtree.py | 120 ------------------------ test/Deprecated/debug-nomemoizer.py | 59 ------------ test/Deprecated/debug-stree.py | 139 --------------------------- test/Deprecated/debug-tree.py | 160 -------------------------------- test/Removed/debug-dtree.py | 57 ++++++++++++ test/Removed/debug-nomemoizer.py | 57 ++++++++++++ test/Removed/debug-stree.py | 57 ++++++++++++ test/Removed/debug-tree.py | 57 ++++++++++++ 10 files changed, 245 insertions(+), 482 deletions(-) delete mode 100644 test/Deprecated/debug-dtree.py delete mode 100644 test/Deprecated/debug-nomemoizer.py delete mode 100644 test/Deprecated/debug-stree.py delete mode 100644 test/Deprecated/debug-tree.py create mode 100644 test/Removed/debug-dtree.py create mode 100644 test/Removed/debug-nomemoizer.py create mode 100644 test/Removed/debug-stree.py create mode 100644 test/Removed/debug-tree.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 87f4e28..dd7f9bd 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -15,6 +15,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From Mats Wichmann - Replace instances of string find method with "in" checks where the index from find() was not used. + - Turn previously deprecated debug options into failures. RELEASE 3.1.1 - Mon, 07 Aug 2019 20:09:12 -0500 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/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 -#include -#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-nomemoizer.py b/test/Deprecated/debug-nomemoizer.py deleted file mode 100644 index 6d05cb2..0000000 --- a/test/Deprecated/debug-nomemoizer.py +++ /dev/null @@ -1,59 +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 calling the (deprecated) --debug=nomemoizer option. -""" - -import TestSCons - -test = TestSCons.TestSCons(match = TestSCons.match_re) - -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('file.in', "file.in\n") - -expect = """ -scons: warning: The --debug=nomemoizer option is deprecated and has no effect. -""" + TestSCons.file_expr - -test.run(arguments = "--debug=nomemoizer", stderr = expect) - -test.must_match('file.out', "file.in\n") - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/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 -#include -#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 -#include -#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/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/Removed/debug-nomemoizer.py b/test/Removed/debug-nomemoizer.py new file mode 100644 index 0000000..a830a88 --- /dev/null +++ b/test/Removed/debug-nomemoizer.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=nomemoizer option fails with expected exception +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons() + + +test.write('SConstruct', "") + +expect=r"""usage: scons [OPTION] [TARGET] ... + +SCons Error: `nomemoizer' is not a valid debug option type ; there is no replacement +""" + +test.run(arguments='-Q --debug=nomemoizer', status=2, stderr=expect) + +os.environ['SCONSFLAGS'] = '--debug=nomemoizer' +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-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..73aa4c9 --- /dev/null +++ b/test/Removed/debug-tree.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=tree option fails with expected exception +""" + +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) + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From f3937a8b0f71fc10e05e81aaaf47824600d3be58 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 12 Sep 2019 12:06:39 -0600 Subject: [PR #3444] fix test issues with --debug removals There were several uses of deprecated debug flags that had not been moved to to test/Deprecated, and so were missed when those moved to test/Removed. Also removed options from manpage. Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 40 ----------------------------------- src/CHANGES.txt | 3 ++- test/Interactive/tree.py | 17 --------------- test/Removed/debug-tree.py | 7 ++++++ test/option--tree.py | 7 ------ test/packaging/rpm/explicit-target.py | 2 +- test/packaging/rpm/multipackage.py | 4 ++-- test/packaging/rpm/package.py | 2 +- 8 files changed, 13 insertions(+), 69 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index fea9d89..eb9f00b 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. - --debug=dtree - -A synonym for the newer - -option. -This will be deprecated in some future release -and ultimately removed. - - - - --debug=explain Print an explanation of precisely why @@ -793,13 +782,6 @@ and before and after building targets. - --debug=nomemoizer - -A deprecated option preserved for backwards compatibility. - - - - --debug=objects Prints a list of the various objects @@ -856,17 +838,6 @@ when encountering an otherwise unexplained error. - --debug=stree - -A synonym for the newer - -option. -This will be deprecated in some future release -and ultimately removed. - - - - --debug=time Prints various time profiling information: @@ -923,17 +894,6 @@ should take place in parallel.) - --debug=tree - -A synonym for the newer - -option. -This will be deprecated in some future release -and ultimately removed. - - - - --diskcheck=types Enable specific checks for diff --git a/src/CHANGES.txt b/src/CHANGES.txt index dd7f9bd..4078669 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -15,7 +15,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From Mats Wichmann - Replace instances of string find method with "in" checks where the index from find() was not used. - - Turn previously deprecated debug options into failures. + - Turn previously deprecated debug options into failures: + --debug=tree, --debug=dtree, --debug=stree, --debug=nomemoizer. RELEASE 3.1.1 - Mon, 07 Aug 2019 20:09:12 -0500 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/Removed/debug-tree.py b/test/Removed/debug-tree.py index 73aa4c9..06287de 100644 --- a/test/Removed/debug-tree.py +++ b/test/Removed/debug-tree.py @@ -26,6 +26,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test that the --debug=tree option fails with expected exception +Check command-line, SCONSFLAGS and interactive """ import os @@ -48,6 +49,12 @@ 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: 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/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' -- cgit v0.12 From fa1affd9d48c795f911f281b88291a8b8248627c Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 8 Aug 2019 09:51:04 -0600 Subject: test: Fix SyntaxWarnings on escapes in Python strings This is the remaining batch of SyntaxWarning cleanups in the test/ directory, as flagged by Python 3.8 (now tested with 3.8.0b4). Most of these are escapes in strings that are not recognized as Python-language escapes up front, due to the embedded nature of testing - tests write a string to a file which is actually Python (code or sconscript) which is later to be executed. Also changed the timestamp-fallback test to eliminate an imp module DeprecationWarning: since in all supported Python versions haslib is stdlib, drop that skip check; the md5 skip check can be a simple import now. My test runs with 3.8 show no SyntaxWarnings after this. Signed-off-by: Mats Wichmann --- test/Errors/execute-a-directory.py | 12 ++++++------ test/Errors/non-executable-file.py | 10 +++++----- test/Interactive/shell.py | 4 ++-- test/Interactive/version.py | 6 +++--- test/Java/JARFLAGS.py | 6 +++--- test/Java/JAVABOOTCLASSPATH.py | 4 ++-- test/Libs/SharedLibrary.py | 17 +++++++---------- test/Scanner/CrossLanguageNoExtension.py | 4 ++-- test/Scanner/FindPathDirs.py | 6 +++--- test/Scanner/Scanner.py | 6 +++--- test/Scanner/dictionary.py | 8 ++++---- test/Scanner/exception.py | 6 +++--- test/Scanner/generated.py | 6 +++--- test/Scanner/multi-env.py | 2 +- test/Scanner/no-Dir-node.py | 2 +- test/Scanner/source_scanner-dict.py | 10 +++++----- test/Scanner/unicode.py | 2 +- test/explain/basic.py | 6 +++--- test/explain/save-info.py | 2 +- test/import.py | 4 ++-- test/option-v.py | 4 ++-- test/runtest/xml/output.py | 8 ++++---- test/srcchange.py | 8 ++++---- test/timestamp-fallback.py | 27 ++++++++++----------------- 24 files changed, 80 insertions(+), 90 deletions(-) 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/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/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 -#include +#include #include #include 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-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/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 = """\ FAILING TEST STDERR - + %(test_no_result_py)s @@ -75,7 +75,7 @@ expect = """\ NO RESULT TEST STDERR - + %(test_pass_py)s @@ -85,9 +85,9 @@ expect = """\ PASSING TEST STDERR - + - + """ % 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 }) -- cgit v0.12 From 4db173f22b9130426b6a5064fea1b01bdc8a375d Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 16 Sep 2019 08:07:37 -0600 Subject: Experiment: print test times for appveyor [travis skip] Signed-off-by: Mats Wichmann --- .appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 -- cgit v0.12 From 8fb4989b55af2afe3d3de328b59a90eebcef4e49 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 25 Sep 2019 12:53:51 -0600 Subject: Docs for InstallVersionedLib and --install-sandbox [ci skip] Adds --install-sandbox to manpage options and to section on Install builder. Adds mention of InstallVersionedLib to user guide. Fixes #3007 Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 12 +++++++ doc/scons.mod | 1 + doc/user/install.xml | 70 ++++++++++++++++++++++++++++++++++++--- src/engine/SCons/Tool/install.xml | 16 +++++++++ 4 files changed, 95 insertions(+), 4 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index eb9f00b..9af3f3e 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -1080,6 +1080,18 @@ This implies + + + --install-sandbox=path + + +When using the &Install; functions, prepend path +to the installation paths such that all installed files will be placed +underneath path. + + + + --interactive 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 @@ Import"> Install"> InstallAs"> +InstallVersionedLib"> Link"> ListOption"> ListVariable"> 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 @@ %scons; - + %builders-mod; @@ -11,7 +11,7 @@ %tools-mod; %variables-mod; - + ]> - 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"); } +
+ Installing a Shared Library + + + 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. + + + + For example, on a Linux system, this instruction: + + + +foo = env.SharedLibrary(target="foo", source="foo.c", SHLIBVERSION="1.2.3") + + + + Will produce a shared library + libfoo.so.1.2.3 + and symbolic links + libfoo.so and + libfoo.so.1 + which point to + libfoo.so.1.2.3. + 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: + + + +env.InstallVersionedLib(target="lib", source=foo) + + + + +
+
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. env.Install('/usr/local/bin', source = ['foo', 'bar']) + + +If the 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. + + + +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). + + -- cgit v0.12 From b907ebd61c3898061412207c2c314107caa3a59b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kul=C3=ADk?= Date: Fri, 27 Sep 2019 09:47:16 +0200 Subject: Fix bytes not being decoded in suncxx.py --- src/engine/SCons/Tool/suncxx.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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: -- cgit v0.12 From 2cc64514e0b17d9f678b5bddb8ffe00789abdba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kul=C3=ADk?= Date: Fri, 27 Sep 2019 09:58:05 +0200 Subject: Modify CHANGES.txt --- src/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 4078669..ac9239f 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -18,6 +18,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Turn previously deprecated debug options into failures: --debug=tree, --debug=dtree, --debug=stree, --debug=nomemoizer. + 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 -- cgit v0.12 From 24bb5363c588cca55826f4da37752a79943728a8 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 1 Oct 2019 07:18:31 -0600 Subject: Add doc for *EMITTER consvars [ci skip] Three *EMITTER construction variables had documentation of "TODO". A fourth, LDMODULEEMITTER, was not mentioned at all. Signed-off-by: Mats Wichmann --- src/engine/SCons/Tool/__init__.xml | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) 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.
@@ -476,7 +476,10 @@ determine the version of versioned import library. -TODO +Contains the emitter specification for the +&b-link-StaticLibrary; builder. +The manpage section "Builder Objects" contains +general information on specifying emitters. @@ -494,10 +497,24 @@ format as &cv-link-SHLIBVERSION;. + + + +Contains the emitter specification for the +&b-link-LoadableModule; builder. +The manpage section "Builder Objects" contains +general information on specifying emitters. + + + + -TODO +Contains the emitter specification for the +&b-link-SharedLibrary; builder. +The manpage section "Builder Objects" contains +general information on specifying emitters. @@ -505,7 +522,10 @@ TODO -TODO +Contains the emitter specification for the +&b-link-Program; builder. +The manpage section "Builder Objects" contains +general information on specifying emitters. @@ -514,7 +534,7 @@ TODO 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, -- cgit v0.12 From 7488962c7f55a2029acb1aedeb5c50e9c1b8d199 Mon Sep 17 00:00:00 2001 From: Theogen Ratkin Date: Wed, 2 Oct 2019 15:18:31 -0400 Subject: Fix a syntax error in the documentation Quotation marks do not match, which is a syntax error. --- doc/user/output.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 env = Environment() -if ARGUMENTS.get('VERBOSE') != "1': +if ARGUMENTS.get('VERBOSE') != '1': env['CCCOMSTR'] = "Compiling $TARGET" env['LINKCOMSTR'] = "Linking $TARGET" env.Program('foo.c') -- cgit v0.12 From 16a9225e26489ab611af03f022eafe6d264bfcc4 Mon Sep 17 00:00:00 2001 From: jw0k Date: Fri, 4 Oct 2019 17:14:47 +0200 Subject: fix CheckFunc detection code for MSVC --- src/engine/SCons/Conftest.py | 4 ++++ 1 file changed, 4 insertions(+) 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 %(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 -- cgit v0.12 From 68b8d043051761e72b304073aeac002abc1ad732 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 5 Oct 2019 09:14:32 -0600 Subject: fix typo: missing quote in a manpage example [ci skip] Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 9af3f3e..9065f25 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -4572,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 -- cgit v0.12 From 5f22daa0bd88e39071860b54678f8c516badf1f1 Mon Sep 17 00:00:00 2001 From: Jacek Kuczera Date: Sun, 6 Oct 2019 21:57:32 +0200 Subject: test whether CheckFunc properly detects memmove --- test/Configure/config-h.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) 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 -- cgit v0.12 From 671aed7eb090d1501a4097b34909db7ec336e68e Mon Sep 17 00:00:00 2001 From: Jacek Kuczera Date: Sun, 6 Oct 2019 22:11:54 +0200 Subject: describe CheckFunc fix --- src/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 4078669..96c8643 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -18,6 +18,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - 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. RELEASE 3.1.1 - Mon, 07 Aug 2019 20:09:12 -0500 -- cgit v0.12