diff options
author | Adam Gross <grossag@gmail.com> | 2019-10-22 14:50:02 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-22 14:50:02 (GMT) |
commit | 49403a2d8484f9d464ac194a625a5feae3e9430b (patch) | |
tree | 85692e27346aa4da5f9cb82f3df54dc8ebe3de8a | |
parent | 2acdea49024d1be045c841f314a31fd67b1b20a0 (diff) | |
parent | c6ca3bdd2ad8e9a6ceea398934d84def9ba7c497 (diff) | |
download | SCons-49403a2d8484f9d464ac194a625a5feae3e9430b.zip SCons-49403a2d8484f9d464ac194a625a5feae3e9430b.tar.gz SCons-49403a2d8484f9d464ac194a625a5feae3e9430b.tar.bz2 |
Merge pull request #2 from SCons/master
Fast forward master
161 files changed, 2907 insertions, 4485 deletions
diff --git a/.appveyor.yml b/.appveyor.yml index d2c63cb..09cd996 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,10 +1,11 @@ #version: '3.0.1.{build}' image: - # linux builds disabled for now + # linux builds done in Travis CI for now # - Ubuntu - Visual Studio 2015 - Visual Studio 2017 + - Visual Studio 2019 cache: - downloads -> appveyor.yml @@ -24,6 +25,7 @@ install: - cmd: set STATIC_DEPS=true & C:\\%WINPYTHON%\\python.exe -m pip install -U --progress-bar off lxml # install 3rd party tools to test with - cmd: choco install --allow-empty-checksums dmd ldc swig vswhere xsltproc winflexbison + - cmd: set SCONS_CACHE_MSVC_CONFIG=true - cmd: set ### LINUX ### @@ -36,58 +38,37 @@ install: - sh: which python$PYTHON - sh: python$PYTHON --version - sh: export PYSITEDIR=$(python$PYTHON -m site --user-site) - - sh: python$PYTHON -m pip install --user -U --progress-bar off pip setuptools wheel + - sh: python$PYTHON -m pip install --user -U --progress-bar off pip setuptools wheel - sh: python$PYTHON -m pip install --user -U --progress-bar off coverage codecov - sh: STATIC_DEPS=true python$PYTHON -m pip install --user -U --progress-bar off lxml - sh: ./.travis/install.sh - sh: printenv -# build matrix will be number of images multiplied -# by each '-' below, split jobs into groups of 4 -# to avoid timeing out +# build matrix will be number of images multiplied by each '-' below, +# less any exclusions. +# split builds into sets of four jobs due to appveyor per-job time limit environment: matrix: - WINPYTHON: "Python27" PYTHON: "2.7" PYVER: 27 BUILD_JOB_NUM: 1 - COVERAGE: 1 + COVERAGE: 0 - WINPYTHON: "Python27" PYTHON: "2.7" PYVER: 27 BUILD_JOB_NUM: 2 - COVERAGE: 1 + COVERAGE: 0 - WINPYTHON: "Python27" PYTHON: "2.7" PYVER: 27 BUILD_JOB_NUM: 3 - COVERAGE: 1 + COVERAGE: 0 - WINPYTHON: "Python27" PYTHON: "2.7" PYVER: 27 BUILD_JOB_NUM: 4 - COVERAGE: 1 - - - WINPYTHON: "Python36" - PYTHON: "3.6" - PYVER: 36 - BUILD_JOB_NUM: 1 - COVERAGE: 1 - - WINPYTHON: "Python36" - PYTHON: "3.6" - PYVER: 36 - BUILD_JOB_NUM: 2 - COVERAGE: 1 - - WINPYTHON: "Python36" - PYTHON: "3.6" - PYVER: 36 - BUILD_JOB_NUM: 3 - COVERAGE: 1 - - WINPYTHON: "Python36" - PYTHON: "3.6" - PYVER: 36 - BUILD_JOB_NUM: 4 - COVERAGE: 1 + COVERAGE: 0 - WINPYTHON: "Python35" PYTHON: "3.5" @@ -110,6 +91,27 @@ environment: BUILD_JOB_NUM: 4 COVERAGE: 0 + - WINPYTHON: "Python36" + PYTHON: "3.6" + PYVER: 36 + BUILD_JOB_NUM: 1 + COVERAGE: 1 + - WINPYTHON: "Python36" + PYTHON: "3.6" + PYVER: 36 + BUILD_JOB_NUM: 2 + COVERAGE: 1 + - WINPYTHON: "Python36" + PYTHON: "3.6" + PYVER: 36 + BUILD_JOB_NUM: 3 + COVERAGE: 1 + - WINPYTHON: "Python36" + PYTHON: "3.6" + PYVER: 36 + BUILD_JOB_NUM: 4 + COVERAGE: 1 + - WINPYTHON: "Python37" PYTHON: "3.7" PYVER: 37 @@ -133,40 +135,49 @@ environment: # remove sets of build jobs based on critia below # to fine tune the number and platforms tested -matrix: - exclude: - # test python 3.5, 3.6 on Visual Studio 2015 image - - image: Visual Studio 2015 - WINPYTHON: "Python37" - - image: Visual Studio 2015 +matrix: + exclude: + # test python 3.5 on Visual Studio 2015 image + - image: Visual Studio 2015 WINPYTHON: "Python27" + - image: Visual Studio 2015 + WINPYTHON: "Python36" + - image: Visual Studio 2015 + WINPYTHON: "Python37" - # test python 2.7, 3.7 on Visual Studio 2015 image + # test python 2.7, 3.6 on Visual Studio 2017 image - image: Visual Studio 2017 WINPYTHON: "Python35" - - image: Visual Studio 2017 + - image: Visual Studio 2017 + WINPYTHON: "Python37" + + # test python 3.7 on Visual Studio 2019 image + - image: Visual Studio 2019 + WINPYTHON: "Python27" + - image: Visual Studio 2019 + WINPYTHON: "Python35" + - image: Visual Studio 2019 WINPYTHON: "Python36" # test python 3.7 on Ubuntu - - image: Ubuntu - WINPYTHON: "Python27" - - image: Ubuntu + - image: Ubuntu + WINPYTHON: "Python27" + - image: Ubuntu WINPYTHON: "Python35" - - image: Ubuntu + - image: Ubuntu WINPYTHON: "Python36" # remove some binaries we dont to be found before_build: - ps: | - if ($isWindows) - { + if ($isWindows) { dir "C:\Program Files\Git\usr\bin\x*.exe" if (Test-Path "C:\Program Files\Git\usr\bin\xsltproc.EXE" ) { Remove-Item "C:\Program Files\Git\usr\bin\xsltproc.EXE" -ErrorAction Ignore } dir "C:\Program Files\Git\usr\bin\x*.exe" } - + build: off build_script: @@ -174,18 +185,17 @@ build_script: - cmd: "C:\\%WINPYTHON%\\python.exe runtest.py -l -a > all_tests.txt" - sh: python$PYTHON runtest.py -l -a > all_tests.txt - # setup coverage by creating the coverage config file, and adding coverage + # setup coverage by creating the coverage config file, and adding coverage # to the usercustomize so that all python processes start with coverage - ps: | - if ($env:COVERAGE -eq 1){ + if ($env:COVERAGE -eq 1) { $env:COVERAGE_PROCESS_START = "$($env:APPVEYOR_BUILD_FOLDER)/.coveragerc"; $env:PYTHONNOUSERSITE = ""; New-Item -ItemType Directory -Force -Path "$($env:PYSITEDIR)"; $env:COVERAGE_FILE = "$($env:APPVEYOR_BUILD_FOLDER)/.coverage"; $usercustomizeText = "import os`r`nos.environ['COVERAGE_PROCESS_START'] = '$($env:COVERAGE_PROCESS_START)'`r`nimport coverage`r`ncoverage.process_startup()"; $usercustomizeText|Set-Content "$($env:PYSITEDIR)/usercustomize.py"; - if ($isWindows) - { + if ($isWindows) { $coveragercFile = "[run]`r`nsource = $($env:APPVEYOR_BUILD_FOLDER)/src`r`nparallel = True`r`ndisable_warnings = trace-changed`r`nomit =`r`n`t*Tests.py`r`n`tsrc\test_*`r`n`tsrc\setup.py`r`n`r`n[path]`r`nsource = $($env:APPVEYOR_BUILD_FOLDER)`r`n[report]`r`nomit =`r`n`t*Tests.py`r`n`tsrc\test_*`r`n`tsrc\setup.py`r`n`r`n" } else @@ -205,35 +215,34 @@ build_script: if ( $start -eq 0 ){ $start = 1 }; get-content all_tests.txt | select -first ($end - $start) -skip ($start - 1) | Out-File -Encoding ASCII build_tests.txt; - # exclude VS 10.0 because it hangs the testing until this is resolved: + # exclude VS 10.0 because it hangs the testing until this is resolved: # https://help.appveyor.com/discussions/problems/19283-visual-studio-2010-trial-license-has-expired - ps: | New-Item -Name exclude_list.txt -ItemType File $workaround_image = "Visual Studio 2015" - if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq $workaround_image){ + if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq $workaround_image) { Add-Content -Path 'exclude_list.txt' -Value 'test\MSVS\vs-10.0-exec.py' } # 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 - sh: | unset JAVA_TOOL_OPTIONS - if [ "$COVERAGE" -eq "1" ]; then - coverage run -p --rcfile="$COVERAGE_PROCESS_START" runtest.py --exclude-list exclude_list.txt -f build_tests.txt || if [[ $? == 2 ]]; then true; else false; fi; + if [ "$COVERAGE" -eq "1" ]; then + coverage run -p --rcfile="$COVERAGE_PROCESS_START" runtest.py --exclude-list exclude_list.txt -f build_tests.txt || if [[ $? == 2 ]]; then true; else false; fi; else - python$PYTHON runtest.py -j 2 --exclude-list exclude_list.txt -f build_tests.txt || if [[ $? == 2 ]]; then true; else false; fi; + python$PYTHON runtest.py -j 2 --exclude-list exclude_list.txt -f build_tests.txt || if [[ $? == 2 ]]; then true; else false; fi; fi # run converage even if there was a test failure on_finish: - ps: | - if ($env:COVERAGE -eq 1) - { + if ($env:COVERAGE -eq 1) { & coverage combine & coverage report & coverage xml -o coverage_xml.xml @@ -244,5 +253,5 @@ on_finish: - sh: if [ $COVERAGE -eq 1 ]; then codecov -X gcov --file coverage_xml.xml; fi # not using coveralls, so leaving it commented out in case we switch back #- cmd: "C:\\%WINPYTHON%\\python.exe -m pip install --user -U coveralls" - #- sh: python$PYTHON -m pip install --user -U coveralls + #- sh: python$PYTHON -m pip install --user -U coveralls #- ps: coveralls --rcfile="$($env:COVERAGE_PROCESS_START)" diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/bug_report.md index eeeb6bc..e249a70 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,8 +1,20 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + ## Please bring your issue to the SCons users mailing list before filing an issue here ## See: https://scons.org/bugs.html -## If the issue is confirmed to be a bug please include the following information +**Describe the bug** +A clear and concise description of what the bug is. + +**Required information** * Link to SCons Users thread discussing your issue. * Version of SCons * Version of Python diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..14f8e7e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,30 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +## Please bring your feature request to the SCons users mailing list before filing an issue here +## See: https://scons.org/bugs.html + + +**Describe the Feature** +A clear and concise description of what the feature request is. + +**Required information** +* Link to SCons Users thread discussing your issue. +* Version of SCons +* Version of Python +* Which python distribution if applicable (python.org, cygwin, anaconda, macports, brew,etc) +* How you installed SCons +* What Platform are you on? (Linux/Windows and which version) +* How to reproduce your issue? Please include a small self contained reproducer. Likely a SConstruct should do for most issues. +* How you invoke scons (The command line you're using "scons --flags some_arguments") + + + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.hgignore b/.hgignore deleted file mode 100644 index 2323687..0000000 --- a/.hgignore +++ /dev/null @@ -1,22 +0,0 @@ -build -bootstrap -.idea - -syntax:glob -*.py[co] -.sconsign* -.svn -.git -*~ -*.xcodeproj -*.orig -*.DS_Store -*\# -*.swp - -doc/user/scons-user -doc/user/scons_db.xml -doc/user/scons_ex.xml -doc/user/scons_exi.xml -doc/user/scons_xi.xml -doc/user/index.html diff --git a/.svnt/conf b/.svnt/conf deleted file mode 100644 index d4ffcb7..0000000 --- a/.svnt/conf +++ /dev/null @@ -1,24 +0,0 @@ -import os -import sys - -python = os.environ.get('PYTHON', sys.executable) - -build = [ - '"%(python)s" bootstrap.py %%s' % locals() -] - -build_test_baseline = [] - -cmd = '"%(python)s" runtest.py -q --noqmtest %%s' % locals() - -test_inputs = [ - 'src/*.py', - 'QMTest/*.py', -] - -tests = ( - ('src/*Tests.py', cmd), - ('test/*.py', cmd), -) - -valid_regression_results = [0, 2] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..2b781b2 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,13 @@ +# Contributing to SCons + +First off, thanks for taking the time to contribute! + +Here are some pointers to get started, before more information gets moved here to this page. + + * [Bugs and Feature Requests](https://scons.org/bugs.html) + * [Development](https://scons.org/dev.html) + * [SCons Developer's Guidelines](https://scons.org/guidelines.html) + +Various resources to contact are here: + + * [Contacts](https://scons.org/contact.html) @@ -1,4 +1,6 @@ -__COPYRIGHT__ +MIT License + +Copyright (c) 2001 - 2019 The SCons Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/LICENSE-local b/LICENSE-local index dde3640..c3fe717 100644 --- a/LICENSE-local +++ b/LICENSE-local @@ -3,6 +3,8 @@ This copyright and license do not apply to any other software with which this software may have been included. +MIT License + __COPYRIGHT__ Permission is hereby granted, free of charge, to any person obtaining @@ -499,13 +499,13 @@ about `Executing SCons Without Installing`_):: Depending on the utilities installed on your system, any or all of the following packages will be built:: - build/dist/scons-3.1.0.tar.gz - build/dist/scons-3.1.0.zip - build/dist/scons-doc-3.1.0.tar.gz - build/dist/scons-local-3.1.0.tar.gz - build/dist/scons-local-3.1.0.zip - build/dist/scons-src-3.1.0.tar.gz - build/dist/scons-src-3.1.0.zip + build/dist/scons-3.1.1.tar.gz + build/dist/scons-3.1.1.zip + build/dist/scons-doc-3.1.1.tar.gz + build/dist/scons-local-3.1.1.tar.gz + build/dist/scons-local-3.1.1.zip + build/dist/scons-src-3.1.1.tar.gz + build/dist/scons-src-3.1.1.zip The SConstruct file is supposed to be smart enough to avoid trying to build packages for which you don't have the proper utilities installed. For diff --git a/ReleaseConfig b/ReleaseConfig index b553411..69be328 100755 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -32,7 +32,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (3, 1, 0) +version_tuple = (3, 1, 2, 'alpha', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version @@ -8,7 +8,7 @@ from __future__ import print_function copyright_years = '2001 - 2019' # This gets inserted into the man pages to reflect the month of release. -month_year = 'July 2019' +month_year = 'August 2019' # # __COPYRIGHT__ @@ -49,7 +49,7 @@ import textwrap import bootstrap project = 'scons' -default_version = '3.1.0' +default_version = '3.1.1' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years SConsignFile() diff --git a/bench/bench.py b/bench/bench.py index 3f7dbc6..aad0fb4 100644 --- a/bench/bench.py +++ b/bench/bench.py @@ -56,12 +56,26 @@ Runs = 10 FunctionPrefix = 'Func' -# The function used to get the current time. The default of time.time is -# good on most UNIX systems, but time.clock (selectable via the --clock -# option) is better on Windows and some other UNIX systems. - -Now = time.time +# Comment from Python2 timeit module: +# The difference in default timer function is because on Windows, +# clock() has microsecond granularity but time()'s granularity is 1/60th +# of a second; on Unix, clock() has 1/100th of a second granularity and +# time() is much more precise. On either platform, the default timer +# functions measure wall clock time, not the CPU time. This means that +# other processes running on the same computer may interfere with the +# timing. The best thing to do when accurate timing is necessary is to +# repeat the timing a few times and use the best time. The -i option is +# good for this. +# On Python3, a new time.perf_counter function picks the best available +# timer, so we use that if we can, else fall back as per above. +try: + Now = time.perf_counter +except AttributeError: + if sys.platform == 'win32': + Now = time.clock + else: + Now = time.time opts, args = getopt.getopt(sys.argv[1:], 'hi:r:', ['clock', 'func=', 'help', @@ -69,7 +83,11 @@ opts, args = getopt.getopt(sys.argv[1:], 'hi:r:', for o, a in opts: if o in ['--clock']: - Now = time.clock + try: + Now = time.clock + except AttributeError: + sys.stderr.write("time.clock unavailable on this Python\n") + sys.exit(1) elif o in ['--func']: FunctionPrefix = a elif o in ['-h', '--help']: @@ -87,15 +105,15 @@ if len(args) != 1: sys.stderr.write(Usage) sys.exit(1) - -exec(open(args[0], 'r').read()) - +with open(args[0], 'r') as f: + exec(f.read()) try: FunctionList except NameError: function_names = sorted([x for x in list(locals().keys()) if x[:4] == FunctionPrefix]) - l = [locals()[f] for f in function_names] + lvars = locals() + l = [lvars[f] for f in function_names] FunctionList = [f for f in l if isinstance(f, types.FunctionType)] IterationList = [None] * Iterations diff --git a/bench/env.__setitem__.py b/bench/env.__setitem__.py index 510dcc7..ed0888e 100644 --- a/bench/env.__setitem__.py +++ b/bench/env.__setitem__.py @@ -289,7 +289,7 @@ else: # that the timer will use to get at these classes. class_names = [] -for n in locals().keys(): +for n in list(locals().keys()): #if n.startswith('env_'): if n[:4] == 'env_': class_names.append(n) diff --git a/bench/timeit.py b/bench/timeit.py deleted file mode 100644 index 7db0dd4..0000000 --- a/bench/timeit.py +++ /dev/null @@ -1,298 +0,0 @@ -#! /usr/bin/env python - -"""Tool for measuring execution time of small code snippets. - -This module avoids a number of common traps for measuring execution -times. See also Tim Peters' introduction to the Algorithms chapter in -the Python Cookbook, published by O'Reilly. - -Library usage: see the Timer class. - -Command line usage: - python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-h] [statement] - -Options: - -n/--number N: how many times to execute 'statement' (default: see below) - -r/--repeat N: how many times to repeat the timer (default 3) - -s/--setup S: statement to be executed once initially (default 'pass') - -t/--time: use time.time() (default on Unix) - -c/--clock: use time.clock() (default on Windows) - -v/--verbose: print raw timing results; repeat for more digits precision - -h/--help: print this usage message and exit - statement: statement to be timed (default 'pass') - -A multi-line statement may be given by specifying each line as a -separate argument; indented lines are possible by enclosing an -argument in quotes and using leading spaces. Multiple -s options are -treated similarly. - -If -n is not given, a suitable number of loops is calculated by trying -successive powers of 10 until the total time is at least 0.2 seconds. - -The difference in default timer function is because on Windows, -clock() has microsecond granularity but time()'s granularity is 1/60th -of a second; on Unix, clock() has 1/100th of a second granularity and -time() is much more precise. On either platform, the default timer -functions measure wall clock time, not the CPU time. This means that -other processes running on the same computer may interfere with the -timing. The best thing to do when accurate timing is necessary is to -repeat the timing a few times and use the best time. The -r option is -good for this; the default of 3 repetitions is probably enough in most -cases. On Unix, you can use clock() to measure CPU time. - -Note: there is a certain baseline overhead associated with executing a -pass statement. The code here doesn't try to hide it, but you should -be aware of it. The baseline overhead can be measured by invoking the -program without arguments. The baseline overhead differs between -Python versions! -""" -from __future__ import division, print_function - -try: - import gc -except ImportError: - class _fake_gc(object): - def isenabled(self): - return None - def enable(self): - pass - def disable(self): - pass - gc = _fake_gc() -import sys -import time -try: - import itertools -except ImportError: - # Must be an older Python version (see timeit() below) - itertools = None - -__all__ = ["Timer"] - -dummy_src_name = "<timeit-src>" -default_number = 1000000 -default_repeat = 3 - -if sys.platform == "win32": - # On Windows, the best timer is time.clock() - default_timer = time.clock -else: - # On most other platforms the best timer is time.time() - default_timer = time.time - -# Don't change the indentation of the template; the reindent() calls -# in Timer.__init__() depend on setup being indented 4 spaces and stmt -# being indented 8 spaces. -template = """ -def inner(_it, _timer): - %(setup)s - _t0 = _timer() - for _i in _it: - %(stmt)s - _t1 = _timer() - return _t1 - _t0 -""" - -def reindent(src, indent): - """Helper to reindent a multi-line statement.""" - return src.replace("\n", "\n" + " "*indent) - -class Timer(object): - """Class for timing execution speed of small code snippets. - - The constructor takes a statement to be timed, an additional - statement used for setup, and a timer function. Both statements - default to 'pass'; the timer function is platform-dependent (see - module doc string). - - To measure the execution time of the first statement, use the - timeit() method. The repeat() method is a convenience to call - timeit() multiple times and return a list of results. - - The statements may contain newlines, as long as they don't contain - multi-line string literals. - """ - - def __init__(self, stmt="pass", setup="pass", timer=default_timer): - """Constructor. See class doc string.""" - self.timer = timer - stmt = reindent(stmt, 8) - setup = reindent(setup, 4) - src = template % {'stmt': stmt, 'setup': setup} - self.src = src # Save for traceback display - code = compile(src, dummy_src_name, "exec") - ns = {} - exec(code, globals(), ns) - self.inner = ns["inner"] - - def print_exc(self, file=None): - """Helper to print a traceback from the timed code. - - Typical use: - - t = Timer(...) # outside the try/except - try: - t.timeit(...) # or t.repeat(...) - except: - t.print_exc() - - The advantage over the standard traceback is that source lines - in the compiled template will be displayed. - - The optional file argument directs where the traceback is - sent; it defaults to sys.stderr. - """ - import linecache, traceback - linecache.cache[dummy_src_name] = (len(self.src), - None, - self.src.split("\n"), - dummy_src_name) - traceback.print_exc(file=file) - - def timeit(self, number=default_number): - """Time 'number' executions of the main statement. - - To be precise, this executes the setup statement once, and - then returns the time it takes to execute the main statement - a number of times, as a float measured in seconds. The - argument is the number of times through the loop, defaulting - to one million. The main statement, the setup statement and - the timer function to be used are passed to the constructor. - """ - if itertools: - it = itertools.repeat(None, number) - else: - it = [None] * number - gcold = gc.isenabled() - gc.disable() - timing = self.inner(it, self.timer) - if gcold: - gc.enable() - return timing - - def repeat(self, repeat=default_repeat, number=default_number): - """Call timeit() a few times. - - This is a convenience function that calls the timeit() - repeatedly, returning a list of results. The first argument - specifies how many times to call timeit(), defaulting to 3; - the second argument specifies the timer argument, defaulting - to one million. - - Note: it's tempting to calculate mean and standard deviation - from the result vector and report these. However, this is not - very useful. In a typical case, the lowest value gives a - lower bound for how fast your machine can run the given code - snippet; higher values in the result vector are typically not - caused by variability in Python's speed, but by other - processes interfering with your timing accuracy. So the min() - of the result is probably the only number you should be - interested in. After that, you should look at the entire - vector and apply common sense rather than statistics. - """ - r = [] - for i in range(repeat): - t = self.timeit(number) - r.append(t) - return r - -def main(args=None): - """Main program, used when run as a script. - - The optional argument specifies the command line to be parsed, - defaulting to sys.argv[1:]. - - The return value is an exit code to be passed to sys.exit(); it - may be None to indicate success. - - When an exception happens during timing, a traceback is printed to - stderr and the return value is 1. Exceptions at other times - (including the template compilation) are not caught. - """ - if args is None: - args = sys.argv[1:] - import getopt - try: - opts, args = getopt.getopt(args, "n:s:r:tcvh", - ["number=", "setup=", "repeat=", - "time", "clock", "verbose", "help"]) - except getopt.error as err: - print(err) - print("use -h/--help for command line help") - return 2 - timer = default_timer - stmt = "\n".join(args) or "pass" - number = 0 # auto-determine - setup = [] - repeat = default_repeat - verbose = 0 - precision = 3 - for o, a in opts: - if o in ("-n", "--number"): - number = int(a) - if o in ("-s", "--setup"): - setup.append(a) - if o in ("-r", "--repeat"): - repeat = int(a) - if repeat <= 0: - repeat = 1 - if o in ("-t", "--time"): - timer = time.time - if o in ("-c", "--clock"): - timer = time.clock - if o in ("-v", "--verbose"): - if verbose: - precision = precision + 1 - verbose = precision + 1 - if o in ("-h", "--help"): - print(__doc__) - return 0 - setup = "\n".join(setup) or "pass" - # Include the current directory, so that local imports work (sys.path - # contains the directory of this script, rather than the current - # directory) - import os - sys.path.insert(0, os.curdir) - t = Timer(stmt, setup, timer) - if number == 0: - # determine number so that 0.2 <= total time < 2.0 - for i in range(1, 10): - number = 10**i - try: - x = t.timeit(number) - except: - t.print_exc() - return 1 - if verbose: - print("%d loops -> %.*g secs" % (number, precision, x)) - if x >= 0.2: - break - try: - r = t.repeat(repeat, number) - except: - t.print_exc() - return 1 - best = min(r) - if verbose: - print("raw times:", ' '.join(["%.*g" % (precision, x) for x in r])) - print("%d loops," % number, end=' ') - usec = best * 1e6 / number - if usec < 1000: - print("best of %d: %.*g usec per loop" % (repeat, precision, usec)) - else: - msec = usec / 1000 - if msec < 1000: - print("best of %d: %.*g msec per loop" % (repeat, precision, msec)) - else: - sec = msec / 1000 - print("best of %d: %.*g sec per loop" % (repeat, precision, sec)) - return None - -if __name__ == "__main__": - sys.exit(main()) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/bin/SConsExamples.py b/bin/SConsExamples.py index 7491c58..501169e 100644 --- a/bin/SConsExamples.py +++ b/bin/SConsExamples.py @@ -882,7 +882,7 @@ def create_scons_output(e): lines = ExecuteCommand(args, command, t, {'osname':o.os, 'tools':o.tools}) if not command.output and lines: ncontent = '\n'.join(lines) - ncontent = address_re.sub(r' at 0x700000>', ncontent) + ncontent = address_re.sub(r' at 0x700000>', ncontent) ncontent = engine_re.sub(r' File "bootstrap/src/engine/SCons/', ncontent) ncontent = file_re.sub(r'\1 <module>', ncontent) ncontent = nodelist_re.sub(r"\1 'NodeList' object \2", ncontent) 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/bin/rsync-sourceforge b/bin/rsync-sourceforge deleted file mode 100644 index de44e3b..0000000 --- a/bin/rsync-sourceforge +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -# -# Sync this directory tree with sourceforge. -# -# Cribbed and modified from Peter Miller's same-named script in -# /home/groups/a/ae/aegis/aegis at SourceForge. -# -# Guide to what this does with rsync: -# -# --rsh=ssh use ssh for the transfer -# -l copy symlinks as symlinks -# -p preserve permissions -# -r recursive -# -t preserve times -# -z compress data -# --stats file transfer statistics -# --exclude exclude files matching the pattern -# --delete delete files that don't exist locally -# --delete-excluded delete files that match the --exclude patterns -# --progress show progress during the transfer -# -v verbose -# -LOCAL=/home/scons/scons -REMOTE=/home/groups/s/sc/scons/scons -/usr/bin/rsync --rsh=ssh -l -p -r -t -z --stats \ - --exclude build \ - --exclude "*,D" \ - --exclude "*.pyc" \ - --exclude aegis.log \ - --delete --delete-excluded \ - --progress -v \ - ${LOCAL}/. scons.sourceforge.net:${REMOTE}/. diff --git a/bin/scons-review.sh b/bin/scons-review.sh deleted file mode 100755 index f126333..0000000 --- a/bin/scons-review.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -case "$1" in -'') exec svn diff --diff-cmd diff -x -c $* ;; --m) svn diff --diff-cmd diff -x -c $* | alpine scons-dev ;; -*) echo "Error: unknown option '$1"; exit 1 ;; -esac - -# OLD CODE FOR USE WITH AEGIS -# -#if test $# -ne 1; then -# echo "Usage: scons-review change#" >&2 -# exit 1 -#fi -#if test "X$AEGIS_PROJECT" = "X"; then -# echo "scons-review: AEGIS_PROJECT is not set" >&2 -# exit 1 -#fi -#DIR=`aegis -cd -dd $*` -#if test "X${DIR}" = "X"; then -# echo "scons-review: No Aegis directory for '$*'" >&2 -# exit 1 -#fi -#(cd ${DIR} && find * -name '*,D' | sort | xargs cat) | pine scons-dev diff --git a/bin/sfsum b/bin/sfsum deleted file mode 100644 index 142793a..0000000 --- a/bin/sfsum +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python -# -# sfsum.py: A script for parsing XML data exported from -# SourceForge projects. -# -# Right now, this is hard-coded to generate a summary of open bugs. -# -# XML data for SourceForge project is available for download by project -# administrators. Because it's intended for backup purposes, you have -# to slurp the whole set of data, including info about all of the closed -# items, the feature requests, etc., so it can get big. -# -# You can do this by hand (if you're an administrator) with a URL like -# this (where 30337 is the group_id for SCons): -# -# http://sourceforge.net/export/xml_export.php?group_id=30337 -# -# They also have a Perl script, called xml_export, available as part -# of a set of utilities called "adocman" which automate dealing with -# SourceForge document management from the command line. "adocman" -# is available at: -# -# https://sourceforge.net/projects/sitedocs/ -# -from __future__ import print_function - -import xml.sax -import xml.sax.saxutils -import sys - -SFName = { - 'Unassigned' : 'nobody', - 'Chad Austin' : 'aegis', - 'Charle Crain' : 'diewarzau', - 'Steven Knight' : 'stevenknight', - 'Steve Leblanc' : 'stevenleblanc', - 'Jeff Petkau' : 'jpet', - 'Anthony Roach' : 'anthonyroach', - 'Steven Shaw' : 'steven_shaw', - 'Terrel Shumway' : 'terrelshumway', - 'Greg Spencer' : 'greg_spencer', - 'Christoph Wiedemann' : 'wiedeman', -} - -class Artifact(object): - """Just a place to hold attributes that we find in the XML.""" - pass - -Artifacts = {} - -def nws(text): - """Normalize white space. This will become important if/when - we enhance this to search for arbitrary fields.""" - return ' '.join(text.split()) - -class ClassifyArtifacts(xml.sax.saxutils.DefaultHandler): - """ - Simple SAX subclass to classify the artifacts in SourceForge - XML output. - - This reads up the fields in an XML description and turns the field - descriptions into attributes of an Artificat object, on the fly. - Artifacts are of the following types: - - Bugs - Feature Requests - Patches - Support Requests - - We could, if we choose to, add additional types in the future - by creating additional trackers. - - This class loses some info right now because we don't pay attention - to the <messages> tag in the output, which contains a list of items - that have <field> tags in them. Right now, these just overwrite - each other in the Arifact object we create. - - We also don't pay attention to any attributes of a <field> tag other - than the "name" attribute. We'll need to extend this class if we - ever want to pay attention to those attributes. - """ - def __init__(self): - self.artifact = None - - def startElement(self, name, attrs): - self.text = "" - if name == 'artifact': - self.artifact = Artifact() - elif not self.artifact is None and name == 'field': - self.fname = attrs.get('name', None) - - def characters(self, ch): - if not self.artifact is None: - self.text = self.text + ch - - def endElement(self, name): - global Artifacts - if name == 'artifact': - type = self.artifact.artifact_type - try: - list = Artifacts[type] - except KeyError: - Artifacts[type] = list = [] - list.append(self.artifact) - self.artifact = None - elif not self.artifact is None and name == 'field': - setattr(self.artifact, self.fname, self.text) - -if __name__ == '__main__': - # Create a parser. - parser = xml.sax.make_parser() - # Tell the parser we are not interested in XML namespaces. - parser.setFeature(xml.sax.handler.feature_namespaces, 0) - - # Instantiate our handler and tell the parser to use it. - parser.setContentHandler(ClassifyArtifacts()) - - # Parse the input. - parser.parse(sys.argv[1]) - - # Hard-coded search for 'Open' bugs. This should be easily - # generalized once we figure out other things for this script to do. - bugs = [x for x in Artifacts['Bugs'] if x.status == 'Open'] - - print(list(Artifacts.keys())) - - print("%d open bugs" % len(bugs)) - - # Sort them into a separate list for each assignee. - Assigned = {} - for bug in bugs: - a = bug.assigned_to - try: - list = Assigned[a] - except KeyError: - Assigned[a] = list = [] - list.append(bug) - - for a in SFName.keys(): - try: - b = Assigned[SFName[a]] - except KeyError: - pass - else: - print(" %s" % a) - b.sort(key=lambda x, y: (x.artifact_id, y.artifact_id)) - for bug in b: - print(" %-6s %s" % (bug.artifact_id, bug.summary)) diff --git a/bin/timebuild b/bin/timebuild deleted file mode 100644 index d5af983..0000000 --- a/bin/timebuild +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/sh -# -# Profile running SCons to build itself from the current package. -# -# This runs "aegis -build" to build a current scons-src-*.tar.gz -# package, unpacks it in the supplied directory name, and then -# starts a profiled run of an SCons build, followed by another. -# This results in two profiles: -# -# NAME/NAME-0.prof -# profile of a build-everything run -# -# NAME/NAME-1.prof -# profile of an all-up-to-date run -# -# This also copies the build scons-src-*.tar.gz file to the NAME -# subdirectory, and tars up everything under src/ as NAME/src.tar.gz, -# so that repeated runs with different in-progress changes can serve -# as their own crude version control, so you don't lose that exact -# combination of features which performed best. - -if test X$1 = X; then - echo "Must supply name!" >&2 - exit 1 -fi - -VERSION=0.90 - -DIR=$1 - -SRC="scons-src-$VERSION" -SRC_TAR_GZ="${SRC}.tar.gz" -B_D_SRC_TAR_GZ="build/dist/${SRC_TAR_GZ}" - -echo "Building ${B_D_SRC_TAR_GZ}: " `date` -aegis -build ${B_D_SRC_TAR_GZ} - -echo "mkdir ${DIR}: " `date` -mkdir ${DIR} - -echo "cp ${B_D_SRC_TAR_GZ} ${DIR}: " `date` -cp ${B_D_SRC_TAR_GZ} ${DIR} - -echo "tar cf ${DIR}/src.tar.gz: " `date` -tar cf ${DIR}/src.tar.gz src - -cd ${DIR} - -echo "tar zxf ${SRC_TAR_GZ}: " `date` -tar zxf ${SRC_TAR_GZ} - -cd ${SRC} - -SCRIPT="src/script/scons.py" -ARGS="version=$VERSION" - -export SCONS_LIB_DIR=`pwd`/src/engine - -echo "Build run starting: " `date` -python $SCRIPT --profile=../$DIR-0.prof $ARGS > ../$DIR-0.log 2>&1 - -echo "Up-to-date run starting: " `date` -python $SCRIPT --profile=../$DIR-1.prof $ARGS > ../$DIR-1.log 2>&1 - -echo "Finished $DIR at: " `date` @@ -1,299 +0,0 @@ -/* - * MANIFEST: use of SCons in project config file to build itself - * - * SCons has a Repository feature, introduced in SCons 0.09, that was - * designed to work well with Aegis. - */ - -/* - * The build_command field of the project config file is used to invoke - * the relevant build command. This command tells SCons where to find - * the rules. - * - * Our chicken-and-egg dilemma is this: we want to use the version of - * SCons under development in an Aegis change to build itself. But the - * pieces of SCons are likely only partly in this change, and partly in - * baselines. - * - * Python only imports things on a module-by-module basis--which is to - * say, once it finds __init__.py in a given directory, it assumes that - * all other files in that module are in the same directory. But that's - * not the way Aegis works, because if a file hasn't changed on the - * branch, it will only be in its parent's baseline directory. - * - * Aegis' mechanism for working around this sort of problem is to make - * symlinks to the proper baseline versions of each file, which makes - * it look like everything is in the local tree. That's unattractive, - * though, because we really want to eat our own dog food and use the - * SCons -Y options to pull things from the baseline repositories. - * - * So our solution (suggested by Anthony Roach) is a bootstrap.py script - * that does some Aegis-like searching through the baseline directories - * and makes a bootstrap copy of the version of SCons under development - * that we can use for building. After it makes this copy of SCons, it - * executes it with the same command-line arguments we supplied (and - * setting $SCONS_LIB_DIR to the right directory) so we can use it - * here with command-line options as if it were SCons itself. (Note, - * however, that bootstrap.py only understands the specific command-line - * options already in use here, so if you change the call below to add - * some other SCons options, you may have to modify bootstrap.py to - * recognize them. - * - * The ${Source bootstrap.py} substitution finds bootstrap.py wherever - * it may be in the Aegis baselines. - * - * The long -Y${SUBSTitute...} substitution takes the Aegis baseline - * search path and turns it into the right -Y command-line options for - * SCons. - * - * The rest of the substitutions (${DEVeloper}, etc.) should be obvious. - * - * Look in aesub(5) for more information about command substitutions. - */ -build_command = "python2.1 ${Source bootstrap.py} -Y${SUBSTitute : \\ -Y $Search_Path} date='${DAte %Y/%m/%d %H:%M:%S}' developer=${DEVeloper} version=${VERsion} change=${Change}"; - -/* - * SCons removes its targets before constructing them, which qualifies it - * for the following entry in the config file. The files must be removed - * first, otherwise the baseline would cease to be self-consistent. - */ - -link_integration_directory = true; - -/* - * This is set temporarily to allow us to build using the SCons - * currently checked in to the src directory. -create_symlinks_before_build = true; - */ - -/* - * aegis - project change supervisor - * This file is in the Public Domain, 1995, 1998 Peter Miller. - * - * MANIFEST: example of using rcs in the project config file - * - * The entries for the commands are listed below. RCS uses a slightly - * different model than aegis wants, so some maneuvering is required. - * The command strings in this section assume that the RCS commands ci and co - * and rcs and rlog are in the command search PATH, but you may like to - * hard-wire the paths, or set PATH at the start of each. You should also note - * that the strings are always handed to the Bourne shell to be executed, and - * are set to exit with an error immediately a sub-command fails. - * - * In these commands, the RCS file is kept unlocked, since only the owner will - * be checking changes in. The RCS functionality for coordinating shared - * access is not required. - * - * One advantage of using RCS version 5.6 or later is that binary files are - * supported, should you want to have binary files in the baseline. - * - * The ${quote ...} construct is used to quote filenames which contain - * shell special characters. A minimum of quoting is performed, so if - * the filenames do not contail shell special characters, no quotes will - * be used. - */ - -/* - * This command is used to create a new file history. - * This command is always executed as the project owner. - * The following substitutions are available: - * - * ${Input} - * absolute path of the source file - * ${History} - * absolute path of the history file - * - * The "ci -f" option is used to specify that a copy is to be checked-in even - * if there are no changes. - * The "ci -u" option is used to specify that an unlocked copy will remain in - * the baseline. - * The "ci -d" option is used to specify that the file time rather than the - * current time is to be used for the new revision. - * The "ci -M" option is used to specify that the mode date on the original - * file is not to be altered. - * The "ci -t" option is used to specify that there is to be no description - * text for the new RCS file. - * The "ci -m" option is used to specify that the change number is to be stored - * in the file log if this is actually an update (typically from aenf - * after aerm on the same file name). - * The "rcs -U" option is used to specify that the new RCS file is to have - * unstrict locking. - * The "rcs -kk" option is used to specify that keyword substitution is - * disabled (only keyword names, not values, are substituted). - */ -history_create_command = - "ci -f -u -d -M -m$c -t/dev/null ${quote $input} ${quote $history,v}; \ -rcs -kk -U ${quote $history,v}"; - - -/* - * This command is used to get a specific edit back from history. - * This command is always executed as the project owner. - * The following substitutions are available: - * - * ${History} - * absolute path of the history file - * ${Edit} - * edit number, as given by history_\%query_\%command - * ${Output} - * absolute path of the destination file - * - * The "co -r" option is used to specify the edit to be retrieved. - * The "co -p" option is used to specify that the results be printed on the - * standard output; this is because the destination filename will never - * look anything like the history source filename. - * The "rcs -kk" option is used to specify that keyword substitution is - * disabled (only keyword names, not values, are substituted). - */ -history_get_command = - "co -kk -r${quote $edit} -p ${quote $history,v} > ${quote $output}"; - -/* - * This command is used to add a new "top-most" entry to the history file. - * This command is always executed as the project owner. - * The following substitutions are available: - * - * ${Input} - * absolute path of source file - * ${History} - * absolute path of history file - * - * The "ci -f" option is used to specify that a copy is to be checked-in even - * if there are no changes. - * The "ci -u" option is used to specify that an unlocked copy will remain in - * the baseline. - * The "ci -d" option is used to specify that the file time rather than the - * current time is to be used for the new revision. - * The "ci -M" option is used to specify that the mode date on the original - * file is not to be altered. - * The "ci -m" option is used to specify that the change number is to be stored - * in the file log, which allows rlog to be used to find the change - * numbers to which each revision of the file corresponds. - * - * It is possible for a a very cautious approach has been taken, in which case - * the history_put_command may be set to the same string specified above for - * the history_create_command. - */ -history_put_command = - "ci -f -u -d -M -m$c ${quote $input} ${quote $history,v}"; - -/* - * This command is used to query what the history mechanism calls the top-most - * edit of a history file. The result may be any arbitrary string, it need not - * be anything like a number, just so long as it uniquely identifies the edit - * for use by the history_get_command at a later date. The edit number is to - * be printed on the standard output. This command is always executed as the - * project owner. - * - * The following substitutions are available: - * - * ${History} - * absolute path of the history file - */ -history_query_command = - "rlog -r ${quote $history,v} | awk '/^head:/ {print $$2}'"; - -/* - * RCS also provides a merge program, which can be used to provide a three-way - * merge. It has an ouput format some sites prefer to the fmerge output. - * - * This command is used by aed(1) to produce a difference listing when a file - * in the development directory is out of date compared to the current version - * in the baseline. - * - * All of the command substitutions described in aesub(5) are available. - * In addition, the following substitutions are also available: - * - * ${ORiginal} - * The absolute path name of a file containing the common ancestor - * version of ${MostRecent} and {$Input}. Usually the version originally - * copied into the change. Usually in a temporary file. - * ${Most_Recent} - * The absolute path name of a file containing the most recent version. - * Usually in the baseline. - * ${Input} - * The absolute path name of the edited version of the file. Usually in - * the development directory. - * ${Output} - * The absolute path name of the file in which to write the difference - * listing. Usually in the development directory. - * - * An exit status of 0 means successful, even of the files differ (and they - * usually do). An exit status which is non-zero means something is wrong. - * - * The "merge -L" options are used to specify labels for the baseline and the - * development directory, respecticvely, when conflict lines are inserted - * into the result. - * The "merge -p" options is used to specify that the results are to be printed - * on the standard output. - */ - -diff3_command = - "set +e; \ -merge -p -L baseline -L C$c ${quote $mostrecent} ${quote $original} \ -${quote $input} > ${quote $output}; \ -test $? -le 1"; - -/* - * The diff command in Red Hat 8.0 changed the exit status so it *fails* - * when *it* thinks it's trying to diff a binary (non-ASCII-text) file. - * The -a option disables this behavior and makes diff's exit status - * behave like it used to, even on any binary files we have checked in. - */ - -diff_command = - "set +e; \ - diff -a -c ${quote $original} ${quote $input} > ${quote $output}; \ - test $? -le 1"; - -/* - * We use a runtest.py script to execute tests. This takes care of - * massaging environment variables and the like to test against the - * unpacked package in the current directory. - * - * Note that we must include $spe in the batch_test_command line (so - * that Aegis thinks we're smart about testing ourselves against the - * baseline) but we don't actually need it. Our tests always run - * relative to the package built under the current directory, which - * is set appropriately during a baseline test. So we just use the - * proper aesub variable to comment out the expanded $spe. - */ -test_command = "python1.5 ${Source runtest.py Absolute} --noqmtest -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -q --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Name}"; - -batch_test_command = "python1.5 ${Source runtest.py Absolute} --noqmtest -p tar-gz -t -v ${SUBSTitute '\\.[CD][0-9]+$' '' ${VERsion}} -o ${Output} --aegis --sp ${Search_Path} --spe ${Search_Path_Executable} ${File_Names}"; - -new_test_filename = "test/CHANGETHIS.py"; - -/* - * - */ -file_template = -[ - { - pattern = [ "src/engine/*__init__.py" ]; - body = "${read_file ${source template/__init__.py abs}}"; - }, - { - pattern = [ "src/engine/*Tests.py" ]; - body = "${read_file ${source template/Tests.py abs}}"; - }, - { - pattern = [ "src/engine/*.py" ]; - body = "${read_file ${source template/file.py abs}}"; - }, - { - pattern = [ "test/*.py" ]; - body = "${read_file ${source template/test.py abs}}"; - }, -]; - -/* - * Command for distributing changes from Aegis to all of the repositories - * we want to mirror the information. - * - * XXX Uncomment after upgrading to an Aegis version that supports this. - -integrate_pass_notify_command = - "$sh ${s bin/scons-cdist} -p $project $change"; - * - */ diff --git a/doc/generated/builders.gen b/doc/generated/builders.gen index 7c62558..54c7aaa 100644 --- a/doc/generated/builders.gen +++ b/doc/generated/builders.gen @@ -1841,72 +1841,28 @@ env.Program(target = 'foo', source = ['foo.o', 'bar.c', 'baz.f']) <function>env.ProgramAllAtOnce()</function> </term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - Builds an executable from D sources without first creating individual - objects for each file. - </para> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - D sources can be compiled file-by-file as C and C++ source are, and - D is integrated into the <filename xmlns="http://www.scons.org/dbxsd/v1.0">scons</filename> Object and Program builders for - this model of build. D codes can though do whole source - meta-programming (some of the testing frameworks do this). For this - it is imperative that all sources are compiled and linked in a single call of - the D compiler. This builder serves that purpose. - </para> - <example_commands xmlns="http://www.scons.org/dbxsd/v1.0"> - env.ProgramAllAtOnce('executable', ['mod_a.d, mod_b.d', 'mod_c.d']) - </example_commands> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - This command will compile the modules mod_a, mod_b, and mod_c in a - single compilation process without first creating object files for - the modules. Some of the D compilers will create executable.o others - will not. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - Builds an executable from D sources without first creating individual - objects for each file. - </para> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - D sources can be compiled file-by-file as C and C++ source are, and - D is integrated into the <filename xmlns="http://www.scons.org/dbxsd/v1.0">scons</filename> Object and Program builders for - this model of build. D codes can though do whole source - meta-programming (some of the testing frameworks do this). For this - it is imperative that all sources are compiled and linked in a single call of - the D compiler. This builder serves that purpose. - </para> - <example_commands xmlns="http://www.scons.org/dbxsd/v1.0"> - env.ProgramAllAtOnce('executable', ['mod_a.d, mod_b.d', 'mod_c.d']) - </example_commands> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - This command will compile the modules mod_a, mod_b, and mod_c in a - single compilation process without first creating object files for - the modules. Some of the D compilers will create executable.o others - will not. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - Builds an executable from D sources without first creating individual - objects for each file. - </para> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - D sources can be compiled file-by-file as C and C++ source are, and - D is integrated into the <filename xmlns="http://www.scons.org/dbxsd/v1.0">scons</filename> Object and Program builders for - this model of build. D codes can though do whole source - meta-programming (some of the testing frameworks do this). For this - it is imperative that all sources are compiled and linked in a single call of - the D compiler. This builder serves that purpose. - </para> - <example_commands xmlns="http://www.scons.org/dbxsd/v1.0"> - env.ProgramAllAtOnce('executable', ['mod_a.d, mod_b.d', 'mod_c.d']) - </example_commands> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - This command will compile the modules mod_a, mod_b, and mod_c in a - single compilation process without first creating object files for - the modules. Some of the D compilers will create executable.o others - will not. - </para> - </listitem> + <para xmlns="http://www.scons.org/dbxsd/v1.0"> + Builds an executable from D sources without first creating individual + objects for each file. + </para> + <para xmlns="http://www.scons.org/dbxsd/v1.0"> + D sources can be compiled file-by-file as C and C++ source are, and + D is integrated into the <filename xmlns="http://www.scons.org/dbxsd/v1.0">scons</filename> Object and Program builders for + this model of build. D codes can though do whole source + meta-programming (some of the testing frameworks do this). For this + it is imperative that all sources are compiled and linked in a single + call to the D compiler. This builder serves that purpose. + </para> + <example_commands xmlns="http://www.scons.org/dbxsd/v1.0"> + env.ProgramAllAtOnce('executable', ['mod_a.d, mod_b.d', 'mod_c.d']) + </example_commands> + <para xmlns="http://www.scons.org/dbxsd/v1.0"> + This command will compile the modules mod_a, mod_b, and mod_c in a + single compilation process without first creating object files for + the modules. Some of the D compilers will create executable.o others + will not. + </para> +</listitem> </varlistentry> <varlistentry id="b-RES"> <term> diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 58ff6ae..c53e02a 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <screen xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">% <userinput>scons -Q</userinput> -cc -o f3.o -c f3.c -cc -o f2.o -c f2.c -cc -o f5.o -c f5.c cc -o f1.o -c f1.c +cc -o f5.o -c f5.c +cc -o f2.o -c f2.c +cc -o f3.o -c f3.c cc -o f4.o -c f4.c cc -o prog f1.o f2.o f3.o f4.o f5.o </screen> diff --git a/doc/generated/examples/troubleshoot_Dump_1.xml b/doc/generated/examples/troubleshoot_Dump_1.xml index 99d1399..1f6f250 100644 --- a/doc/generated/examples/troubleshoot_Dump_1.xml +++ b/doc/generated/examples/troubleshoot_Dump_1.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <screen xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">% <userinput>scons</userinput> scons: Reading SConscript files ... -{ 'BUILDERS': {'_InternalInstall': <function InstallBuilderWrapper at 0x700000&gt;, '_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000&gt;, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000&gt;}, +{ 'BUILDERS': {'_InternalInstall': <function InstallBuilderWrapper at 0x700000>, '_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000>, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000>}, 'CONFIGUREDIR': '#/.sconf_temp', 'CONFIGURELOG': '#/config.log', 'CPPSUFFIXES': [ '.c', @@ -25,16 +25,16 @@ scons: Reading SConscript files ... '.SPP', '.sx'], 'DSUFFIXES': ['.d'], - 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, - 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'ENV': { 'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}, - 'ESCAPE': <function escape at 0x700000&gt;, - 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'ESCAPE': <function escape at 0x700000>, + 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'HOST_ARCH': None, 'HOST_OS': None, 'IDLSUFFIXES': ['.idl', '.IDL'], - 'INSTALL': <function copyFunc at 0x700000&gt;, - 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000&gt;, + 'INSTALL': <function copyFunc at 0x700000>, + 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000>, 'LIBPREFIX': 'lib', 'LIBPREFIXES': ['$LIBPREFIX'], 'LIBSUFFIX': '.a', @@ -45,18 +45,19 @@ scons: Reading SConscript files ... 'PLATFORM': 'posix', 'PROGPREFIX': '', 'PROGSUFFIX': '', - 'PSPAWN': <function piped_env_spawn at 0x700000&gt;, - 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, - 'SCANNERS': [<SCons.Scanner.Base object at 0x700000&gt;], + 'PSPAWN': <function piped_env_spawn at 0x700000>, + 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'SCANNERS': [<SCons.Scanner.Base object at 0x700000>], 'SHELL': 'sh', 'SHLIBPREFIX': '$LIBPREFIX', 'SHLIBSUFFIX': '.so', 'SHOBJPREFIX': '$OBJPREFIX', 'SHOBJSUFFIX': '$OBJSUFFIX', - 'SPAWN': <function subprocess_spawn at 0x700000&gt;, + 'SPAWN': <function subprocess_spawn at 0x700000>, 'TARGET_ARCH': None, 'TARGET_OS': None, 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, + 'TEMPFILEARGJOIN': ' ', 'TEMPFILEPREFIX': '@', 'TOOLS': ['install', 'install'], '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}', @@ -68,10 +69,10 @@ scons: Reading SConscript files ... '__LDMODULEVERSIONFLAGS': '${__libversionflags(__env__,"LDMODULEVERSION","_LDMODULEVERSIONFLAGS")}', '__RPATH': '$_RPATH', '__SHLIBVERSIONFLAGS': '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', - '__libversionflags': <function __libversionflags at 0x700000&gt;, - '_concat': <function _concat at 0x700000&gt;, - '_defines': <function _defines at 0x700000&gt;, - '_stripixes': <function _stripixes at 0x700000&gt;} + '__libversionflags': <function __libversionflags at 0x700000>, + '_concat': <function _concat at 0x700000>, + '_defines': <function _defines at 0x700000>, + '_stripixes': <function _stripixes at 0x700000>} scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. diff --git a/doc/generated/examples/troubleshoot_Dump_2.xml b/doc/generated/examples/troubleshoot_Dump_2.xml index e8e0960..6722575 100644 --- a/doc/generated/examples/troubleshoot_Dump_2.xml +++ b/doc/generated/examples/troubleshoot_Dump_2.xml @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <screen xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">C:\><userinput>scons</userinput> scons: Reading SConscript files ... -{ 'BUILDERS': {'_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000&gt;, '_InternalInstall': <function InstallBuilderWrapper at 0x700000&gt;, 'Object': <SCons.Builder.CompositeBuilder object at 0x700000&gt;, 'PCH': <SCons.Builder.BuilderBase object at 0x700000&gt;, 'RES': <SCons.Builder.BuilderBase object at 0x700000&gt;, 'SharedObject': <SCons.Builder.CompositeBuilder object at 0x700000&gt;, 'StaticObject': <SCons.Builder.CompositeBuilder object at 0x700000&gt;, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000&gt;}, +{ 'BUILDERS': {'_InternalInstallVersionedLib': <function InstallVersionedBuilderWrapper at 0x700000>, '_InternalInstall': <function InstallBuilderWrapper at 0x700000>, 'Object': <SCons.Builder.CompositeBuilder object at 0x700000>, 'PCH': <SCons.Builder.BuilderBase object at 0x700000>, 'RES': <SCons.Builder.BuilderBase object at 0x700000>, 'SharedObject': <SCons.Builder.CompositeBuilder object at 0x700000>, 'StaticObject': <SCons.Builder.CompositeBuilder object at 0x700000>, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000>}, 'CC': 'cl', - 'CCCOM': <SCons.Action.FunctionAction object at 0x700000&gt;, + 'CCCOM': <SCons.Action.FunctionAction object at 0x700000>, 'CCFLAGS': ['/nologo'], 'CCPCHFLAGS': ['${(PCH and "/Yu%s \\"/Fp%s\\""%(PCHSTOP or "",File(PCH))) or ""}'], 'CCPDBFLAGS': ['${(PDB and "/Z7") or ""}'], @@ -38,20 +38,20 @@ scons: Reading SConscript files ... 'CXXFILESUFFIX': '.cc', 'CXXFLAGS': ['$(', '/TP', '$)'], 'DSUFFIXES': ['.d'], - 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, - 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'ENV': { 'PATH': 'C:\\WINDOWS\\System32', 'PATHEXT': '.COM;.EXE;.BAT;.CMD', 'SystemRoot': 'C:\\WINDOWS'}, - 'ESCAPE': <function escape at 0x700000&gt;, - 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, + 'ESCAPE': <function escape at 0x700000>, + 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'HOST_ARCH': '', 'HOST_OS': 'win32', 'IDLSUFFIXES': ['.idl', '.IDL'], 'INCPREFIX': '/I', 'INCSUFFIX': '', - 'INSTALL': <function copyFunc at 0x700000&gt;, - 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000&gt;, + 'INSTALL': <function copyFunc at 0x700000>, + 'INSTALLVERSIONEDLIB': <function copyFuncVersionedLib at 0x700000>, 'LEXUNISTD': ['--nounistd'], 'LIBPREFIX': '', 'LIBPREFIXES': ['$LIBPREFIX'], @@ -66,30 +66,31 @@ scons: Reading SConscript files ... 'PLATFORM': 'win32', 'PROGPREFIX': '', 'PROGSUFFIX': '.exe', - 'PSPAWN': <function piped_spawn at 0x700000&gt;, + 'PSPAWN': <function piped_spawn at 0x700000>, 'RC': 'rc', - 'RCCOM': <SCons.Action.FunctionAction object at 0x700000&gt;, + 'RCCOM': <SCons.Action.FunctionAction object at 0x700000>, 'RCFLAGS': ['/nologo'], 'RCSUFFIXES': ['.rc', '.rc2'], - 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;, - 'SCANNERS': [<SCons.Scanner.Base object at 0x700000&gt;], + 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'SCANNERS': [<SCons.Scanner.Base object at 0x700000>], 'SHCC': '$CC', - 'SHCCCOM': <SCons.Action.FunctionAction object at 0x700000&gt;, + 'SHCCCOM': <SCons.Action.FunctionAction object at 0x700000>, 'SHCCFLAGS': ['$CCFLAGS'], 'SHCFLAGS': ['$CFLAGS'], 'SHCXX': '$CXX', 'SHCXXCOM': '${TEMPFILE("$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM","$SHCXXCOMSTR")}', 'SHCXXFLAGS': ['$CXXFLAGS'], - 'SHELL': None, + 'SHELL': 'command', 'SHLIBPREFIX': '', 'SHLIBSUFFIX': '.dll', 'SHOBJPREFIX': '$OBJPREFIX', 'SHOBJSUFFIX': '$OBJSUFFIX', - 'SPAWN': <function spawn at 0x700000&gt;, + 'SPAWN': <function spawn at 0x700000>, 'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1, 'TARGET_ARCH': None, 'TARGET_OS': None, 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, + 'TEMPFILEARGJOIN': '\n', 'TEMPFILEPREFIX': '@', 'TOOLS': ['msvc', 'install', 'install'], '_CCCOMCOM': '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS', @@ -97,14 +98,14 @@ scons: Reading SConscript files ... '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', - '_MSVC_OUTPUT_FLAG': <function msvc_output_flag at 0x700000&gt;, + '_MSVC_OUTPUT_FLAG': <function msvc_output_flag at 0x700000>, '__DSHLIBVERSIONFLAGS': '${__libversionflags(__env__,"DSHLIBVERSION","_DSHLIBVERSIONFLAGS")}', '__LDMODULEVERSIONFLAGS': '${__libversionflags(__env__,"LDMODULEVERSION","_LDMODULEVERSIONFLAGS")}', '__SHLIBVERSIONFLAGS': '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', - '__libversionflags': <function __libversionflags at 0x700000&gt;, - '_concat': <function _concat at 0x700000&gt;, - '_defines': <function _defines at 0x700000&gt;, - '_stripixes': <function _stripixes at 0x700000&gt;} + '__libversionflags': <function __libversionflags at 0x700000>, + '_concat': <function _concat at 0x700000>, + '_defines': <function _defines at 0x700000>, + '_stripixes': <function _stripixes at 0x700000>} scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml index 04b09fd..cb3ef9b 100644 --- a/doc/generated/examples/troubleshoot_explain1_3.xml +++ b/doc/generated/examples/troubleshoot_explain1_3.xml @@ -3,5 +3,6 @@ cp file.in file.oout scons: warning: Cannot find target file.out after building -File "/home/bdeegan/devel/scons/git/as_scons/bootstrap/src/script/scons.py", line 204, in <module> +File "/Users/bdbaddog/devel/scons/git/scons-bugfixes-3/src/script/scons.py", line 204, in <module> +File "/home/mats/github/scons/src/script/scons.py", line 204, in <module> </screen> diff --git a/doc/generated/examples/troubleshoot_stacktrace_2.xml b/doc/generated/examples/troubleshoot_stacktrace_2.xml index 76cfc1a..2d88ae8 100644 --- a/doc/generated/examples/troubleshoot_stacktrace_2.xml +++ b/doc/generated/examples/troubleshoot_stacktrace_2.xml @@ -4,10 +4,10 @@ scons: *** [prog.o] Source `prog.c' not found, needed by target `prog.o'. scons: internal stack trace: File "bootstrap/src/engine/SCons/Job.py", line 199, in start task.prepare() - File "bootstrap/src/engine/SCons/Script/Main.py", line 177, in prepare + File "bootstrap/src/engine/SCons/Script/Main.py", line 190, in prepare return SCons.Taskmaster.OutOfDateTask.prepare(self) File "bootstrap/src/engine/SCons/Taskmaster.py", line 198, in prepare executor.prepare() - File "bootstrap/src/engine/SCons/Executor.py", line 430, in prepare + File "bootstrap/src/engine/SCons/Executor.py", line 431, in prepare raise SCons.Errors.StopError(msg % (s, self.batches[0].targets[0])) </screen> diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen index 5e8bebb..e55799c 100644 --- a/doc/generated/functions.gen +++ b/doc/generated/functions.gen @@ -1333,11 +1333,11 @@ env.Depends(bar, installed_lib) <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> Returns a dictionary object -containing copies of all of the -construction variables in the environment. -If there are any variable names specified, -only the specified construction -variables are returned in the dictionary. +containing the <literal xmlns="http://www.scons.org/dbxsd/v1.0">construction variables</literal> in the <literal xmlns="http://www.scons.org/dbxsd/v1.0">construction environment</literal>. +If there are any arguments specified, +the values of the specified <literal xmlns="http://www.scons.org/dbxsd/v1.0">construction variables</literal> +are returned as a string (if one +argument) or as a list of strings. </para> <para xmlns="http://www.scons.org/dbxsd/v1.0"> @@ -1345,8 +1345,8 @@ Example: </para> <example_commands xmlns="http://www.scons.org/dbxsd/v1.0"> -dict = env.Dictionary() -cc_dict = env.Dictionary('CC', 'CCFLAGS', 'CCCOM') +cvars = env.Dictionary() +cc_values = env.Dictionary('CC', 'CCFLAGS', 'CCCOM') </example_commands> </listitem> </varlistentry> @@ -2948,30 +2948,33 @@ and added to the following construction variables: </para> <example_commands xmlns="http://www.scons.org/dbxsd/v1.0"> --arch CCFLAGS, LINKFLAGS --D CPPDEFINES --framework FRAMEWORKS --frameworkdir= FRAMEWORKPATH --include CCFLAGS --isysroot CCFLAGS, LINKFLAGS --isystem CCFLAGS --iquote CCFLAGS --idirafter CCFLAGS --I CPPPATH --l LIBS --L LIBPATH --mno-cygwin CCFLAGS, LINKFLAGS --mwindows LINKFLAGS --pthread CCFLAGS, LINKFLAGS --std= CFLAGS --Wa, ASFLAGS, CCFLAGS --Wl,-rpath= RPATH --Wl,-R, RPATH --Wl,-R RPATH --Wl, LINKFLAGS --Wp, CPPFLAGS -- CCFLAGS -+ CCFLAGS, LINKFLAGS +-arch CCFLAGS, LINKFLAGS +-D CPPDEFINES +-framework FRAMEWORKS +-frameworkdir= FRAMEWORKPATH +-fmerge-all-constants CCFLAGS, LINKFLAGS +-fopenmp CCFLAGS, LINKFLAGS +-include CCFLAGS +-isysroot CCFLAGS, LINKFLAGS +-isystem CCFLAGS +-iquote CCFLAGS +-idirafter CCFLAGS +-I CPPPATH +-l LIBS +-L LIBPATH +-mno-cygwin CCFLAGS, LINKFLAGS +-mwindows LINKFLAGS +-openmp CCFLAGS, LINKFLAGS +-pthread CCFLAGS, LINKFLAGS +-std= CFLAGS +-Wa, ASFLAGS, CCFLAGS +-Wl,-rpath= RPATH +-Wl,-R, RPATH +-Wl,-R RPATH +-Wl, LINKFLAGS +-Wp, CPPFLAGS +- CCFLAGS ++ CCFLAGS, LINKFLAGS </example_commands> <para xmlns="http://www.scons.org/dbxsd/v1.0"> diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen index be717e3..0d30f6f 100644 --- a/doc/generated/tools.gen +++ b/doc/generated/tools.gen @@ -91,7 +91,7 @@ Sets construction variables for the bcc32 compiler. <term>cc</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> -Sets construction variables for generic POSIX C copmilers. +Sets construction variables for generic POSIX C compilers. </para> <para>Sets: &cv-link-CC;, &cv-link-CCCOM;, &cv-link-CCFLAGS;, &cv-link-CFILESUFFIX;, &cv-link-CFLAGS;, &cv-link-CPPDEFPREFIX;, &cv-link-CPPDEFSUFFIX;, &cv-link-FRAMEWORKPATH;, &cv-link-FRAMEWORKS;, &cv-link-INCPREFIX;, &cv-link-INCSUFFIX;, &cv-link-SHCC;, &cv-link-SHCCCOM;, &cv-link-SHCCFLAGS;, &cv-link-SHCFLAGS;, &cv-link-SHOBJSUFFIX;.</para><para>Uses: &cv-link-PLATFORM;.</para></listitem> </varlistentry> @@ -139,9 +139,91 @@ Set construction variables for cygwin linker/loader. <term>default</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> -Sets variables by calling a default list of Tool modules -for the platform on which SCons is running. +Sets <literal xmlns="http://www.scons.org/dbxsd/v1.0">construction variables</literal> for a default list of Tool modules. +Use <emphasis role="bold">default</emphasis> +in the tools list to retain the original defaults, +since the <parameter>tools</parameter> parameter +is treated as a literal statement of the tools +to be made available in that <literal xmlns="http://www.scons.org/dbxsd/v1.0">construction environment</literal>, not an addition. </para> + +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +The list of tools selected by default is not static, +but is dependent both on +the platform and on the software installed on the platform. +Some tools will not initialize if an underlying command is +not found, and some tools are selected from a list of choices +on a first-found basis. The finished tool list can be +examined by inspecting the <envar>TOOLS</envar> <literal xmlns="http://www.scons.org/dbxsd/v1.0">construction variable</literal> +in the <literal xmlns="http://www.scons.org/dbxsd/v1.0">construction environment</literal>. +</para> + +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +On all platforms, all tools from the following list +are selected whose respective conditions are met: +filesystem, wix, lex, yacc, rpcgen, swig, +jar, javac, javah, rmic, dvipdf, dvips, gs, +tex, latex, pdflatex, pdftex, tar, zip, textfile. +</para> + +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +On Linux systems, the default tools list selects +(first-found): a C compiler from +gcc, intelc, icc, cc; +a C++ compiler from +g++, intelc, icc, cxx; +an assembler from +gas, nasm, masm; +a linker from +gnulink, ilink; +a Fortran compiler from +gfortran, g77, ifort, ifl, f95, f90, f77; +and a static archiver 'ar'. +It also selects all found from the list +m4, rpm. +</para> + +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +On Windows systems, the default tools list selects +(first-found): a C compiler from +msvc, mingw, gcc, intelc, icl, icc, cc, bcc32; +a C++ compiler from +msvc, intelc, icc, g++, cxx, bcc32; +an assembler from +masm, nasm, gas, 386asm; +a linker from +mslink, gnulink, ilink, linkloc, ilink32; +a Fortran compiler from +gfortran, g77, ifl, cvf, f95, f90, fortran; +and a static archiver from +mslib, ar, tlib; +It also selects all found from the list +msvs, midl. +</para> + +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +On MacOS systems, the default tools list selects +(first-found): a C compiler from +gcc, cc; +a C++ compiler from +g++, cxx; +an assembler 'as'; +a linker from +applelink, gnulink; +a Fortran compiler from +gfortran, f95, f90, g77; +and a static archiver ar. +It also selects all found from the list +m4, rpm. +</para> + +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +Default lists for other platforms can be found by +examining the <filename xmlns="http://www.scons.org/dbxsd/v1.0">scons</filename> +source code (see +<filename>SCons/Tool/__init__.py</filename>). +</para> + </listitem> </varlistentry> <varlistentry id="t-dmd"> @@ -627,7 +709,9 @@ Sets construction variables for the <application xmlns="http://www.scons.org/dbx <term>link</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> -Sets construction variables for generic POSIX linkers. +Sets construction variables for generic POSIX linkers. This is +a "smart" linker tool which selects a compiler to complete the linking +based on the types of source files. </para> <para>Sets: &cv-link-LDMODULE;, &cv-link-LDMODULECOM;, &cv-link-LDMODULEFLAGS;, &cv-link-LDMODULENOVERSIONSYMLINKS;, &cv-link-LDMODULEPREFIX;, &cv-link-LDMODULESUFFIX;, &cv-link-LDMODULEVERSION;, &cv-link-LDMODULEVERSIONFLAGS;, &cv-link-LIBDIRPREFIX;, &cv-link-LIBDIRSUFFIX;, &cv-link-LIBLINKPREFIX;, &cv-link-LIBLINKSUFFIX;, &cv-link-LINK;, &cv-link-LINKCOM;, &cv-link-LINKFLAGS;, &cv-link-SHLIBSUFFIX;, &cv-link-SHLINK;, &cv-link-SHLINKCOM;, &cv-link-SHLINKFLAGS;, &cv-link-__LDMODULEVERSIONFLAGS;, &cv-link-__SHLIBVERSIONFLAGS;.</para><para>Uses: &cv-link-LDMODULECOMSTR;, &cv-link-LINKCOMSTR;, &cv-link-SHLINKCOMSTR;.</para></listitem> </varlistentry> @@ -779,19 +863,19 @@ Sets construction variables for the </para> <para>Sets: &cv-link-AS;, &cv-link-ASCOM;, &cv-link-ASFLAGS;, &cv-link-ASPPCOM;, &cv-link-ASPPFLAGS;.</para><para>Uses: &cv-link-ASCOMSTR;, &cv-link-ASPPCOMSTR;.</para></listitem> </varlistentry> - <varlistentry id="t-packaging"> - <term>packaging</term> + <varlistentry id="t-Packaging"> + <term>Packaging</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> -A framework for building binary and source packages. +Sets construction variables for the <function xmlns="http://www.scons.org/dbxsd/v1.0">Package</function> Builder. </para> </listitem> </varlistentry> - <varlistentry id="t-Packaging"> - <term>Packaging</term> + <varlistentry id="t-packaging"> + <term>packaging</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> -Sets construction variables for the <function xmlns="http://www.scons.org/dbxsd/v1.0">Package</function> Builder. +A framework for building binary and source packages. </para> </listitem> </varlistentry> diff --git a/doc/generated/tools.mod b/doc/generated/tools.mod index f9bc1d7..1209d74 100644 --- a/doc/generated/tools.mod +++ b/doc/generated/tools.mod @@ -78,8 +78,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. <!ENTITY t-mwcc "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>mwcc</literal>"> <!ENTITY t-mwld "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>mwld</literal>"> <!ENTITY t-nasm "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>nasm</literal>"> -<!ENTITY t-packaging "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>packaging</literal>"> <!ENTITY t-Packaging "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>Packaging</literal>"> +<!ENTITY t-packaging "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>packaging</literal>"> <!ENTITY t-pdf "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>pdf</literal>"> <!ENTITY t-pdflatex "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>pdflatex</literal>"> <!ENTITY t-pdftex "<literal xmlns='http://www.scons.org/dbxsd/v1.0'>pdftex</literal>"> @@ -186,8 +186,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. <!ENTITY t-link-mwcc "<link linkend='t-mwcc' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>mwcc</literal></link>"> <!ENTITY t-link-mwld "<link linkend='t-mwld' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>mwld</literal></link>"> <!ENTITY t-link-nasm "<link linkend='t-nasm' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>nasm</literal></link>"> -<!ENTITY t-link-packaging "<link linkend='t-packaging' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>packaging</literal></link>"> <!ENTITY t-link-Packaging "<link linkend='t-Packaging' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>Packaging</literal></link>"> +<!ENTITY t-link-packaging "<link linkend='t-packaging' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>packaging</literal></link>"> <!ENTITY t-link-pdf "<link linkend='t-pdf' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>pdf</literal></link>"> <!ENTITY t-link-pdflatex "<link linkend='t-pdflatex' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>pdflatex</literal></link>"> <!ENTITY t-link-pdftex "<link linkend='t-pdftex' xmlns='http://www.scons.org/dbxsd/v1.0'><literal>pdftex</literal></link>"> diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index 28dfc59..8f09512 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -874,35 +874,15 @@ depending on the specific C++ compiler being used. <para xmlns="http://www.scons.org/dbxsd/v1.0"> The D compiler to use. </para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> -The D compiler to use. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> -The D compiler to use. -</para> </listitem> </varlistentry> <varlistentry id="cv-DCOM"> <term>DCOM</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line used to compile a D file to an object file. - Any options specified in the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-DFLAGS"><envar>$DFLAGS</envar></link> construction variable - is included on this command line. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line used to compile a D file to an object file. - Any options specified in the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-DFLAGS"><envar>$DFLAGS</envar></link> construction variable - is included on this command line. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line used to compile a D file to an object file. - Any options specified in the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-DFLAGS"><envar>$DFLAGS</envar></link> construction variable - is included on this command line. +The command line used to compile a D file to an object file. +Any options specified in the <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-DFLAGS"><envar>$DFLAGS</envar></link> construction variable +is included on this command line. </para> </listitem> </varlistentry> @@ -910,49 +890,25 @@ The D compiler to use. <term>DDEBUG</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - List of debug tags to enable when compiling. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - List of debug tags to enable when compiling. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - List of debug tags to enable when compiling. +List of debug tags to enable when compiling. </para> </listitem> </varlistentry> <varlistentry id="cv-DDEBUGPREFIX"> <term>DDEBUGPREFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DDEBUGPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DDEBUGPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DDEBUGPREFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DDEBUGPREFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DDEBUGSUFFIX"> <term>DDEBUGSUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DDEBUGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DDEBUGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DDEBUGSUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DDEBUGSUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DESCRIPTION"> <term>DESCRIPTION</term> @@ -980,98 +936,50 @@ section of an RPM <varlistentry id="cv-DFILESUFFIX"> <term>DFILESUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DFILESUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DFILESUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DFILESUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DFILESUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DFLAGPREFIX"> <term>DFLAGPREFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DFLAGPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DFLAGPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DFLAGPREFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DFLAGPREFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DFLAGS"> <term>DFLAGS</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - General options that are passed to the D compiler. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - General options that are passed to the D compiler. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - General options that are passed to the D compiler. +General options that are passed to the D compiler. </para> </listitem> </varlistentry> <varlistentry id="cv-DFLAGSUFFIX"> <term>DFLAGSUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DFLAGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DFLAGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DFLAGSUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DFLAGSUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DINCPREFIX"> <term>DINCPREFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DINCPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DINCPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DINCPREFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DINCPREFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DINCSUFFIX"> <term>DINCSUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBFLAGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBFLAGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBFLAGSUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DLIBFLAGSUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-Dir"> <term>Dir</term> @@ -1100,15 +1008,7 @@ into a list of Dir instances relative to the target being built. <term>DLIB</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - Name of the lib tool to use for D codes. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - Name of the lib tool to use for D codes. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - Name of the lib tool to use for D codes. +Name of the lib tool to use for D codes. </para> </listitem> </varlistentry> @@ -1116,127 +1016,63 @@ into a list of Dir instances relative to the target being built. <term>DLIBCOM</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when creating libraries. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when creating libraries. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when creating libraries. +The command line to use when creating libraries. </para> </listitem> </varlistentry> <varlistentry id="cv-DLIBDIRPREFIX"> <term>DLIBDIRPREFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKPREFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DLIBLINKPREFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DLIBDIRSUFFIX"> <term>DLIBDIRSUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKSUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DLIBLINKSUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DLIBFLAGPREFIX"> <term>DLIBFLAGPREFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBFLAGPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBFLAGPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBFLAGPREFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DLIBFLAGPREFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DLIBFLAGSUFFIX"> <term>DLIBFLAGSUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBFLAGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBFLAGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBFLAGSUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DLIBFLAGSUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DLIBLINKPREFIX"> <term>DLIBLINKPREFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKPREFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DLIBLINKPREFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DLIBLINKSUFFIX"> <term>DLIBLINKSUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLIBLINKSUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DLIBLINKSUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DLINK"> <term>DLINK</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - Name of the linker to use for linking systems including D sources. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - Name of the linker to use for linking systems including D sources. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - Name of the linker to use for linking systems including D sources. +Name of the linker to use for linking systems including D sources. </para> </listitem> </varlistentry> @@ -1244,33 +1080,17 @@ into a list of Dir instances relative to the target being built. <term>DLINKCOM</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when linking systems including D sources. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when linking systems including D sources. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when linking systems including D sources. +The command line to use when linking systems including D sources. </para> </listitem> </varlistentry> <varlistentry id="cv-DLINKFLAGPREFIX"> <term>DLINKFLAGPREFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLINKFLAGPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLINKFLAGPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLINKFLAGPREFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DLINKFLAGPREFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DLINKFLAGS"> <term>DLINKFLAGS</term> @@ -1278,31 +1098,15 @@ into a list of Dir instances relative to the target being built. <para xmlns="http://www.scons.org/dbxsd/v1.0"> List of linker flags. </para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> -List of linker flags. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> -List of linker flags. -</para> </listitem> </varlistentry> <varlistentry id="cv-DLINKFLAGSUFFIX"> <term>DLINKFLAGSUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLINKFLAGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLINKFLAGSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DLINKFLAGSUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DLINKFLAGSUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DOCBOOK_DEFAULT_XSL_EPUB"> <term>DOCBOOK_DEFAULT_XSL_EPUB</term> @@ -1507,39 +1311,31 @@ for <literal>saxon</literal> and <literal>saxon-xslt</literal>, respectively. <para xmlns="http://www.scons.org/dbxsd/v1.0"> List of paths to search for import modules. </para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - List of paths to search for import modules. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - List of paths to search for import modules. -</para> </listitem> </varlistentry> <varlistentry id="cv-DRPATHPREFIX"> <term>DRPATHPREFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DRPATHPREFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DRPATHPREFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DRPATHSUFFIX"> <term>DRPATHSUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DRPATHSUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DRPATHSUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DShLibSonameGenerator"> <term>DShLibSonameGenerator</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DShLibSonameGenerator. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DShLibSonameGenerator. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DSUFFIXES"> <term>DSUFFIXES</term> @@ -1558,50 +1354,26 @@ The default list is: <varlistentry id="cv-DVERPREFIX"> <term>DVERPREFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DVERPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DVERPREFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DVERPREFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DVERPREFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DVERSIONS"> <term>DVERSIONS</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - List of version tags to enable when compiling. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - List of version tags to enable when compiling. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - List of version tags to enable when compiling. +List of version tags to enable when compiling. </para> </listitem> </varlistentry> <varlistentry id="cv-DVERSUFFIX"> <term>DVERSUFFIX</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DVERSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DVERSUFFIX. - </para> - - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - DVERSUFFIX. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +DVERSUFFIX. +</para> +</listitem> </varlistentry> <varlistentry id="cv-DVIPDF"> <term>DVIPDF</term> @@ -3298,7 +3070,7 @@ The command line used to call the Java archive tool. <para xmlns="http://www.scons.org/dbxsd/v1.0"> The string displayed when the Java archive tool is called -If this is not set, then <envar xmlns="http://www.scons.org/dbxsd/v1.0">$JARCOM</envar> (the command line) is displayed. +If this is not set, then <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-JARCOM"><envar>$JARCOM</envar></link> (the command line) is displayed. </para> <example_commands xmlns="http://www.scons.org/dbxsd/v1.0"> @@ -3308,7 +3080,7 @@ env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET") <para xmlns="http://www.scons.org/dbxsd/v1.0"> The string displayed when the Java archive tool is called -If this is not set, then <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-JARCOM"><envar>$JARCOM</envar></link> (the command line) is displayed. +If this is not set, then <envar xmlns="http://www.scons.org/dbxsd/v1.0">$JARCOM</envar> (the command line) is displayed. </para> <example_commands xmlns="http://www.scons.org/dbxsd/v1.0"> @@ -4239,7 +4011,7 @@ The command line used to pass files to the Microsoft IDL compiler. <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> The string displayed when -the Microsoft IDL copmiler is called. +the Microsoft IDL compiler is called. If this is not set, then <link xmlns="http://www.scons.org/dbxsd/v1.0" linkend="cv-MIDLCOM"><envar>$MIDLCOM</envar></link> (the command line) is displayed. </para> </listitem> @@ -6149,18 +5921,8 @@ to generate shared-library objects. <term>SHDC</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - The name of the compiler to use when compiling D source - destined to be in a shared objects. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The name of the compiler to use when compiling D source - destined to be in a shared objects. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The name of the compiler to use when compiling D source - destined to be in a shared objects. +The name of the compiler to use when compiling D source +destined to be in a shared objects. </para> </listitem> </varlistentry> @@ -6168,50 +5930,32 @@ to generate shared-library objects. <term>SHDCOM</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when compiling code to be part of shared objects. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when compiling code to be part of shared objects. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when compiling code to be part of shared objects. +The command line to use when compiling code to be part of shared objects. </para> </listitem> </varlistentry> <varlistentry id="cv-SHDLIBVERSION"> <term>SHDLIBVERSION</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - SHDLIBVERSION. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +SHDLIBVERSION. +</para> +</listitem> </varlistentry> <varlistentry id="cv-SHDLIBVERSIONFLAGS"> <term>SHDLIBVERSIONFLAGS</term> <listitem> - <para xmlns="http://www.scons.org/dbxsd/v1.0"> - SHDLIBVERSIONFLAGS. - </para> - </listitem> +<para xmlns="http://www.scons.org/dbxsd/v1.0"> +SHDLIBVERSIONFLAGS. +</para> +</listitem> </varlistentry> <varlistentry id="cv-SHDLINK"> <term>SHDLINK</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - The linker to use when creating shared objects for code bases - include D sources. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The linker to use when creating shared objects for code bases - include D sources. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The linker to use when creating shared objects for code bases - include D sources. +The linker to use when creating shared objects for code bases +include D sources. </para> </listitem> </varlistentry> @@ -6219,15 +5963,7 @@ to generate shared-library objects. <term>SHDLINKCOM</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when generating shared objects. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when generating shared objects. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The command line to use when generating shared objects. +The command line to use when generating shared objects. </para> </listitem> </varlistentry> @@ -6235,15 +5971,7 @@ to generate shared-library objects. <term>SHDLINKFLAGS</term> <listitem> <para xmlns="http://www.scons.org/dbxsd/v1.0"> - The list of flags to use when generating a shared object. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The list of flags to use when generating a shared object. -</para> - -<para xmlns="http://www.scons.org/dbxsd/v1.0"> - The list of flags to use when generating a shared object. +The list of flags to use when generating a shared object. </para> </listitem> </varlistentry> diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index 47576f4..372a15f 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -504,8 +504,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. <!ENTITY cv-_SHLIBSONAME "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$_SHLIBSONAME</envar>"> <!ENTITY cv-SHLIBSUFFIX "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBSUFFIX</envar>"> <!ENTITY cv-SHLIBVERSION "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBVERSION</envar>"> -<!ENTITY cv-_SHLIBVERSIONFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$_SHLIBVERSIONFLAGS</envar>"> <!ENTITY cv-SHLIBVERSIONFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLIBVERSIONFLAGS</envar>"> +<!ENTITY cv-_SHLIBVERSIONFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$_SHLIBVERSIONFLAGS</envar>"> <!ENTITY cv-SHLINK "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLINK</envar>"> <!ENTITY cv-SHLINKCOM "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLINKCOM</envar>"> <!ENTITY cv-SHLINKCOMSTR "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$SHLINKCOMSTR</envar>"> @@ -1144,8 +1144,8 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. <!ENTITY cv-link-_SHLIBSONAME "<link linkend='cv-_SHLIBSONAME' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$_SHLIBSONAME</envar></link>"> <!ENTITY cv-link-SHLIBSUFFIX "<link linkend='cv-SHLIBSUFFIX' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBSUFFIX</envar></link>"> <!ENTITY cv-link-SHLIBVERSION "<link linkend='cv-SHLIBVERSION' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBVERSION</envar></link>"> -<!ENTITY cv-link-_SHLIBVERSIONFLAGS "<link linkend='cv-_SHLIBVERSIONFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$_SHLIBVERSIONFLAGS</envar></link>"> <!ENTITY cv-link-SHLIBVERSIONFLAGS "<link linkend='cv-SHLIBVERSIONFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLIBVERSIONFLAGS</envar></link>"> +<!ENTITY cv-link-_SHLIBVERSIONFLAGS "<link linkend='cv-_SHLIBVERSIONFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$_SHLIBVERSIONFLAGS</envar></link>"> <!ENTITY cv-link-SHLINK "<link linkend='cv-SHLINK' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLINK</envar></link>"> <!ENTITY cv-link-SHLINKCOM "<link linkend='cv-SHLINKCOM' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLINKCOM</envar></link>"> <!ENTITY cv-link-SHLINKCOMSTR "<link linkend='cv-SHLINKCOMSTR' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$SHLINKCOMSTR</envar></link>"> diff --git a/doc/man/scons-time.xml b/doc/man/scons-time.xml index e0fa6b1..794e593 100644 --- a/doc/man/scons-time.xml +++ b/doc/man/scons-time.xml @@ -53,7 +53,6 @@ <refsect1 id='generating_timing_information'><title>Generating Timing Information</title> <para><emphasis role="bold">scons-time run</emphasis> [<option>-hnqv</option>] -[<option>--aegis=</option><replaceable>PROJECT</replaceable>] [<option>-f </option><emphasis>FILE</emphasis>] [<option>--number=</option><replaceable>NUMBER</replaceable>] [<option>--outdir=</option><replaceable>OUTDIR</replaceable>] @@ -644,7 +643,6 @@ files.</para> <refsect2 id='the_run_subcommand'><title>The run Subcommand</title> <para><emphasis role="bold">scons-time run</emphasis> [<option>-hnqv</option>] -[<option>--aegis=</option><replaceable>PROJECT</replaceable>] [<option>-f </option><emphasis>FILE</emphasis>] [<option>--number=</option><replaceable>NUMBER</replaceable>] [<option>--outdir=</option><replaceable>OUTDIR</replaceable>] @@ -728,31 +726,6 @@ this should be an up-to-date, "do nothing" rebuild.</para> subcommand supports the following options:</para> <variablelist> <varlistentry> - <term>--aegis=PROJECT</term> - <listitem> -<para>Specifies the Aegis -<emphasis>PROJECT</emphasis> -from which the -version(s) of -<emphasis role="bold">scons</emphasis> -being timed will be extracted. -When -<option>--aegis</option> -is specified, the -<option>--number=</option><replaceable>NUMBER</replaceable> -option specifies delta numbers -that will be tested. -Output from each invocation run will be placed in file -names that match the Aegis delta numbers. -If the -<option>--number=</option> -option is not specified, -then the default behavior is to time the -tip of the specified -<emphasis>PROJECT</emphasis>.</para> - </listitem> - </varlistentry> - <varlistentry> <term>-f FILE, --file=FILE</term> <listitem> <para>Reads configuration information from the specified @@ -799,14 +772,6 @@ the log files and profile outputs generated by this run.</para> </variablelist> <para>When used in conjunction with the -<option>--aegis=</option><replaceable>PROJECT</replaceable> -option, -<emphasis>NUMBER</emphasis> -specifies one or more comma-separated Aegis delta numbers -that will be retrieved automatically from the specified Aegis -<emphasis>PROJECT</emphasis>.</para> - -<para>When used in conjunction with the <option>--svn=</option><replaceable>URL</replaceable> option, <emphasis>NUMBER</emphasis> @@ -1057,24 +1022,6 @@ the necessary information for producing (and reporting) consistent timing runs for a given configuration.</para> <variablelist> <varlistentry> - <term><emphasis role="bold">aegis</emphasis></term> - <listitem> -<para>The Aegis executable for extracting deltas. -The default is simply -<emphasis role="bold">aegis</emphasis>.</para> - </listitem> - </varlistentry> - <varlistentry> - <term><emphasis role="bold">aegis_project</emphasis></term> - <listitem> -<para>The Aegis project from which deltas should be extracted. -The default is whatever is specified -with the -<option>--aegis=</option> -command-line option.</para> - </listitem> - </varlistentry> - <varlistentry> <term><emphasis role="bold">archive_list</emphasis></term> <listitem> <para>A list of archives (files or directories) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 542ac9d..a9e0dd7 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -209,12 +209,12 @@ that you want to use to build your target files are not in standard system locations, <command>scons</command> will not find them unless -you explicitly set the PATH +you explicitly set the <envar>PATH</envar> to include those locations. Whenever you create an <command>scons</command> construction environment, -you can propagate the value of PATH +you can propagate the value of <envar>PATH</envar> from your external environment as follows:</para> <literallayout class="monospaced"> @@ -223,13 +223,20 @@ env = Environment(ENV = {'PATH' : os.environ['PATH']}) </literallayout> <para>Similarly, if the commands use external environment variables -like $PATH, $HOME, $JAVA_HOME, $LANG, $SHELL, $TERM, etc., +like +<envar>PATH</envar>, +<envar>HOME</envar>, +<envar>JAVA_HOME</envar>, +<envar>LANG</envar>, +<envar>SHELL</envar>, +<envar>TERM</envar>, +etc., these variables can also be explicitly propagated:</para> <literallayout class="monospaced"> import os -env = Environment(ENV = {'PATH' : os.environ['PATH'], - 'HOME' : os.environ['HOME']}) +env = Environment(ENV = {'PATH': os.environ['PATH'], + 'HOME': os.environ['HOME']}) </literallayout> <para>Or you may explicitly propagate the invoking user's @@ -720,17 +727,6 @@ files, as well as unlinking old targets before building them.</para> </listitem> </varlistentry> <varlistentry> - <term>--debug=dtree</term> - <listitem> -<para>A synonym for the newer -<option>--tree=derived</option> -option. -This will be deprecated in some future release -and ultimately removed.</para> - - </listitem> - </varlistentry> - <varlistentry> <term>--debug=explain</term> <listitem> <para>Print an explanation of precisely why @@ -786,13 +782,6 @@ and before and after building targets.</para> </listitem> </varlistentry> <varlistentry> - <term>--debug=nomemoizer</term> - <listitem> -<para>A deprecated option preserved for backwards compatibility.</para> - - </listitem> - </varlistentry> - <varlistentry> <term>--debug=objects</term> <listitem> <para>Prints a list of the various objects @@ -849,17 +838,6 @@ when encountering an otherwise unexplained error.</para> </listitem> </varlistentry> <varlistentry> - <term>--debug=stree</term> - <listitem> -<para>A synonym for the newer -<option>--tree=all,status</option> -option. -This will be deprecated in some future release -and ultimately removed.</para> - - </listitem> - </varlistentry> - <varlistentry> <term>--debug=time</term> <listitem> <para>Prints various time profiling information:</para> @@ -912,20 +890,43 @@ since multiple build commands and intervening SCons processing should take place in parallel.) </para> - </listitem> </varlistentry> - <varlistentry> - <term>--debug=tree</term> - <listitem> -<para>A synonym for the newer -<option>--tree=all</option> -option. -This will be deprecated in some future release -and ultimately removed.</para> +<varlistentry> + <term>--debug=action_timestamps</term> + <listitem> + <para>Prints additional time profiling information:</para> + <itemizedlist> + <listitem> + <para>The time spent executing each individual build command</para> + </listitem> + <listitem> + <para>The total build time (time SCons ran from beginning to end)</para> + </listitem> + <listitem> + <para>The total time spent reading and executing SConscript files</para> + </listitem> + <listitem> + <para>The total time spent SCons itself spend running +(that is, not counting reading and executing SConscript files)</para> + </listitem> + <listitem> + <para>The total time spent executing all build commands</para> + </listitem> + <listitem> + <para>The elapsed wall-clock time spent executing those build commands</para> + </listitem> + <listitem> + <para>The absolute start and end wall-clock time spent executing those build commands</para> + </listitem> + <listitem> + <para>The time spent processing each file passed to the <emphasis>SConscript()</emphasis> function</para> + </listitem> + </itemizedlist> </listitem> - </varlistentry> +</varlistentry> + <varlistentry> <term>--diskcheck=<emphasis>types</emphasis></term> <listitem> @@ -1113,6 +1114,18 @@ This implies </listitem> </varlistentry> + + <varlistentry> + <term>--install-sandbox=<replaceable>path</replaceable></term> + <listitem> +<para> +When using the &Install; functions, prepend <replaceable>path</replaceable> +to the installation paths such that all installed files will be placed +underneath <replaceable>path</replaceable>. +</para> + </listitem> + </varlistentry> + <varlistentry> <term>--interactive</term> <listitem> @@ -1814,27 +1827,6 @@ method.</para> </listitem> </varlistentry> - <varlistentry> - <term>--warn=deprecated-source-signatures, --warn=no-deprecated-source-signatures</term> - <listitem> -<para>Enables or disables warnings about use of the deprecated -<emphasis role="bold">SourceSignatures()</emphasis> -function or -<emphasis role="bold">env.SourceSignatures()</emphasis> -method.</para> - - </listitem> - </varlistentry> - <varlistentry> - <term>--warn=deprecated-target-signatures, --warn=no-deprecated-target-signatures</term> - <listitem> -<para>Enables or disables warnings about use of the deprecated -<emphasis role="bold">TargetSignatures()</emphasis> -function or -<emphasis role="bold">env.TargetSignatures()</emphasis> -method.</para> - </listitem> - </varlistentry> </variablelist> </blockquote> @@ -1914,7 +1906,7 @@ These warnings are enabled by default.</para> <option>--debug=object</option> feature not working when <command>scons</command> -is run with the python +is run with the Python <option>-O</option> option or from optimized Python (.pyo) modules.</para> @@ -2041,7 +2033,7 @@ env['BAR'] = 'bar' <para>As a convenience, construction variables may also be set or modified by the -<emphasis>parse_flags</emphasis> +<emphasis role="bold">parse_flags</emphasis> keyword argument, which applies the &f-link-env-MergeFlags; method (described below) to the argument value @@ -2112,36 +2104,59 @@ env = Environment(platform = my_platform) <para>Additionally, a specific set of tools with which to initialize the environment -may be specified as an optional keyword argument:</para> +may be specified using the optional keyword argument +<parameter>tools</parameter>:</para> <literallayout class="monospaced"> -env = Environment(tools = ['msvc', 'lex']) +env = Environment(tools=['msvc', 'lex']) </literallayout> -<para>Non-built-in tools may be specified using the toolpath argument:</para> +<para> +The <parameter>tools</parameter> argument overrides +the tool list, it does not add to it, so be +sure to include all the tools you need. +For example if you are building a c/c++ program +you must add a tool for both compiler and linker, +as in <literal>tools=['clang', 'link']</literal>. +The tool name <literal>'default'</literal> can +be used to retain the default list. +</para> + +<para>Non-built-in tools may be specified using the +optional <parameter>toolpath</parameter> keyword argument:</para> <literallayout class="monospaced"> -env = Environment(tools = ['default', 'foo'], toolpath = ['tools']) +env = Environment(tools=['default', 'foo'], toolpath=['tools']) </literallayout> -<para>This looks for a tool specification in tools/foo.py (as well as -using the ordinary default tools for the platform). foo.py should -have two functions: generate(env, **kw) and exists(env). +<para> +This looks for a tool specification in <filename>tools/foo.py</filename> +as well as using the ordinary default tools for the platform. +</para> + +<para> +A tool specification must include two functions: +<function>generate(env, **kw)</function> +and <function>exists(env)</function>. The -<function>generate()</function> +<function>generate</function> function -modifies the passed-in environment +modifies the environment referenced by <parameter>env</parameter> to set up variables so that the tool can be executed; it may use any keyword arguments -that the user supplies (see below) +that the user supplies in <parameter>kw</parameter> (see below) to vary its initialization. The -<function>exists()</function> +<function>exists</function> function should return a true value if the tool is available. +</para> + +<para> Tools in the toolpath are used before -any of the built-in ones. For example, adding gcc.py to the toolpath +any of the built-in ones. For example, adding +<filename>gcc.py</filename> to the toolpath would override the built-in gcc tool. Also note that the toolpath is stored in the environment for use @@ -2149,7 +2164,8 @@ by later calls to <emphasis role="bold">Clone</emphasis>() and <emphasis role="bold">Tool</emphasis>() -methods:</para> +methods: +</para> <literallayout class="monospaced"> base = Environment(toolpath=['custom_path']) @@ -2192,11 +2208,12 @@ or otherwise changing its initialization.</para> def generate(env, **kw): # Sets MY_TOOL to the value of keyword argument 'arg1' or 1. env['MY_TOOL'] = kw.get('arg1', '1') + def exists(env): - return 1 + return True # in SConstruct: -env = Environment(tools = ['default', ('my_tool', {'arg1': 'abc'})], +env = Environment(tools=['default', ('my_tool', {'arg1': 'abc'})], toolpath=['tools']) </programlisting> @@ -2215,7 +2232,7 @@ With a nested tool name the dot represents a directory seperator</para> <programlisting> # namespaced builder -env = Environment(ENV = os.environ, tools = ['SubDir1.SubDir2.SomeTool']) +env = Environment(ENV=os.environ, tools=['SubDir1.SubDir2.SomeTool']) env.SomeTool(targets, sources) # Search Paths @@ -2257,90 +2274,108 @@ env.SomeTool(targets, sources) <!-- '\" END GENERATED TOOL DESCRIPTIONS --> <!-- '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" --> -<para>Additionally, there is a "tool" named -<emphasis role="bold">default</emphasis> -which configures the -environment with a default set of tools for the current platform.</para> - -<para>On posix and cygwin platforms -the GNU tools (e.g. gcc) are preferred by SCons, -on Windows the Microsoft tools (e.g. msvc) -followed by MinGW are preferred by SCons, -and in OS/2 the IBM tools (e.g. icc) are preferred by SCons.</para> - </refsect2> <refsect2 id='builder_methods'><title>Builder Methods</title> -<para>Build rules are specified by calling a construction -environment's builder methods. -The arguments to the builder methods are -<emphasis role="bold">target</emphasis> -(a list of targets to be built, -usually file names) +<para>You tell <program>scons</program> what to build +by calling Builders, functions which know to take a +particular action when given files of a particular type +to produce a particular result type. <program>scons</program> +defines a number of builders, and you can also write your own. +Builders are attached to a &consenv; as methods, +and the available builder methods are listed as +key-value pairs in the +<envar>BUILDERS</envar> attribute of the &consenv;. +The available builders can be displayed like this +for debugging purposes: +</para> + +<literallayout class="monospaced"> +print("Builders:", list(env['BUILDERS'])) +</literallayout> + +<para> +Builder methods always take two arguments: +<replaceable>target</replaceable> +(a target or a list of targets to be built) and -<emphasis role="bold">source</emphasis> -(a list of sources to be built, -usually file names).</para> +<replaceable>source</replaceable> +(a source or list of sources to be used as input +when building), +although in some circumstances, +the target argument can actually be omitted (see below). +Builder methods also take a variety of +keyword arguments, described below. +</para> <para>Because long lists of file names can lead to a lot of quoting, <command>scons</command> -supplies a -<emphasis role="bold">Split()</emphasis> +supplies a &Split; global function and a same-named environment method that split a single string into a list, separated on strings of white-space characters. -(These are similar to the split() member function of Python strings -but work even if the input isn't a string.)</para> +(These are similar to the Python string <function>split</function> +method, but work even if the input isn't a string.)</para> -<para>Like all Python arguments, -the target and source arguments to a builder method -can be specified either with or without -the "target" and "source" keywords. -When the keywords are omitted, -the target is first, -followed by the source. -The following are equivalent examples of calling the Program builder method:</para> +<para> +The target and source arguments to a builder method +can be specified either as positional arguments, +in which case the target comes first, or as +keyword arguments, using <parameter>target=</parameter> +and <parameter>source=</parameter>. +The following are equivalent examples of calling the +&Program; builder method: +</para> <literallayout class="monospaced"> env.Program('bar', ['bar.c', 'foo.c']) env.Program('bar', Split('bar.c foo.c')) env.Program('bar', env.Split('bar.c foo.c')) -env.Program(source = ['bar.c', 'foo.c'], target = 'bar') -env.Program(target = 'bar', Split('bar.c foo.c')) -env.Program(target = 'bar', env.Split('bar.c foo.c')) -env.Program('bar', source = 'bar.c foo.c'.split()) +env.Program(source=['bar.c', 'foo.c'], target='bar') +env.Program(target='bar', source=Split('bar.c foo.c')) +env.Program(target='bar', source=env.Split('bar.c foo.c')) +env.Program('bar', source='bar.c foo.c'.split()) </literallayout> -<para>Target and source file names -that are not absolute path names -(that is, do not begin with -<emphasis role="bold">/</emphasis> -on POSIX systems -or -<emphasis role="bold">\</emphasis> -on Windows systems, -with or without -an optional drive letter) -are interpreted relative to the directory containing the -<emphasis role="bold">SConscript</emphasis> -file being read. -An initial -<emphasis role="bold">#</emphasis> -(hash mark) -on a path name means that the rest of the file name -is interpreted relative to -the directory containing -the top-level -<emphasis role="bold">SConstruct</emphasis> -file, -even if the -<emphasis role="bold">#</emphasis> -is followed by a directory separator character -(slash or backslash).</para> +<para> +Python follows the POSIX pathname convention for path +strings: if a string begins with the operating system pathname separator +(on Windows both the slash and backslash separator work, +and any leading drive specifier is ignored for +the determination) it is considered an absolute path, +otherwise it is a relative path. +If the path string contains no separator characters, +it is searched for as a file in the current directory. If it +contains separator characters, the search follows down +from the starting point, which is the top of the directory tree for +an absolute path and the current directory for a relative path. +</para> +<para> +<command>scons</command> recognizes a third way to specify +path strings: if the string begins with +the <emphasis role="bold">#</emphasis> character it is +top-relative - it works like a relative path but the +search follows down from the directory containing the top-level +<emphasis role="bold">SConstruct</emphasis> rather than +from the current directory (the # is allowed +to be followed by a pathname separator, which is ignored if +found in that position). +Top-relative paths only work in places where &scons; will +interpret the path (see some examples below). To be +used in other contexts the string will need to be converted +to a relative or absolute path first. +</para> + +<para> +Target and source pathnames can be absolute, relative, or +top-relative. Relative pathnames are searched considering the +directory of the <emphasis role="bold">SConscript</emphasis> +file currently being processed as the "current directory". +</para> <para>Examples:</para> @@ -2382,12 +2417,12 @@ executable program or <emphasis role="bold">bar.exe</emphasis> (on Windows systems) -from the bar.c source file:</para> +from the <filename>bar.c</filename> source file:</para> <literallayout class="monospaced"> -env.Program(target = 'bar', source = 'bar.c') -env.Program('bar', source = 'bar.c') -env.Program(source = 'bar.c') +env.Program(target='bar', source='bar.c') +env.Program('bar', source='bar.c') +env.Program(source='bar.c') env.Program('bar.c') </literallayout> @@ -2397,28 +2432,31 @@ keyword argument may be specified when calling a Builder. When specified, all source file strings that are not absolute paths +or top-relative paths will be interpreted relative to the specified <emphasis role="bold">srcdir</emphasis>. The following example will build the -<emphasis role="bold">build/prog</emphasis> +<filename>build/prog</filename> (or -<emphasis role="bold">build/prog.exe</emphasis> +<filename>build/prog.exe</filename> on Windows) program from the files -<emphasis role="bold">src/f1.c</emphasis> +<filename>src/f1.c</filename> and -<emphasis role="bold">src/f2.c</emphasis>:</para> +<filename>src/f2.c</filename>: +</para> <literallayout class="monospaced"> env.Program('build/prog', ['f1.c', 'f2.c'], srcdir='src') </literallayout> -<para>It is possible to override or add construction variables when calling a -builder method by passing additional keyword arguments. -These overridden or added -variables will only be in effect when building the target, so they will not -affect other parts of the build. For example, if you want to add additional -libraries for just one program:</para> +<para>It is possible to <emphasis>override</emphasis> (replace or add) +construction variables when calling a +builder method by passing them as keyword arguments. +These overrides +will only be in effect when building that target, and will not +affect other parts of the build. For example, if you want to specify +some libraries needed by just one program:</para> <literallayout class="monospaced"> env.Program('hello', 'hello.c', LIBS=['gl', 'glut']) @@ -2438,7 +2476,7 @@ for dependencies on the non-standard library names; see the descriptions of these variables, below, for more information.)</para> <para>It is also possible to use the -<emphasis>parse_flags</emphasis> +<emphasis role="bold">parse_flags</emphasis> keyword argument in an override, to merge command-line style arguments into the appropriate construction variables @@ -2483,8 +2521,7 @@ from SCons.Script import * </literallayout> <para>All builder methods return a list-like object -containing Nodes that -represent the target or targets that will be built. +containing Nodes that will be built. A <emphasis>Node</emphasis> is an internal SCons object @@ -2496,9 +2533,8 @@ can be passed to other builder methods as source(s) or passed to any SCons function or method where a filename would normally be accepted. For example, if it were necessary -to add a specific -<option>-D</option> -flag when compiling one specific object file:</para> +to add a specific preprocessor define +when compiling one specific object file:</para> <literallayout class="monospaced"> bar_obj_list = env.StaticObject('bar.c', CPPDEFINES='-DBAR') @@ -2509,14 +2545,14 @@ env.Program(source = ['foo.c', bar_obj_list, 'main.c']) makes for a more portable build by avoiding having to specify a platform-specific object suffix -when calling the Program() builder method.</para> +when calling the &Program; builder method.</para> -<para>Note that Builder calls will automatically "flatten" +<para>Note that builder calls will automatically "flatten" the source and target file lists, -so it's all right to have the bar_obj list -return by the StaticObject() call +so it's all right to have the <literal>bar_obj_list</literal> +returned by the &StaticObject; call in the middle of the source file list. -If you need to manipulate a list of lists returned by Builders +If you need to manipulate a list of lists returned by builders directly using Python, you can either build the list by hand:</para> @@ -2528,8 +2564,7 @@ for object in objects: print(str(object)) </literallayout> -<para>Or you can use the -<emphasis role="bold">Flatten</emphasis>() +<para>Or you can use the &Flatten; function supplied by scons to create a list containing just the Nodes, which may be more convenient:</para> @@ -2542,23 +2577,23 @@ for object in objects: print(str(object)) </literallayout> -<para>Note also that because Builder calls return +<para>Note also that because builder calls return a list-like object, not an actual Python list, you should <emphasis>not</emphasis> -use the Python -<emphasis role="bold">+=</emphasis> -operator to append Builder results to a Python list. +use the Python add +operator (<literal>+</literal> or <literal>+=</literal>) +to append builder results to a Python list. Because the list and the object are different types, Python will not update the original list in place, but will instead create a new Node-list object containing the concatenation of the list -elements and the Builder results. +elements and the builder results. This will cause problems for any other Python variables in your SCons configuration that still hold on to a reference to the original list. -Instead, use the Python -<markup>.extend()</markup> +Instead, use the Python list +<function>extend</function> method to make sure the list is updated in-place. Example:</para> @@ -2571,14 +2606,14 @@ object_files = [] # # It will not update the object_files list in place. # -# Instead, use the .extend() method: +# Instead, use the list extend method: object_files.extend(Object('bar.c')) </literallayout> <para>The path name for a Node's file may be used -by passing the Node to the Python-builtin -<function>str()</function> +by passing the Node to Python's builtin +<function>str</function> function:</para> <literallayout class="monospaced"> @@ -2588,7 +2623,7 @@ print("The path to bar_obj is:", str(bar_obj_list[0])) <para>Note again that because the Builder call returns a list, we have to access the first element in the list -<emphasis role="bold">(bar_obj_list[0])</emphasis> +(<literal>(bar_obj_list[0])</literal>) to get at the Node that actually represents the object file.</para> @@ -2651,7 +2686,12 @@ to use just the filename portion of the targets and source.</para> <para><command>scons</command> -provides the following builder methods:</para> +predefined the following builder methods. +Depending on the setup of a particular +&consenv; and on the type and software +installation status of the underlying system, +not all builders may be available to that +&consenv;.</para> <!-- '\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" --> <!-- '\" BEGIN GENERATED BUILDER DESCRIPTIONS --> @@ -3119,11 +3159,12 @@ defined construction variables:</para> method of the construction environment:</para> <literallayout class="monospaced"> -dict = env.Dictionary() -dict["CC"] = "cc" +cvars = env.Dictionary() +cvars["CC"] = "cc" </literallayout> -<para>or using the [] operator:</para> +<para>or using the key lookup operator <literal>[]</literal> +directly on the construction environment:</para> <literallayout class="monospaced"> env["CC"] = "cc" @@ -4387,7 +4428,7 @@ functions return and <emphasis>Dir</emphasis> Nodes, respectively. -python objects, respectively. +Python objects, respectively. Those objects have several user-visible attributes and methods that are often useful:</para> @@ -4544,7 +4585,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 @@ -5404,17 +5445,15 @@ a = Action(build_it, varlist=['XXX']) </programlisting> <para>The -<emphasis role="bold">Action</emphasis>() +&Action; global function can be passed the following optional keyword arguments to modify the Action object's behavior:</para> - -<para><emphasis role="bold">chdir</emphasis> -The -<emphasis role="bold">chdir</emphasis> -keyword argument specifies that +<para> +<replaceable>chdir</replaceable> +specifies that scons will execute the action after changing to the specified directory. If the @@ -5459,15 +5498,9 @@ a = Action("build < ${SOURCE.file} > ${TARGET.file}", chdir=1) </literallayout> - -<para><emphasis role="bold">exitstatfunc</emphasis> -The -<emphasis role="bold">Action</emphasis>() -global function -also takes an -<emphasis role="bold">exitstatfunc</emphasis> -keyword argument -which specifies a function +<para> +<replaceable>exitstatfunc</replaceable> +specifies a function that is passed the exit status (or return value) from the specified action @@ -5489,11 +5522,9 @@ a = Action("build < ${SOURCE.file} > ${TARGET.file}", </programlisting> -<para><emphasis role="bold">batch_key</emphasis> -The -<emphasis role="bold">batch_key</emphasis> -keyword argument can be used -to specify that the Action can create multiple target files +<para> +<replaceable>batch_key</replaceable> +specifies that the Action can create multiple target files by processing multiple independent source files simultaneously. (The canonical example is "batch compilation" of multiple object files @@ -5502,7 +5533,7 @@ to a single invocation of a compiler such as Microsoft's Visual C / C++ compiler.) If the <emphasis role="bold">batch_key</emphasis> -argument is any non-False, non-callable Python value, +argument evaluates True and is not a callable object, the configured Action object will cause <command>scons</command> to collect all targets built with the Action object @@ -5534,7 +5565,7 @@ will be used to identify different for batch building. A <emphasis role="bold">batch_key</emphasis> -function must take the following arguments:</para> +function must accept the following arguments:</para> <variablelist> <varlistentry> @@ -5666,7 +5697,7 @@ sequences of file manipulation without relying on platform-specific external commands: -that</para> +</para> <literallayout class="monospaced"> env = Environment(TMPBUILD = '/tmp/builddir') env.Command('foo.out', 'foo.in', @@ -5826,13 +5857,13 @@ env.Command('marker', 'input_file', <para>Before executing a command, <command>scons</command> -performs construction variable interpolation on the strings that make up -the command line of builders. -Variables are introduced by a -<emphasis role="bold">$</emphasis> +performs construction variable interpolation on the string that makes up +the command line of the builder. +Variables are introduced in such strings by a +<literal>$</literal> prefix. -Besides construction variables, scons provides the following -variables for each command execution:</para> +Besides regular construction variables, scons provides the following +special variables for each command execution:</para> <variablelist> <varlistentry> @@ -5901,15 +5932,19 @@ from sources that have <emphasis>not</emphasis> changed since the target was last built.</para> -<para>(Note that the above variables are reserved -and may not be set in a construction environment.)</para> - </listitem> </varlistentry> </variablelist> -<para>For example, given the construction variable CC='cc', targets=['foo'], and -sources=['foo.c', 'bar.c']:</para> +<para>Note that the above variables are reserved +and may not be set in a construction environment.</para> + +<para>For example, given the construction variables +<literal>CC='cc'</literal>, +<literal>targets=['foo']</literal> +and +<literal>sources=['foo.c', 'bar.c']</literal>: +</para> <literallayout class="monospaced"> action='$CC -c -o $TARGET $SOURCES' @@ -5921,8 +5956,10 @@ action='$CC -c -o $TARGET $SOURCES' cc -c -o foo foo.c bar.c </literallayout> -<para>Variable names may be surrounded by curly braces ({}) -to separate the name from the trailing characters. +<para>Variable names may be surrounded by curly braces +<emphasis role="bold">{ }</emphasis> +to separate the name from surrounding characters which +are not part of the name. Within the curly braces, a variable name may have a Python slice subscript appended to select one or more items from a list. @@ -6085,20 +6122,42 @@ may be a callable Python function associated with a construction variable in the environment. The function should -take four arguments: -<emphasis>target</emphasis> -- a list of target nodes, -<emphasis>source</emphasis> -- a list of source nodes, -<emphasis>env</emphasis> -- the construction environment, -<emphasis>for_signature</emphasis> -- a Boolean value that specifies +accept four arguments: +</para> +<variablelist> + <varlistentry> + <term><replaceable>target</replaceable></term> + <listitem> +<para>a list of target nodes</para> + </listitem> + </varlistentry> + <varlistentry> + <term><replaceable>source</replaceable></term> + <listitem> +<para>a list of source nodes</para> + </listitem> + </varlistentry> + <varlistentry> + <term><replaceable>env</replaceable></term> + <listitem> +<para>the construction environment</para> + </listitem> + </varlistentry> + <varlistentry> + <term><replaceable>for_signature</replaceable></term> + <listitem> +<para>a Boolean value that specifies whether the function is being called -for generating a build signature. +for generating a build signature. </para> + </listitem> + </varlistentry> +</variablelist> + +<para> SCons will insert whatever the called function returns -into the expanded string:</para> +into the expanded string: +</para> <programlisting> def foo(target, source, env, for_signature): @@ -6179,9 +6238,12 @@ echo Last build occurred . > $TARGET <refsect2 id='python_code_substitution'><title>Python Code Substitution</title> -<para>Any python code within -<emphasis role="bold">${</emphasis>-<emphasis role="bold">}</emphasis> -pairs gets evaluated by python 'eval', with the python globals set to +<para> +Any Python code within curly braces +<emphasis role="bold">{ }</emphasis> +and introduced by the variable prefix <emphasis role="bold">$</emphasis> +gets evaluated by the Python <function>eval</function> statement, +with the Python globals set to the current environment's set of construction variables. So in the following case:</para> <literallayout class="monospaced"> @@ -6197,14 +6259,20 @@ echo FOO > foo.out <literallayout class="monospaced"> echo BAR > foo.out </literallayout> -<para>according to the current value of env['COND'] when the command is -executed. The evaluation occurs when the target is being -built, not when the SConscript is being read. So if env['COND'] is changed +<para>according to the current value of <literal>env['COND']</literal> +when the command is executed. +The evaluation takes place when the target is being +built, not when the SConscript is being read. So if +<literal>env['COND']</literal> is changed later in the SConscript, the final value will be used.</para> -<para>Here's a more interesting example. Note that all of COND, FOO, and -BAR are environment variables, and their values are substituted into -the final command. FOO is a list, so its elements are interpolated +<para>Here's a more interesting example. Note that all of +<envar>COND</envar>, +<envar>FOO</envar>, +and +<envar>BAR</envar> are construction variables, +and their values are substituted into the final command. +<envar>FOO</envar> is a list, so its elements are interpolated separated by spaces.</para> <literallayout class="monospaced"> @@ -6315,7 +6383,8 @@ might not exist argument is the construction environment for the scan. Fetch values from it using the <emphasis role="bold">env.Dictionary()</emphasis> -method.</para> +method or using the key lookup operator +directly on the construction environment.</para> <para>The <emphasis role="bold">path</emphasis> @@ -6551,9 +6620,10 @@ do this, in part, by sharing an ability to interpret UNIX-like path names. For example, the Cygwin tools will internally translate a Cygwin path name -like /cygdrive/c/mydir +like <filename>/cygdrive/c/mydir</filename> to an equivalent Windows pathname -of C:/mydir (equivalent to C:\mydir).</para> +of <filename>C:/mydir</filename> (equivalent to <filename>C:\mydir</filename>). +</para> <para>Versions of Python that are built for native Windows execution, @@ -6561,7 +6631,8 @@ such as the python.org and ActiveState versions, do not have the Cygwin path name semantics. This means that using a native Windows version of Python to build compiled programs using Cygwin tools -(such as gcc, bison, and flex) +(such as <command>gcc</command>, <command>bison</command>, +and <command>flex</command>) may yield unpredictable results. "Mixing and matching" in this way can be made to work, @@ -6771,7 +6842,7 @@ env['BUILDERS]['PDFBuilder'] = bld <refsect2 id='defining_your_own_scanner_object'><title>Defining Your Own Scanner Object</title> -<para>The following example shows an extremely simple scanner (the +<para>The following example shows adding an extremely simple scanner (the <emphasis role="bold">kfile_scan</emphasis>() function) that doesn't use a search path at all @@ -6796,8 +6867,10 @@ kscan = Scanner(name = 'kfile', function = kfile_scan, argument = None, skeys = ['.k']) -scanners = Environment().Dictionary('SCANNERS') -env = Environment(SCANNERS = scanners + [kscan]) + +scanners = DefaultEnvironment()['SCANNERS'] +scanners.append(kscan) +env = Environment(SCANNERS=scanners) env.Command('foo', 'foo.k', 'kprocess < $SOURCES > $TARGET') @@ -6814,7 +6887,8 @@ you can use the function of your current Environment in order to create nodes on the fly from a sequence of file names with relative paths.</para> -<para>Here is a similar but more complete example that searches +<para>Here is a similar but more complete example that adds +a scanner which searches a path of directories (specified as the <emphasis role="bold">MYPATH</emphasis> @@ -6840,15 +6914,16 @@ def my_scan(node, env, path, arg): break return env.File(results) -scanner = Scanner(name = 'myscanner', - function = my_scan, - argument = None, - skeys = ['.x'], - path_function = FindPathDirs('MYPATH') +scanner = Scanner(name='myscanner', + function=my_scan, + argument=None, + skeys=['.x'], + path_function=FindPathDirs('MYPATH') ) -scanners = Environment().Dictionary('SCANNERS') -env = Environment(SCANNERS = scanners + [scanner], - MYPATH = ['incs']) + +scanners = DefaultEnvironment()['SCANNERS'] +scanners.append(scanner) +env = Environment(SCANNERS=scanners, MYPATH=['incs']) env.Command('foo', 'foo.x', 'xprocess < $SOURCES > $TARGET') </programlisting> @@ -6861,8 +6936,8 @@ that will return a list of directories specified in the <emphasis role="bold">$MYPATH</emphasis> construction variable. It lets SCons detect the file -<emphasis role="bold">incs/foo.inc</emphasis> -, even if +<emphasis role="bold">incs/foo.inc</emphasis>, +even if <emphasis role="bold">foo.x</emphasis> contains the line <emphasis role="bold">include foo.inc</emphasis> @@ -6883,17 +6958,18 @@ def pf(env, dir, target, source, arg): results.append(top_dir + os.sep + p) return results -scanner = Scanner(name = 'myscanner', - function = my_scan, - argument = None, - skeys = ['.x'], - path_function = pf +scanner = Scanner(name='myscanner', + function=my_scan, + argument=None, + skeys=['.x'], + path_function=pf ) </programlisting> </refsect2> -<refsect2 id='creating_a_hierarchical_build'><title>Creating a Hierarchical Build</title> +<refsect2 id='creating_a_hierarchical_build'> +<title>Creating a Hierarchical Build</title> <para>Notice that the file names specified in a subdirectory's SConscript @@ -7126,22 +7202,62 @@ env.Program('MyApp', ['Foo.cpp', 'Bar.cpp']) </refsect1> <refsect1 id='environment'><title>ENVIRONMENT</title> + +<para>In general, &scons; is not controlled by environment +variables set in the shell used to invoke it, leaving it +up to the SConscript file author to import those if desired. +However the following variables are imported by +&scons; itself if set: +</para> + <variablelist> <varlistentry> - <term>SCONS_LIB_DIR</term> - <listitem> -<para>Specifies the directory that contains the SCons Python module directory -(e.g. /home/aroach/scons-src-0.01/src/engine).</para> + <term>SCONS_LIB_DIR</term> + <listitem> +<para>Specifies the directory that contains the &scons; +Python module directory (for example, +<filename>/home/aroach/scons-src-0.01/src/engine</filename>).</para> + </listitem> + </varlistentry> - </listitem> + <varlistentry> + <term>SCONSFLAGS</term> + <listitem> +<para>A string of options that will be used by &scons; +in addition to those passed on the command line.</para> + </listitem> </varlistentry> + <varlistentry> - <term>SCONSFLAGS</term> - <listitem> -<para>A string of options that will be used by scons in addition to those passed -on the command line.</para> + <term>SCONS_CACHE_MSVC_CONFIG</term> + <listitem> +<para>(Windows only). If set, save the shell environment variables +generated when setting up the Microsoft Visual C++ compiler +(and/or Build Tools) to a file to give these settings, +which are expensive to generate, persistence +across &scons; invocations. +Use of this option is primarily intended to aid performance +in tightly controlled Continuous Integration setups.</para> + +<para>If set to a True-like value (<literal>"1"</literal>, +<literal>"true"</literal> or +<literal>"True"</literal>) will cache to a file named +<filename>.scons_msvc_cache</filename> in the user's home directory. +If set to a pathname, will use that pathname for the cache.</para> + +<para>Note: use this cache with caution as it +might be somewhat fragile: while each major toolset version +(e.g. Visual Studio 2017 vs 2019) and architecture pair will get separate +cache entries, if toolset updates cause a change +to settings within a given release series, &scons; will not +detect the change and will reuse old settings. +Remove the cache file in case of problems with this. +&scons; will ignore failures reading or writing the file +and will silently revert to non-cached behavior in such cases.</para> + +<para>Since &scons; 3.1.</para> - </listitem> + </listitem> </varlistentry> </variablelist> </refsect1> @@ -7157,8 +7273,9 @@ source code.</para> </refsect1> <refsect1 id='authors'><title>AUTHORS</title> -<para>Originally: Steven Knight <knight@baldmt.com> and Anthony Roach <aroach@electriceyeball.com> -Since 2010: The SCons Development Team <scons-dev@scons.org> +<para>Originally: Steven Knight <email>knight@baldmt.com</email> +and Anthony Roach <email>aroach@electriceyeball.com</email>. +Since 2010: The SCons Development Team <email>scons-dev@scons.org</email>. </para> </refsect1> </refentry> diff --git a/doc/scons.mod b/doc/scons.mod index 77fa39b..3e843a0 100644 --- a/doc/scons.mod +++ b/doc/scons.mod @@ -212,6 +212,7 @@ <!ENTITY Import "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Import</function>"> <!ENTITY Install "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Install</function>"> <!ENTITY InstallAs "<function xmlns='http://www.scons.org/dbxsd/v1.0'>InstallAs</function>"> +<!ENTITY InstallVersionedLib "<function xmlns='http://www.scons.org/dbxsd/v1.0'>InstallVersionedLib</function>"> <!ENTITY Link "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Link</function>"> <!ENTITY ListOption "<function xmlns='http://www.scons.org/dbxsd/v1.0'>ListOption</function>"> <!ENTITY ListVariable "<function xmlns='http://www.scons.org/dbxsd/v1.0'>ListVariable</function>"> @@ -259,11 +260,8 @@ <!ENTITY SetDefault "<function xmlns='http://www.scons.org/dbxsd/v1.0'>SetDefault</function>"> <!ENTITY SetOption "<function xmlns='http://www.scons.org/dbxsd/v1.0'>SetOption</function>"> <!ENTITY SideEffect "<function xmlns='http://www.scons.org/dbxsd/v1.0'>SideEffect</function>"> -<!ENTITY SourceSignature "<function xmlns='http://www.scons.org/dbxsd/v1.0'>SourceSignature</function>"> -<!ENTITY SourceSignatures "<function xmlns='http://www.scons.org/dbxsd/v1.0'>SourceSignatures</function>"> <!ENTITY Split "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Split</function>"> <!ENTITY Tag "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Tag</function>"> -<!ENTITY TargetSignatures "<function xmlns='http://www.scons.org/dbxsd/v1.0'>TargetSignatures</function>"> <!ENTITY Task "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Task</function>"> <!ENTITY Touch "<function xmlns='http://www.scons.org/dbxsd/v1.0'>Touch</function>"> <!ENTITY UnknownOptions "<function xmlns='http://www.scons.org/dbxsd/v1.0'>UnknownOptions</function>"> diff --git a/doc/user/builders-writing.xml b/doc/user/builders-writing.xml index ce95128..e20e99b 100644 --- a/doc/user/builders-writing.xml +++ b/doc/user/builders-writing.xml @@ -453,7 +453,7 @@ def build_function(target, source, env): A list of Node objects representing the target or targets to be - built by this builder function. + built by this function. The file names of these target(s) may be extracted using the Python &str; function. @@ -469,7 +469,7 @@ def build_function(target, source, env): A list of Node objects representing the sources to be - used by this builder function to build the targets. + used by this function to build the targets. The file names of these source(s) may be extracted using the Python &str; function. @@ -484,7 +484,7 @@ def build_function(target, source, env): <para> The &consenv; used for building the target(s). - The builder function may use any of the + The function may use any of the environment's construction variables in any way to affect how it builds the targets. @@ -496,13 +496,14 @@ def build_function(target, source, env): <para> - The builder function must - return a <literal>0</literal> or <literal>None</literal> value - if the target(s) are built successfully. - The builder function - may raise an exception - or return any non-zero value - to indicate that the build is unsuccessful. + The function will be constructed as a SCons FunctionAction and + must return a <literal>0</literal> or <literal>None</literal> + value if the target(s) are built successfully. The function may + raise an exception or return any non-zero value to indicate that + the build is unsuccessful. + + For more information on Actions see the Action Objects section of + the man page. </para> diff --git a/doc/user/depends.xml b/doc/user/depends.xml index 7947900..5a78eb5 100644 --- a/doc/user/depends.xml +++ b/doc/user/depends.xml @@ -765,184 +765,6 @@ int main() { printf("Hello, world!\n"); } </para> - <section> - <title>The &SourceSignatures; Function</title> - - <para> - - The &SourceSignatures; function is fairly straightforward, - and supports two different argument values - to configure whether source file changes should be decided - using MD5 signatures: - - </para> - - <sconstruct> -Program('hello.c') -SourceSignatures('MD5') - </sconstruct> - - <para> - - Or using time stamps: - - </para> - - <sconstruct> -Program('hello.c') -SourceSignatures('timestamp') - </sconstruct> - - <para> - - These are roughly equivalent to specifying - <function>Decider('MD5')</function> - or - <function>Decider('timestamp-match')</function>, - respectively, - although it only affects how SCons makes - decisions about dependencies on - <emphasis>source</emphasis> files--that is, - files that are not built from any other files. - - </para> - - </section> - - <section> - <title>The &TargetSignatures; Function</title> - - <para> - - The &TargetSignatures; function - specifies how &SCons; decides - when a target file has changed - <emphasis>when it is used as a - dependency of (input to) another target</emphasis>--that is, - the &TargetSignatures; function configures - how the signatures of "intermediate" target files - are used when deciding if a "downstream" target file - must be rebuilt. - <footnote><para> - This easily-overlooked distinction between - how &SCons; decides if the target itself must be rebuilt - and how the target is then used to decide if a different - target must be rebuilt is one of the confusing - things that has led to the &TargetSignatures; - and &SourceSignatures; functions being - replaced by the simpler &Decider; function. - </para></footnote> - - </para> - - <para> - - The &TargetSignatures; function supports the same - <literal>'MD5'</literal> and <literal>'timestamp'</literal> - argument values that are supported by the &SourceSignatures;, - with the same meanings, but applied to target files. - That is, in the example: - - </para> - - <sconstruct> -Program('hello.c') -TargetSignatures('MD5') - </sconstruct> - - <para> - - The MD5 checksum of the &hello_o; target file - will be used to decide if it has changed since the last - time the "downstream" &hello; target file was built. - And in the example: - - </para> - - <sconstruct> -Program('hello.c') -TargetSignatures('timestamp') - </sconstruct> - - <para> - - The modification time of the &hello_o; target file - will be used to decide if it has changed since the last - time the "downstream" &hello; target file was built. - - </para> - - <para> - - The &TargetSignatures; function supports - two additional argument values: - <literal>'source'</literal> and <literal>'build'</literal>. - The <literal>'source'</literal> argument - specifies that decisions involving - whether target files have changed - since a previous build - should use the same behavior - for the decisions configured for source files - (using the &SourceSignatures; function). - So in the example: - - </para> - - <sconstruct> -Program('hello.c') -TargetSignatures('source') -SourceSignatures('timestamp') - </sconstruct> - - <para> - - All files, both targets and sources, - will use modification times - when deciding if an input file - has changed since the last - time a target was built. - - </para> - - <para> - - Lastly, the <literal>'build'</literal> argument - specifies that &SCons; should examine - the build status of a target file - and always rebuild a "downstream" target - if the target file was itself rebuilt, - without re-examining the contents or timestamp - of the newly-built target file. - If the target file was not rebuilt during - this &scons; invocation, - then the target file will be examined - the same way as configured by - the &SourceSignature; call - to decide if it has changed. - - </para> - - <para> - - This mimics the behavior of - <literal>build signatures</literal> - in earlier versions of &SCons;. - A &buildsignature; re-combined - signatures of all the input files - that went into making the target file, - so that the target file itself - did not need to have its contents read - to compute an MD5 signature. - This can improve performance for some configurations, - but is generally not as effective as using - <literal>Decider('MD5-timestamp')</literal>. - - </para> - - </section> - - </section> - <section> <title>Implicit Dependencies: The &cv-CPPPATH; Construction Variable</title> diff --git a/doc/user/environments.xml b/doc/user/environments.xml index 65eed72..0b246d2 100644 --- a/doc/user/environments.xml +++ b/doc/user/environments.xml @@ -618,7 +618,7 @@ int main() { } <para> - You can fetch individual construction variables + You can fetch individual &consvars; using the normal syntax for accessing individual named items in a Python dictionary: @@ -645,20 +645,21 @@ print("CC is: %s"%env['CC']) <para> - A construction environment, however, - is actually an object with associated methods, etc. + A &consenv; + is actually an object with associated methods and + attributes. If you want to have direct access to only the - dictionary of construction variables, + dictionary of &consvars; you can fetch this using the &Dictionary; method: </para> <scons_example name="environments_ex6b"> <file name="SConstruct" printme="1"> -env = Environment(FOO = 'foo', BAR = 'bar') -dict = env.Dictionary() +env = Environment(FOO='foo', BAR='bar') +cvars = env.Dictionary() for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']: - print("key = %s, value = %s" % (key, dict[key])) + print("key = %s, value = %s" % (key, cvars[key])) </file> </scons_example> @@ -687,7 +688,7 @@ for key in ['OBJSUFFIX', 'LIBSUFFIX', 'PROGSUFFIX']: <para> If you want to loop and print the values of - all of the construction variables in a construction environment, + all of the &consvars; in a &consenv;, the Python code to do that in sorted order might look something like: </para> @@ -698,6 +699,16 @@ for item in sorted(env.Dictionary().items()): print("construction variable = '%s', value = '%s'" % item) </sconstruct> + <para> + It should be noted that for the previous example, there is actually + a &consenv; method that does the same thing more simply, + and tries to format the output nicely as well: + </para> + <sconstruct> +env = Environment() +print(env.Dump()) + </sconstruct> + </section> <section> @@ -706,10 +717,10 @@ for item in sorted(env.Dictionary().items()): <para> Another way to get information from - a construction environment + a &consenv; is to use the &subst; method on a string containing <literal>$</literal> expansions - of construction variable names. + of &consvar; names. As a simple example, the example from the previous section that used @@ -728,7 +739,7 @@ print("CC is: %s"%env.subst('$CC')) One advantage of using &subst; to expand strings is - that construction variables + that &consvars; in the result get re-expanded until there are no expansions left in the string. So a simple fetch of a value like diff --git a/doc/user/install.xml b/doc/user/install.xml index 8c224d4..db87521 100644 --- a/doc/user/install.xml +++ b/doc/user/install.xml @@ -2,7 +2,7 @@ <!DOCTYPE sconsdoc [ <!ENTITY % scons SYSTEM "../scons.mod"> %scons; - + <!ENTITY % builders-mod SYSTEM "../generated/builders.mod"> %builders-mod; <!ENTITY % functions-mod SYSTEM "../generated/functions.mod"> @@ -11,7 +11,7 @@ %tools-mod; <!ENTITY % variables-mod SYSTEM "../generated/variables.mod"> %variables-mod; - + ]> <chapter id="chap-install" @@ -50,7 +50,7 @@ Once a program is built, it is often appropriate to install it in another directory for public use. - You use the &Install; method + You use the &Install; method to arrange for a program, or any other file, to be copied into a destination directory: @@ -226,7 +226,7 @@ int main() { printf("Hello, world!\n"); } <para> - Lastly, if you have multiple files that all + If you have multiple files that all need to be installed with different file names, you can either call the &InstallAs; function multiple times, or as a shorthand, @@ -268,4 +268,66 @@ int main() { printf("Goodbye, world!\n"); } </section> + <section> + <title>Installing a Shared Library</title> + + <para> + If a shared library is created with the + &cv-link-SHLIBVERSION; variable set, + &scons; will create symbolic links as needed based on that + variable. To properly install such a library including the + symbolic links, use the &InstallVersionedLib; function. + </para> + + <para> + For example, on a Linux system, this instruction: + </para> + + <sconstruct> +foo = env.SharedLibrary(target="foo", source="foo.c", SHLIBVERSION="1.2.3") + </sconstruct> + + <para> + Will produce a shared library + <filename>libfoo.so.1.2.3</filename> + and symbolic links + <filename>libfoo.so</filename> and + <filename>libfoo.so.1</filename> + which point to + <filename>libfoo.so.1.2.3</filename>. + You can use the Node returned by the &SharedLibrary; + builder in order to install the library and its + symbolic links in one go without having to list + them individually: + </para> + + <sconstruct> +env.InstallVersionedLib(target="lib", source=foo) + </sconstruct> + +<!-- didn't get this to illustrate what I expected: example reports + installing lib without version, while manual effort has it: + + <scons_example name="install_ex6"> + <file name="SConstruct" printme="1"> +env = Environment() +foo = env.SharedLibrary(target="foo", source="foo.c", SHLIBVERSION="1.2.3") +ins = env.InstallVersionedLib(target="lib", source=foo) +env.Alias('install', ins) + </file> + <file name="foo.c"> +int call_foo() { + printf("Hello world"); + return(0); +} + </file> + </scons_example> + + <scons_output example="install_ex6" suffix="1"> + <scons_output_command>scons -Q install</scons_output_command> + </scons_output> +--> + + </section> + </chapter> diff --git a/doc/user/output.xml b/doc/user/output.xml index ca4707d..f9e1a98 100644 --- a/doc/user/output.xml +++ b/doc/user/output.xml @@ -309,7 +309,7 @@ Linking foo <scons_example name="output_COMSTR-VERBOSE"> <file name="SConstruct" printme="1"> env = Environment() -if ARGUMENTS.get('VERBOSE') != "1': +if ARGUMENTS.get('VERBOSE') != '1': env['CCCOMSTR'] = "Compiling $TARGET" env['LINKCOMSTR'] = "Linking $TARGET" env.Program('foo.c') @@ -31,8 +31,8 @@ Options: -n --no-exec No execute, just print command lines. --nopipefiles Do not use the "file pipe" workaround for Popen() for starting tests. WARNING: use only when too much - file traffic is giving you trouble AND you can be - sure that none of your tests create output >65K + file traffic is giving you trouble AND you can be + sure that none of your tests create output >65K chars! You might run into some deadlocks else. -o --output FILE Save the output from a test run to the log file. -P PYTHON Use the specified Python interpreter. @@ -71,7 +71,6 @@ Environment Variables: from __future__ import print_function - import getopt import glob import os @@ -367,7 +366,7 @@ else: return (spawned_stderr, spawned_stdout, p.wait()) -class Base(object): +class RuntestBase(object): def __init__(self, path, num, spe=None): self.path = path self.num = num @@ -381,7 +380,7 @@ class Base(object): self.status = None -class SystemExecutor(Base): +class SystemExecutor(RuntestBase): def execute(self): self.stderr, self.stdout, s = spawn_it(self.command_args) self.status = s @@ -389,7 +388,7 @@ class SystemExecutor(Base): sys.stdout.write("Unexpected exit status %d\n" % s) -class PopenExecutor(Base): +class PopenExecutor(RuntestBase): # For an explanation of the following 'if ... else' # and the 'allow_pipe_files' option, please check out the # definition of spawn_it() above. @@ -639,15 +638,14 @@ else: # Each test path specifies a test file, or a directory to search for # SCons tests. SCons code layout assumes that any file under the 'src' - # subdirectory that ends with 'Tests.py' is a unit test, and Python + # subdirectory that ends with 'Tests.py' is a unit test, and any Python # script (*.py) under the 'test' subdirectory an end-to-end test. + # We need to track these because they are invoked differently. # # Note that there are some tests under 'src' that *begin* with # 'test_', but they're packaging and installation tests, not # functional tests, so we don't execute them by default. (They can - # still be executed by hand, though, and are routinely executed - # by the Aegis packaging build to make sure that we're building - # things correctly.) + # still be executed by hand, though). if options.all: testpaths = ['src', 'test'] @@ -680,7 +678,7 @@ else: tests.extend(unittests) tests.extend(endtests) tests.sort() - + if not tests: sys.stderr.write(usagestr + """ runtest.py: No tests were found. @@ -733,37 +731,46 @@ else: total_start_time = time_func() total_num_tests = len(tests) -tests_completed = 0 -tests_passing = 0 -tests_failing = 0 -def log_result(t, io_lock): - global tests_completed, tests_passing, tests_failing - tests_completed += 1 - if t.status == 0: - tests_passing += 1 - else: - tests_failing += 1 +def log_result(t, io_lock=None): + """ log the result of a test. + + "log" in this case means writing to stdout. Since we might be + called from from any of several different threads (multi-job run), + we need to lock access to the log to avoid interleaving. The same + would apply if output was a file. + + :param t: a completed testcase + :type t: Test + :param io_lock: + :type io_lock: threading.Lock + """ + + # there is no lock in single-job run, which includes + # running test/runtest tests from multi-job run, so check. if io_lock: io_lock.acquire() - if suppress_output or catch_output: - sys.stdout.write(t.headline) - if not suppress_output: - if t.stdout: - print(t.stdout) - if t.stderr: - print(t.stderr) - print_time_func("Test execution time: %.1f seconds\n", t.test_time) - if io_lock: - io_lock.release() + try: + if suppress_output or catch_output: + sys.stdout.write(t.headline) + if not suppress_output: + if t.stdout: + print(t.stdout) + if t.stderr: + print(t.stderr) + print_time_func("Test execution time: %.1f seconds\n", t.test_time) + finally: + if io_lock: + io_lock.release() + if quit_on_failure and t.status == 1: print("Exiting due to error") print(t.status) sys.exit(1) -def run_test(t, io_lock, run_async=True): +def run_test(t, io_lock=None, run_async=True): t.headline = "" command_args = [] if sys.version_info[0] < 3: @@ -797,39 +804,39 @@ def run_test(t, io_lock, run_async=True): test_start_time = time_func() if execute_tests: t.execute() + t.test_time = time_func() - test_start_time - log_result(t, io_lock) + log_result(t, io_lock=io_lock) class RunTest(threading.Thread): - def __init__(self, queue, io_lock): - threading.Thread.__init__(self) + def __init__(self, queue=None, io_lock=None, + group=None, target=None, name=None, args=(), kwargs=None): + super(RunTest, self).__init__(group=group, target=target, name=name) self.queue = queue self.io_lock = io_lock def run(self): - while True: - t = self.queue.get() - run_test(t, self.io_lock, True) + for t in iter(self.queue.get, None): + run_test(t, io_lock=self.io_lock, run_async=True) self.queue.task_done() if jobs > 1: - print("Running tests using %d jobs"%jobs) - # Start worker threads + print("Running tests using %d jobs" % jobs) queue = Queue() + for t in tests: + queue.put(t) io_lock = threading.Lock() - for _ in range(jobs): - t = RunTest(queue, io_lock) + # Start worker threads to consume the queue + threads = [RunTest(queue=queue, io_lock=io_lock) for _ in range(jobs)] + for t in threads: t.daemon = True t.start() - # Give tasks to workers - for t in tests: - queue.put(t) - # wait until all done + # wait on the queue rather than the individual threads queue.join() else: for t in tests: - run_test(t, None, False) + run_test(t, io_lock=None, run_async=False) # --- all tests are complete by the time we get here --- if len(tests) > 0: diff --git a/src/Announce.txt b/src/Announce.txt index 2ceb8bc..1359696 100755 --- a/src/Announce.txt +++ b/src/Announce.txt @@ -18,7 +18,7 @@ So that everyone using SCons can help each other learn how to use it more effectively, please go to http://scons.org/lists.html#users to sign up for the scons-users mailing list. -RELEASE 3.1.0 - Mon, 20 Jul 2019 16:59:23 -0700 +RELEASE VERSION/DATE TO BE FILLED IN LATER Please consult the RELEASE.txt file for a summary of changes since the last release and consult the CHANGES.txt file for complete a list of changes diff --git a/src/CHANGES.txt b/src/CHANGES.txt index a23140c..af448d5 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -4,6 +4,58 @@ Change Log +RELEASE VERSION/DATE TO BE FILLED IN LATER + + From Mathew Robinson: + + - Improved threading performance by ensuring NodeInfo is shared + across threads. Results in ~13% improvement for parallel builds + (-j# > 1) with many shared nodes. + + From Mats Wichmann + - Replace instances of string find method with "in" checks where + the index from find() was not used. + - CmdStringHolder fix from issue #3428 + - Turn previously deprecated debug options into failures: + --debug=tree, --debug=dtree, --debug=stree, --debug=nomemoizer. + - Experimental New Feature: Enable caching MSVC configuration + If SCONS_CACHE_MSVC_CONFIG shell environment variable is set, + SCons will cache the results of past calls to vcvarsall.bat to + a file; integrates with existing memoizing of such vars. + On vs2019 saves 5+ seconds per SCons invocation, which really + helps test suite runs. + - Remove deprecated SourceSignatures, TargetSignatures + + From Jacek Kuczera: + - Fix CheckFunc detection code for Visual 2019. Some functions + (e.g. memmove) were incorrectly recognized as not available. + + From Jakub Kulik + - Fix subprocess result bytes not being decoded in SunOS/Solaris related tools. + + From Edoardo Bezzeccheri + - Added debug option "action_timestamps" which outputs to stdout the absolute start and end time for each target. + +RELEASE 3.1.1 - Mon, 07 Aug 2019 20:09:12 -0500 + + From William Deegan: + - Remove obsoleted references to DeciderNeedsNode which could cause crash when using --debug=explain + + From Jason Kenny + - Add Fix and test for crash in 3.1.0 when using Decider('MD5-timestamp') and --debug=explain + + From Ben Reed: + - Added -fmerge-all-constants to flags that get included in both CCFLAGS and LINKFLAGS. + + From Mathew Robinson: + - Fix issue #3415 - Update remaining usages of EnvironmentError to SConsEnvironmentError + this patch fixes issues introduced in 3.1.0 where any of the + following would cause SCons to error and exit: + - CacheDir not write-able + - JSON encoding errors for CacheDir config + - JSON decoding errors for CacheDir config + + RELEASE 3.1.0 - Mon, 20 Jul 2019 16:59:23 -0700 From Joseph Brill: @@ -13,7 +65,7 @@ RELEASE 3.1.0 - Mon, 20 Jul 2019 16:59:23 -0700 From William Deegan: - Enhanced --debug=explain output. Now the separate components of the dependency list are split up as follows: - + scons: rebuilding `file3' because: the dependency order changed: ->Sources @@ -84,7 +136,7 @@ RELEASE 3.1.0 - Mon, 20 Jul 2019 16:59:23 -0700 - More fixes for newer Java versions (since 9): handle new jdk directory naming (jdk-X.Y instead of jdkX.Y) on Windows; handle two-digit major version. Docstrings improved. - - Fixups for pylint: exception types, redefined functions, + - Fixups for pylint: exception types, redefined functions, globals, etc. Some old code removed to resolve issues (hashlib is always present on modern Pythons; no longer need the code for 2.5-and-earlier optparse). cmp is not a builtin function in Py3, @@ -94,7 +146,7 @@ RELEASE 3.1.0 - Mon, 20 Jul 2019 16:59:23 -0700 - Add a PY3-only function for setting up the cachedir that should be less prone to races. Add a hack to the PY2 version (from Issue #3351) to be less prone to a race in the check for old-style cache. - - Fix coding error in docbook tool only exercised when using python lxml + - Fix coding error in docbook tool only exercised when using python lxml - Recognize two additional GNU compiler header directory options in ParseFlags: -iquote and -idirafter. - Fix more re patterns that contain \ but not specified as raw strings @@ -141,7 +193,7 @@ From Daniel Moody: From Bernhard M. Wiedemann: - Do not store build host+user name if reproducible builds are wanted - + RELEASE 3.0.4 - Mon, 20 Jan 2019 22:49:27 +0000 @@ -209,9 +261,9 @@ RELEASE 3.0.2 - Mon, 31 Dec 2018 16:00:12 -0700 - Fix GH Issue #2580 - # in FRAMEWORKPATH doesn't get properly expanded. The # is left in the command line. - Fix issue #2980 with credit to Piotr Bartosik (and William Blevins). This is an issue where using - TimeStamp-MD5 Decider and CacheDir can yield incorrect md5's being written into the .sconsign. - The difference between Piotr Bartosik's patch and the current code is that the more complicated - creation of file to csig map is only done when the count of children for the current node doesn't + TimeStamp-MD5 Decider and CacheDir can yield incorrect md5's being written into the .sconsign. + The difference between Piotr Bartosik's patch and the current code is that the more complicated + creation of file to csig map is only done when the count of children for the current node doesn't match the previous count which is loaded from the sconsign. - Fix issue # 3106 MSVC if using MSVC_BATCH and target dir had a space would fail due to quirk in MSVC's handling of escaped targetdirs when batch compiling. @@ -247,7 +299,7 @@ RELEASE 3.0.2 - Mon, 31 Dec 2018 16:00:12 -0700 - Removed unused --warn options from the man page and source code. From Arda Fu - - Fix cpp scanner regex logic to treat ifndef for py3.5+. Previously it was + - Fix cpp scanner regex logic to treat ifndef for py3.5+. Previously it was not properly differentiating between if, ifdef, and ifndef. From Philipp Maierhöfer @@ -258,7 +310,7 @@ RELEASE 3.0.2 - Mon, 31 Dec 2018 16:00:12 -0700 From Matthew Marinets: - Fixed an issue that caused the Java emitter to incorrectly parse arguments to constructors that implemented a class. - + From Fredrik Medley: - Fix exception when printing of EnviromentError messages. Specifically, this fixes error reporting of the race condition when @@ -379,7 +431,7 @@ RELEASE 3.0.2 - Mon, 31 Dec 2018 16:00:12 -0700 filter type -> list in ipk From Bernhard M. Wiedemann: - - Update SCons' internal scons build logic to allow overriding build date + - Update SCons' internal scons build logic to allow overriding build date with SOURCE_DATE_EPOCH for SCons itself. - Change the datestamps in SCons' docs and embedded in code use ISO 8601 format and UTC diff --git a/src/LICENSE.txt b/src/LICENSE.txt index 7aa2a09..1641aba 100644 --- a/src/LICENSE.txt +++ b/src/LICENSE.txt @@ -1,3 +1,5 @@ +MIT License + __COPYRIGHT__ Permission is hereby granted, free of charge, to any person obtaining diff --git a/src/RELEASE.txt b/src/RELEASE.txt index 5927ef8..17e698f 100755 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -1,81 +1,73 @@ - A new SCons checkpoint release, 3.1.0, is now available + A new SCons checkpoint release, 3.1.2.alpha.yyyymmdd, is now available on the SCons download page: https://scons.org/pages/download.html - Here is a summary of the changes since 3.0.5: + XXX The primary purpose of this release ... XXX + + A SCons "checkpoint release" is intended to provide early access to + new features so they can be tested in the field before being released + for adoption by other software distributions. + + Note that a checkpoint release is developed using the same test-driven + development methodology as all SCons releases. Existing SCons + functionality should all work as it does in previous releases (except + for any changes identified in the release notes) and early adopters + should be able to use a checkpoint release safely for production work + with existing SConscript files. If not, it represents not only a bug + in SCons but also a hole in the regression test suite, and we want to + hear about it. + + New features may be more lightly tested than in past releases, + especially as concerns their interaction with all of the other + functionality in SCons. We are especially interested in hearing bug + reports about new functionality. + + We do not recommend that downstream distributions (Debian, Fedora, + etc.) package a checkpoint release, mainly to avoid confusing the + "public" release numbering with the long checkpoint release names. + + Here is a summary of the changes since 1.3.0: NEW FUNCTIONALITY - - Added variable TEMPFILEARGJOIN to specify how to join arguments written - to temp files used when command lines exceed MAXLINELENGTH when the - command uses $TEMPFILE{...} - - Support for MSVC 2019 - - Upgraded and improved Visual Studio solution/project generation code using the MSVSProject builder. - - Added support for Visual Studio 2017 and 2019. - - Added support for the following per-variant parameters to the builder: - - cpppaths: Provides per-variant include paths. - - cppdefines: Provides per-variant preprocessor definitions. + - List new features (presumably why a checkpoint is being released) + + DEPRECATED FUNCTIONALITY + - List anything that's been deprecated since the last release CHANGED/ENHANCED EXISTING FUNCTIONALITY - - Fix performance degradation for MD5-timestamp decider. NOTE: This changes the Decider() function arguments. - From: - def my_decider(dependency, target, prev_ni): - To: - def my_decider(dependency, target, prev_ni, repo_node): - Where repo_node is the repository (or other) node to use to check if the node is out of date instead of dependency. - - - Enhanced --debug=explain output. Now the separate components of the dependency list are split up - as follows: - - scons: rebuilding `file3' because: - the dependency order changed: - ->Sources - Old:xxx New:zzz - Old:yyy New:yyy - Old:zzz New:xxx - ->Depends - ->Implicit - Old:/usr/bin/python New:/usr/bin/python - - - Changed: Pseudo-builders now inherit OverrideEnvironments. For - example when calling a pseudo-builder from another - pseudo-builder the override variables passed to the first - pseudo-builder call had to be explicitly passed on to the - internal pseudo-builder call. Now the second pseudo-builder call - will automatically inherit these override values. + - List modifications to existing features, where the previous behavior + wouldn't actually be considered a bug FIXES - - Fix Issue #3350 - SCons Exception EnvironmentError is conflicting with Python's EnvironmentError. - - Fix spurious rebuilds on second build for cases where builder has > 1 target and the source file - is generated. This was causing the > 1th target to not have it's implicit list cleared when the source - file was actually built, leaving an implicit list similar to follows for 2nd and higher target - ['/usr/bin/python', 'xxx', 'yyy', 'zzz'] - This was getting persisted to SConsign and on rebuild it would be corrected to be similar to this - ['zzz', 'yyy', 'xxx', '/usr/bin/python'] - Which would trigger a rebuild because the order changed. - The fix involved added logic to mark all shared targets as peers and then ensure they're implicit - list is all cleared together. - - Fix Issue #3349 - SCons Exception EnvironmentError is conflicting with Python's EnvironmentError. - Renamed to SConsEnvironmentError - - Fix Issue #3350 - mslink failing when too many objects. This is resolved by adding TEMPFILEARGJOIN variable - which specifies what character to join all the argements output into the tempfile. The default remains a space - when mslink, msvc, or mslib tools are loaded they change the TEMPFILEARGJOIN to be a line separator (\r\n on win32) - - Additional fix to issue #3135 - Also handle 'pure' and 'elemental' type bound procedures - - - Fix handling of Visual Studio Compilers to properly reject any unknown HOST_PLATFORM or TARGET_PLATFORM - - Enable LaTeX scanner to find more than one include per line - + + - List fixes of outright bugs + + IMPROVEMENTS + + - List improvements that wouldn't be visible to the user in the + documentation: performance improvements (describe the circumstances under which they would be observed), or major code cleanups -git shortlog --no-merges -ns 3.0.5..HEAD - 64 William Deegan - 56 Mats Wichmann - 10 Adam Gross - 4 Mathew Robinson - 4 Peter Diener - 3 Lukas Schrangl - 1 Daniel Holth - 1 bdbaddog + PACKAGING + + - List changes in the way SCons is packaged and/or released + + DOCUMENTATION + + - List any significant changes to the documentation (not individual + typo fixes, even if they're mentioned in src/CHANGES.txt to give + the contributor credit) + + DEVELOPMENT + + - List visible changes in the way SCons is developed + + Thanks to CURLY, LARRY, and MOE for their contributions to this release. + Contributors are listed alphabetically by their last name. + +__COPYRIGHT__ +__FILE__ __REVISION__ __DATE__ __DEVELOPER__ diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py index 704b9a5..10c088d 100644 --- a/src/engine/SCons/CacheDir.py +++ b/src/engine/SCons/CacheDir.py @@ -33,6 +33,7 @@ import os import stat import sys +import SCons import SCons.Action import SCons.Warnings from SCons.Util import PY3 @@ -185,7 +186,7 @@ class CacheDir(object): pass except OSError: msg = "Failed to create cache directory " + path - raise SCons.Errors.EnvironmentError(msg) + raise SCons.Errors.SConsEnvironmentError(msg) try: with open(config_file, 'x') as config: @@ -194,14 +195,14 @@ class CacheDir(object): json.dump(self.config, config) except Exception: msg = "Failed to write cache configuration for " + path - raise SCons.Errors.EnvironmentError(msg) + raise SCons.Errors.SConsEnvironmentError(msg) except FileExistsError: try: with open(config_file) as config: self.config = json.load(config) except ValueError: msg = "Failed to read cache configuration for " + path - raise SCons.Errors.EnvironmentError(msg) + raise SCons.Errors.SConsEnvironmentError(msg) def _readconfig2(self, path): diff --git a/src/engine/SCons/CacheDirTests.py b/src/engine/SCons/CacheDirTests.py index ef87746..07c32b4 100644 --- a/src/engine/SCons/CacheDirTests.py +++ b/src/engine/SCons/CacheDirTests.py @@ -27,10 +27,13 @@ import os.path import shutil import sys import unittest +import tempfile +import stat from TestCmd import TestCmd import SCons.CacheDir +from SCons.Util import PY3 built_it = None @@ -112,6 +115,84 @@ class CacheDirTestCase(BaseTestCase): finally: SCons.Util.MD5collect = save_collect +class ExceptionTestCase(unittest.TestCase): + """Test that the correct exceptions are thrown by CacheDir.""" + + # Don't inherit from BaseTestCase, we're by definition trying to + # break things so we really want a clean slate for each test. + def setUp(self): + self.tmpdir = tempfile.mkdtemp() + self._CacheDir = SCons.CacheDir.CacheDir(self.tmpdir) + + def tearDown(self): + shutil.rmtree(self.tmpdir) + + @unittest.skipIf(sys.platform.startswith("win"), "This fixture will not trigger an OSError on Windows") + def test_throws_correct_on_OSError(self): + """Test that the correct error is thrown when cache directory cannot be created.""" + privileged_dir = os.path.join(os.getcwd(), "privileged") + try: + os.mkdir(privileged_dir) + os.chmod(privileged_dir, stat.S_IREAD) + cd = SCons.CacheDir.CacheDir(os.path.join(privileged_dir, "cache")) + assert False, "Should have raised exception and did not" + except SCons.Errors.SConsEnvironmentError as e: + assert str(e) == "Failed to create cache directory {}".format(os.path.join(privileged_dir, "cache")) + finally: + os.chmod(privileged_dir, stat.S_IWRITE | stat.S_IEXEC | stat.S_IREAD) + shutil.rmtree(privileged_dir) + + + def test_throws_correct_when_failed_to_write_configfile(self): + class Unserializable: + """A class which the JSON should not be able to serialize""" + + def __init__(self, oldconfig): + self.something = 1 # Make the object unserializable + # Pretend to be the old config just enough + self.__dict__["prefix_len"] = oldconfig["prefix_len"] + + def __getitem__(self, name, default=None): + if name == "prefix_len": + return self.__dict__["prefix_len"] + else: + return None + + def __setitem__(self, name, value): + self.__dict__[name] = value + + oldconfig = self._CacheDir.config + self._CacheDir.config = Unserializable(oldconfig) + # Remove the config file that got created on object creation + # so that _readconfig* will try to rewrite it + old_config = os.path.join(self._CacheDir.path, "config") + os.remove(old_config) + + try: + if PY3: + self._CacheDir._readconfig3(self._CacheDir.path) + else: + self._CacheDir._readconfig2(self._CacheDir.path) + assert False, "Should have raised exception and did not" + except SCons.Errors.SConsEnvironmentError as e: + assert str(e) == "Failed to write cache configuration for {}".format(self._CacheDir.path) + + def test_raise_environment_error_on_invalid_json(self): + config_file = os.path.join(self._CacheDir.path, "config") + with open(config_file, "r") as cfg: + content = cfg.read() + # This will make JSON load raise a ValueError + content += "{}" + with open(config_file, "w") as cfg: + cfg.write(content) + + try: + # Construct a new cache dir that will try to read the invalid config + new_cache_dir = SCons.CacheDir.CacheDir(self._CacheDir.path) + assert False, "Should have raised exception and did not" + except SCons.Errors.SConsEnvironmentError as e: + assert str(e) == "Failed to read cache configuration for {}".format(self._CacheDir.path) + class FileTestCase(BaseTestCase): """ Test calling CacheDir code through Node.FS.File interfaces. diff --git a/src/engine/SCons/Conftest.py b/src/engine/SCons/Conftest.py index 1163aa3..c24adf8 100644 --- a/src/engine/SCons/Conftest.py +++ b/src/engine/SCons/Conftest.py @@ -290,6 +290,10 @@ char %s();""" % function_name #include <assert.h> %(hdr)s +#if _MSC_VER && !__INTEL_COMPILER + #pragma function(%(name)s) +#endif + int main(void) { #if defined (__stub_%(name)s) || defined (__stub___%(name)s) fail fail fail diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 8d06af7..0e1102e 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -46,7 +46,7 @@ import SCons.Builder import SCons.Debug from SCons.Debug import logInstanceCreation import SCons.Defaults -import SCons.Errors +from SCons.Errors import UserError, BuildError import SCons.Memoize import SCons.Node import SCons.Node.Alias @@ -75,11 +75,6 @@ CalculatorArgs = {} semi_deepcopy = SCons.Util.semi_deepcopy semi_deepcopy_dict = SCons.Util.semi_deepcopy_dict -# Pull UserError into the global name space for the benefit of -# Environment().SourceSignatures(), which has some import statements -# which seem to mess up its ability to reference SCons directly. -UserError = SCons.Errors.UserError - def alias_builder(env, target, source): pass @@ -154,7 +149,7 @@ def _set_BUILDERS(env, key, value): env._dict[key] = bd for k, v in value.items(): if not SCons.Builder.is_a_Builder(v): - raise SCons.Errors.UserError('%s is not a Builder.' % repr(v)) + raise UserError('%s is not a Builder.' % repr(v)) bd.update(value) def _del_SCANNERS(env, key): @@ -431,7 +426,7 @@ class SubstitutionEnvironment(object): # efficient than calling another function or a method. if key not in self._dict \ and not _is_valid_var.match(key): - raise SCons.Errors.UserError("Illegal construction variable `%s'" % key) + raise UserError("Illegal construction variable `%s'" % key) self._dict[key] = value def get(self, key, default=None): @@ -783,13 +778,14 @@ class SubstitutionEnvironment(object): elif arg in ['-mno-cygwin', '-pthread', '-openmp', + '-fmerge-all-constants', '-fopenmp']: dict['CCFLAGS'].append(arg) dict['LINKFLAGS'].append(arg) elif arg == '-mwindows': dict['LINKFLAGS'].append(arg) elif arg[:5] == '-std=': - if arg[5:].find('++')!=-1: + if '++' in arg[5:]: key='CXXFLAGS' else: key='CFLAGS' @@ -1492,8 +1488,14 @@ class Base(SubstitutionEnvironment): self.copy_from_cache = copy_function + def Detect(self, progs): """Return the first available program in progs. + + :param progs: one or more command names to check for + :type progs: str or list + :returns str: first name from progs that can be found. + """ if not SCons.Util.is_List(progs): progs = [ progs ] @@ -1502,7 +1504,17 @@ class Base(SubstitutionEnvironment): if path: return prog return None + def Dictionary(self, *args): + """Return construction variables from an environment. + + :param *args: (optional) variable names to look up + :returns: if args omitted, the dictionary of all constr. vars. + If one arg, the corresponding value is returned. + If more than one arg, a list of values is returned. + :raises KeyError: if any of *args is not in the construction env. + + """ if not args: return self._dict dlist = [self._dict[x] for x in args] @@ -1510,23 +1522,28 @@ class Base(SubstitutionEnvironment): dlist = dlist[0] return dlist - def Dump(self, key = None): - """ - Using the standard Python pretty printer, return the contents of the - scons build environment as a string. - If the key passed in is anything other than None, then that will - be used as an index into the build environment dictionary and - whatever is found there will be fed into the pretty printer. Note - that this key is case sensitive. + def Dump(self, key=None): + """ Return pretty-printed string of construction variables. + + :param key: if None, format the whole dict of variables. + Else look up and format just the value for key. + """ import pprint pp = pprint.PrettyPrinter(indent=2) if key: - dict = self.Dictionary(key) + cvars = self.Dictionary(key) else: - dict = self.Dictionary() - return pp.pformat(dict) + cvars = self.Dictionary() + + # TODO: pprint doesn't do a nice job on path-style values + # if the paths contain spaces (i.e. Windows), because the + # algorithm tries to break lines on spaces, while breaking + # on the path-separator would be more "natural". Is there + # a better way to format those? + return pp.pformat(cvars) + def FindIxes(self, paths, prefix, suffix): """ @@ -1599,7 +1616,7 @@ class Base(SubstitutionEnvironment): for td in tdlist: targets.extend(td[0]) if len(targets) > 1: - raise SCons.Errors.UserError( + raise UserError( "More than one dependency target found in `%s': %s" % (filename, targets)) for target, depends in tdlist: @@ -2038,7 +2055,7 @@ class Base(SubstitutionEnvironment): """ action = self.Action(action, *args, **kw) result = action([], [], self) - if isinstance(result, SCons.Errors.BuildError): + if isinstance(result, BuildError): errstr = result.errstr if result.filename: errstr = result.filename + ': ' + errstr @@ -2158,7 +2175,7 @@ class Base(SubstitutionEnvironment): for side_effect in side_effects: if side_effect.multiple_side_effect_has_builder(): - raise SCons.Errors.UserError("Multiple ways to build the same target were specified for: %s" % str(side_effect)) + raise UserError("Multiple ways to build the same target were specified for: %s" % str(side_effect)) side_effect.add_source(targets) side_effect.side_effect = 1 self.Precious(side_effect) @@ -2176,24 +2193,6 @@ class Base(SubstitutionEnvironment): entry.set_src_builder(builder) return entries - def SourceSignatures(self, type): - global _warn_source_signatures_deprecated - if _warn_source_signatures_deprecated: - msg = "The env.SourceSignatures() method is deprecated;\n" + \ - "\tconvert your build to use the env.Decider() method instead." - SCons.Warnings.warn(SCons.Warnings.DeprecatedSourceSignaturesWarning, msg) - _warn_source_signatures_deprecated = False - type = self.subst(type) - self.src_sig_type = type - if type == 'MD5': - if not SCons.Util.md5: - raise UserError("MD5 signatures are not available in this version of Python.") - self.decide_source = self._changed_content - elif type == 'timestamp': - self.decide_source = self._changed_timestamp_match - else: - raise UserError("Unknown source signature type '%s'" % type) - def Split(self, arg): """This function converts a string or list into a list of strings or Nodes. This makes things easier for users by allowing files to @@ -2215,28 +2214,6 @@ class Base(SubstitutionEnvironment): else: return [self.subst(arg)] - def TargetSignatures(self, type): - global _warn_target_signatures_deprecated - if _warn_target_signatures_deprecated: - msg = "The env.TargetSignatures() method is deprecated;\n" + \ - "\tconvert your build to use the env.Decider() method instead." - SCons.Warnings.warn(SCons.Warnings.DeprecatedTargetSignaturesWarning, msg) - _warn_target_signatures_deprecated = False - type = self.subst(type) - self.tgt_sig_type = type - if type in ('MD5', 'content'): - if not SCons.Util.md5: - raise UserError("MD5 signatures are not available in this version of Python.") - self.decide_target = self._changed_content - elif type == 'timestamp': - self.decide_target = self._changed_timestamp_match - elif type == 'build': - self.decide_target = self._changed_build - elif type == 'source': - self.decide_target = self._changed_source - else: - raise UserError("Unknown target signature type '%s'"%type) - def Value(self, value, built_value=None): """ """ @@ -2321,7 +2298,7 @@ class OverrideEnvironment(Base): return attr.clone(self) else: return attr - + def __setattr__(self, name, value): setattr(self.__dict__['__subject'], name, value) @@ -2333,7 +2310,7 @@ class OverrideEnvironment(Base): return self.__dict__['__subject'].__getitem__(key) def __setitem__(self, key, value): if not is_valid_construction_var(key): - raise SCons.Errors.UserError("Illegal construction variable `%s'" % key) + raise UserError("Illegal construction variable `%s'" % key) self.__dict__['overrides'][key] = value def __delitem__(self, key): try: diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 1b0a04c..829bf12 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -148,9 +148,9 @@ appending to this list, although the more flexible approach is to associate scanners with a specific Builder. -See the sections "Builder Objects" -and "Scanner Objects," -below, for more information. +See the manpage sections "Builder Objects" +and "Scanner Objects" +for more information. </para> </summary> </cvar> @@ -160,7 +160,8 @@ below, for more information. <para> A reserved variable name that may not be set or used in a construction environment. -(See "Variable Substitution," below.) +(See the manpage section "Variable Substitution" +for more information). </para> </summary> </cvar> @@ -170,7 +171,8 @@ that may not be set or used in a construction environment. <para> A reserved variable name that may not be set or used in a construction environment. -(See "Variable Substitution," below.) +(See the manpage section "Variable Substitution" +for more information). </para> </summary> </cvar> @@ -180,7 +182,8 @@ that may not be set or used in a construction environment. <para> A reserved variable name that may not be set or used in a construction environment. -(See "Variable Substitution," below.) +(See the manpage section "Variable Substitution" +for more information). </para> </summary> </cvar> @@ -190,7 +193,8 @@ that may not be set or used in a construction environment. <para> A reserved variable name that may not be set or used in a construction environment. -(See "Variable Substitution," below.) +(See the manpage section "Variable Substitution" +for more information). </para> </summary> </cvar> @@ -200,7 +204,8 @@ that may not be set or used in a construction environment. <para> A reserved variable name that may not be set or used in a construction environment. -(See "Variable Substitution," below.) +(See the manpage section "Variable Substitution" +for more information). </para> </summary> </cvar> @@ -210,7 +215,8 @@ that may not be set or used in a construction environment. <para> A reserved variable name that may not be set or used in a construction environment. -(See "Variable Substitution," below.) +(See the manpage section "Variable Substitution" +for more information). </para> </summary> </cvar> @@ -220,7 +226,8 @@ that may not be set or used in a construction environment. <para> A reserved variable name that may not be set or used in a construction environment. -(See "Variable Substitution," below.) +(See the manpage section "Variable Substitution" +for more information). </para> </summary> </cvar> @@ -230,7 +237,8 @@ that may not be set or used in a construction environment. <para> A reserved variable name that may not be set or used in a construction environment. -(See "Variable Substitution," below.) +(See the manpage section "Variable Substitution" +for more information). </para> </summary> </cvar> @@ -255,8 +263,8 @@ that are part of this construction environment. Creates an Action object for the specified <varname>action</varname>. -See the section "Action Objects," -below, for a complete explanation of the arguments and behavior. +See the manpage section "Action Objects" +for a complete explanation of the arguments and behavior. </para> <para> @@ -359,7 +367,8 @@ has been built. The specified action(s) may be an Action object, or anything that can be converted into an Action object -(see below). +See the manpage section "Action Objects" +for a complete explanation. </para> <para> @@ -386,7 +395,8 @@ is built. The specified action(s) may be an Action object, or anything that can be converted into an Action object -(see below). +See the manpage section "Action Objects" +for a complete explanation. </para> <para> @@ -512,7 +522,7 @@ Otherwise, the construction variable and the value of the keyword argument are both coerced to lists, and the lists are added together. -(See also the Prepend method, below.) +(See also the &Prepend; method). </para> <para> @@ -634,8 +644,8 @@ or Creates a Builder object for the specified <varname>action</varname>. -See the section "Builder Objects," -below, for a complete explanation of the arguments and behavior. +See the manpage section "Builder Objects" +for a complete explanation of the arguments and behavior. </para> <para> @@ -898,11 +908,15 @@ wx_env = env.Clone(parse_flags='!wx-config --cflags --cxxflags') <builder name="Command"> <summary> <para> -The &b-Command; "Builder" is actually implemented -as a function that looks like a Builder, -but actually takes an additional argument of the action -from which the Builder should be made. -See the &f-link-Command; function description +The &b-Command; "Builder" is actually +a function that looks like a Builder, +but takes a required third argument, which is the +action to take to construct the target +from the source, used for "one-off" builds +where a full builder is not needed. +Thus it does not follow the builder +calling rules described at the start of this section. +See instead the &f-link-Command; function description for the calling syntax and details. </para> </summary> @@ -947,7 +961,7 @@ same-named existing construction variables. An action can be an external command, specified as a string, or a callable Python object; -see "Action Objects," below, +see the manpage section "Action Objects" for more complete information. Also note that a string specifying an external command may be preceded by an @@ -971,7 +985,7 @@ env.Command('foo.out', 'foo.in', env.Command('bar.out', 'bar.in', ["rm -f $TARGET", "$BAR_BUILD < $SOURCES > $TARGET"], - ENV = {'PATH' : '/usr/local/bin/'}) + ENV={'PATH': '/usr/local/bin/'}) def rename(env, target, source): import os @@ -979,7 +993,7 @@ def rename(env, target, source): env.Command('baz.out', 'baz.in', ["$BAZ_BUILD < $SOURCES > .tmp", - rename ]) + rename]) </example_commands> <para> @@ -988,14 +1002,14 @@ Note that the function will usually assume, by default, that the specified targets and/or sources are Files, if no other part of the configuration -identifies what type of entry it is. +identifies what type of entries they are. If necessary, you can explicitly specify that targets or source nodes should -be treated as directoriese +be treated as directories by using the &f-link-Dir; or -<function>env.Dir</function>() +<function>env.Dir</function> functions. </para> @@ -1011,9 +1025,9 @@ env.Command(env.Dir('$DISTDIR')), None, make_distdir) </example_commands> <para> -(Also note that SCons will usually +Also note that SCons will usually automatically create any directory necessary to hold a target file, -so you normally don't need to create directories by hand.) +so you normally don't need to create directories by hand. </para> </summary> </scons_function> @@ -1029,8 +1043,8 @@ so you normally don't need to create directories by hand.) <para> Creates a Configure object for integrated functionality similar to GNU autoconf. -See the section "Configure Contexts," -below, for a complete explanation of the arguments and behavior. +See the manpage section "Configure Contexts" +for a complete explanation of the arguments and behavior. </para> </summary> </scons_function> @@ -1325,11 +1339,11 @@ env.Depends(bar, installed_lib) <summary> <para> Returns a dictionary object -containing copies of all of the -construction variables in the environment. -If there are any variable names specified, -only the specified construction -variables are returned in the dictionary. +containing the &consvars; in the &consenv;. +If there are any arguments specified, +the values of the specified &consvars; +are returned as a string (if one +argument) or as a list of strings. </para> <para> @@ -1337,8 +1351,8 @@ Example: </para> <example_commands> -dict = env.Dictionary() -cc_dict = env.Dictionary('CC', 'CCFLAGS', 'CCCOM') +cvars = env.Dictionary() +cc_values = env.Dictionary('CC', 'CCFLAGS', 'CCCOM') </example_commands> </summary> </scons_function> @@ -1375,7 +1389,8 @@ would supply a string as a directory name to a Builder method or function. Directory Nodes have attributes and methods that are useful in many situations; -see "File and Directory Nodes," below. +see manpage section "File and Directory Nodes" +for more information. </para> </summary> </scons_function> @@ -1458,8 +1473,8 @@ Executes an Action object. The specified <varname>action</varname> may be an Action object -(see the section "Action Objects," -below, for a complete explanation of the arguments and behavior), +(see manpage section "Action Objects" +for a complete explanation of the arguments and behavior), or it may be a command-line string, list of commands, or executable Python function, @@ -1532,7 +1547,8 @@ would supply a string as a file name to a Builder method or function. File Nodes have attributes and methods that are useful in many situations; -see "File and Directory Nodes," below. +see manpage section "File and Directory Nodes" +for more information. </para> </summary> </scons_function> @@ -2190,7 +2206,7 @@ and the construction variables they affect are as specified for the &f-link-env-ParseFlags; method (which this method calls). -See that method's description, below, +See that method's description for a table of options and construction variables. </para> </summary> @@ -2301,30 +2317,33 @@ and added to the following construction variables: </para> <example_commands> --arch CCFLAGS, LINKFLAGS --D CPPDEFINES --framework FRAMEWORKS --frameworkdir= FRAMEWORKPATH --include CCFLAGS --isysroot CCFLAGS, LINKFLAGS --isystem CCFLAGS --iquote CCFLAGS --idirafter CCFLAGS --I CPPPATH --l LIBS --L LIBPATH --mno-cygwin CCFLAGS, LINKFLAGS --mwindows LINKFLAGS --pthread CCFLAGS, LINKFLAGS --std= CFLAGS --Wa, ASFLAGS, CCFLAGS --Wl,-rpath= RPATH --Wl,-R, RPATH --Wl,-R RPATH --Wl, LINKFLAGS --Wp, CPPFLAGS -- CCFLAGS -+ CCFLAGS, LINKFLAGS +-arch CCFLAGS, LINKFLAGS +-D CPPDEFINES +-framework FRAMEWORKS +-frameworkdir= FRAMEWORKPATH +-fmerge-all-constants CCFLAGS, LINKFLAGS +-fopenmp CCFLAGS, LINKFLAGS +-include CCFLAGS +-isysroot CCFLAGS, LINKFLAGS +-isystem CCFLAGS +-iquote CCFLAGS +-idirafter CCFLAGS +-I CPPPATH +-l LIBS +-L LIBPATH +-mno-cygwin CCFLAGS, LINKFLAGS +-mwindows LINKFLAGS +-openmp CCFLAGS, LINKFLAGS +-pthread CCFLAGS, LINKFLAGS +-std= CFLAGS +-Wa, ASFLAGS, CCFLAGS +-Wl,-rpath= RPATH +-Wl,-R, RPATH +-Wl,-R RPATH +-Wl, LINKFLAGS +-Wp, CPPFLAGS +- CCFLAGS ++ CCFLAGS, LINKFLAGS </example_commands> <para> @@ -2655,8 +2674,8 @@ env.Requires('foo', 'file-that-must-be-built-before-foo') Creates a Scanner object for the specified <varname>function</varname>. -See the section "Scanner Objects," -below, for a complete explanation of the arguments and behavior. +See manpage section "Scanner Objects" +for a complete explanation of the arguments and behavior. </para> </summary> </scons_function> @@ -2968,105 +2987,6 @@ env.SourceCode('no_source.c', None) </summary> </scons_function> -<scons_function name="SourceSignatures"> -<arguments> -(type) -</arguments> -<summary> -<para> -Note: Although it is not yet officially deprecated, -use of this function is discouraged. -See the -&f-link-Decider; -function for a more flexible and straightforward way -to configure SCons' decision-making. -</para> - -<para> -The -&f-SourceSignatures; -function tells -&scons; -how to decide if a source file -(a file that is not built from any other files) -has changed since the last time it -was used to build a particular target file. -Legal values are -<literal>MD5</literal> -or -<literal>timestamp</literal>. -</para> - -<para> -If the environment method is used, -the specified type of source signature -is only used when deciding whether targets -built with that environment are up-to-date or must be rebuilt. -If the global function is used, -the specified type of source signature becomes the default -used for all decisions -about whether targets are up-to-date. -</para> - -<para> -<literal>MD5</literal> -means -&scons; -decides that a source file has changed -if the MD5 checksum of its contents has changed since -the last time it was used to rebuild a particular target file. -</para> - -<para> -<literal>timestamp</literal> -means -&scons; -decides that a source file has changed -if its timestamp (modification time) has changed since -the last time it was used to rebuild a particular target file. -(Note that although this is similar to the behavior of Make, -by default it will also rebuild if the dependency is -<emphasis>older</emphasis> -than the last time it was used to rebuild the target file.) -</para> - -<para> -There is no different between the two behaviors -for Python -&f-Value; -node objects. -</para> - -<para> -<literal>MD5</literal> -signatures take longer to compute, -but are more accurate than -<literal>timestamp</literal> -signatures. -The default value is -<literal>MD5</literal>. -</para> - -<para> -Note that the default -&f-link-TargetSignatures; -setting (see below) -is to use this -&f-SourceSignatures; -setting for any target files that are used -to build other target files. -Consequently, changing the value of -&f-SourceSignatures; -will, by default, -affect the up-to-date decision for all files in the build -(or all files built with a specific construction environment -when -&f-env-SourceSignatures; -is used). -</para> -</summary> -</scons_function> - <scons_function name="Split"> <arguments> (arg) @@ -3210,159 +3130,6 @@ source_nodes = env.subst('$EXPAND_TO_NODELIST', </summary> </scons_function> -<scons_function name="TargetSignatures"> -<arguments> -(type) -</arguments> -<summary> -<para> -Note: Although it is not yet officially deprecated, -use of this function is discouraged. -See the -&f-link-Decider; -function for a more flexible and straightforward way -to configure SCons' decision-making. -</para> - -<para> -The -&f-TargetSignatures; -function tells -&scons; -how to decide if a target file -(a file that -<emphasis>is</emphasis> -built from any other files) -has changed since the last time it -was used to build some other target file. -Legal values are -<literal>"build"</literal>; -<literal>"content"</literal> -(or its synonym -<literal>"MD5"</literal>); -<literal>"timestamp"</literal>; -or -<literal>"source"</literal>. -</para> - -<para> -If the environment method is used, -the specified type of target signature is only used -for targets built with that environment. -If the global function is used, -the specified type of signature becomes the default -used for all target files that -don't have an explicit target signature type -specified for their environments. -</para> - -<para> -<literal>"content"</literal> -(or its synonym -<literal>"MD5"</literal>) -means -&scons; -decides that a target file has changed -if the MD5 checksum of its contents has changed since -the last time it was used to rebuild some other target file. -This means -&scons; -will open up -MD5 sum the contents -of target files after they're built, -and may decide that it does not need to rebuild -"downstream" target files if a file was -rebuilt with exactly the same contents as the last time. -</para> - -<para> -<literal>"timestamp"</literal> -means -&scons; -decides that a target file has changed -if its timestamp (modification time) has changed since -the last time it was used to rebuild some other target file. -(Note that although this is similar to the behavior of Make, -by default it will also rebuild if the dependency is -<emphasis>older</emphasis> -than the last time it was used to rebuild the target file.) -</para> - -<para> -<literal>"source"</literal> -means -&scons; -decides that a target file has changed -as specified by the corresponding -&f-SourceSignatures; -setting -(<literal>"MD5"</literal> -or -<literal>"timestamp"</literal>). -This means that -&scons; -will treat all input files to a target the same way, -regardless of whether they are source files -or have been built from other files. -</para> - -<para> -<literal>"build"</literal> -means -&scons; -decides that a target file has changed -if it has been rebuilt in this invocation -or if its content or timestamp have changed -as specified by the corresponding -&f-SourceSignatures; -setting. -This "propagates" the status of a rebuilt file -so that other "downstream" target files -will always be rebuilt, -even if the contents or the timestamp -have not changed. -</para> - -<para> -<literal>"build"</literal> -signatures are fastest because -<literal>"content"</literal> -(or -<literal>"MD5"</literal>) -signatures take longer to compute, -but are more accurate than -<literal>"timestamp"</literal> -signatures, -and can prevent unnecessary "downstream" rebuilds -when a target file is rebuilt to the exact same contents -as the previous build. -The -<literal>"source"</literal> -setting provides the most consistent behavior -when other target files may be rebuilt from -both source and target input files. -The default value is -<literal>"source"</literal>. -</para> - -<para> -Because the default setting is -<literal>"source"</literal>, -using -&f-SourceSignatures; -is generally preferable to -&f-TargetSignatures;, -so that the up-to-date decision -will be consistent for all files -(or all files built with a specific construction environment). -Use of -&f-TargetSignatures; -provides specific control for how built target files -affect their "downstream" dependencies. -</para> -</summary> -</scons_function> - <scons_function name="Tool"> <arguments> (string, [toolpath, **kw]) @@ -3647,30 +3414,51 @@ SConscript(dirs='doc', variant_dir='build/doc', duplicate=0) Searches for the specified executable <varname>program</varname>, returning the full path name to the program -if it is found, -and returning None if not. -Searches the specified -<varname>path</varname>, -the value of the calling environment's PATH -(<literal>env['ENV']['PATH']</literal>), -or the user's current external PATH -(<literal>os.environ['PATH']</literal>) -by default. +if it is found, else <literal>None</literal>. +Searches the value of the +<varname>path</varname> keyword argument, +or if <literal>None</literal> (the default) +the value of the calling environment's <envar>PATH</envar> +(<literal>env['ENV']['PATH']</literal>). +If <varname>path</varname> is <literal>None</literal> and +the <literal>env['ENV']['PATH']</literal> key does not exist, +the user's current external <envar>PATH</envar> +(<literal>os.environ['PATH']</literal>) is used as fallback. +</para> +<para> On Windows systems, searches for executable -programs with any of the file extensions -listed in the specified -<varname>pathext</varname>, -the calling environment's PATHEXT -(<literal>env['ENV']['PATHEXT']</literal>) -or the user's current PATHEXT +programs with any of the file extensions listed in the +<varname>pathext</varname> keyword argument, +or if <literal>None</literal> (the default) +the calling environment's <envar>PATHEXT</envar> +(<literal>env['ENV']['PATHEXT']</literal>). +The user's current external <envar>PATHEXT</envar> (<literal>os.environ['PATHEXT']</literal>) -by default. +is used as a fallback if <varname>pathext</varname> is +<literal>None</literal> +and the key <literal>env['ENV']['PATHEXT']</literal> +does not exist. +</para> +<para> Will not select any path name or names in the specified <varname>reject</varname> list, if any. </para> +<note> +<para> +If you would prefer to search +the user's current external <envar>PATH</envar> +(<literal>os.environ['PATH']</literal>) +by default, +consider using the function <literal>SCons.Util.WhereIs</literal> instead. +Note that <literal>SCons.Util.WhereIs</literal> +does not expand environment variables automatically +(no implicit <literal>env.subst</literal> for its arguments). +</para> +</note> + </summary> </scons_function> diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 834cfd1..f016f22 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -797,6 +797,7 @@ sys.exit(0) "-F fwd3 " + \ "-dylib_file foo-dylib " + \ "-pthread " + \ + "-fmerge-all-constants " +\ "-fopenmp " + \ "-mno-cygwin -mwindows " + \ "-arch i386 -isysroot /tmp " + \ @@ -811,7 +812,8 @@ sys.exit(0) assert d['ASFLAGS'] == ['-as'], d['ASFLAGS'] assert d['CFLAGS'] == ['-std=c99'] assert d['CCFLAGS'] == ['-X', '-Wa,-as', - '-pthread', '-fopenmp', '-mno-cygwin', + '-pthread', '-fmerge-all-constants', + '-fopenmp', '-mno-cygwin', ('-arch', 'i386'), ('-isysroot', '/tmp'), ('-iquote', '/usr/include/foo1'), ('-isystem', '/usr/include/foo2'), @@ -832,7 +834,7 @@ sys.exit(0) assert LIBS == ['xxx', 'yyy', 'ascend'], (d['LIBS'], LIBS) assert d['LINKFLAGS'] == ['-Wl,-link', '-dylib_file', 'foo-dylib', - '-pthread', '-fopenmp', + '-pthread', '-fmerge-all-constants', '-fopenmp', '-mno-cygwin', '-mwindows', ('-arch', 'i386'), ('-isysroot', '/tmp'), @@ -2024,6 +2026,7 @@ def generate(env): "-Ffwd2 " + \ "-F fwd3 " + \ "-pthread " + \ + "-fmerge-all-constants " + \ "-mno-cygwin -mwindows " + \ "-arch i386 -isysroot /tmp " + \ "-iquote /usr/include/foo1 " + \ @@ -2035,7 +2038,7 @@ def generate(env): assert save_command == ['fake command'], save_command assert env['ASFLAGS'] == ['assembler', '-as'], env['ASFLAGS'] assert env['CCFLAGS'] == ['', '-X', '-Wa,-as', - '-pthread', '-mno-cygwin', + '-pthread', '-fmerge-all-constants', '-mno-cygwin', ('-arch', 'i386'), ('-isysroot', '/tmp'), ('-iquote', '/usr/include/foo1'), ('-isystem', '/usr/include/foo2'), @@ -2049,6 +2052,7 @@ def generate(env): assert env['LIBPATH'] == ['list', '/usr/fax', 'foo'], env['LIBPATH'] assert env['LIBS'] == ['xxx', 'yyy', env.File('abc')], env['LIBS'] assert env['LINKFLAGS'] == ['', '-Wl,-link', '-pthread', + '-fmerge-all-constants', '-mno-cygwin', '-mwindows', ('-arch', 'i386'), ('-isysroot', '/tmp'), @@ -3280,44 +3284,6 @@ def generate(env): s = e.src_builder() assert s is None, s - def test_SourceSignatures(self): - """Test the SourceSignatures() method""" - import SCons.Errors - - env = self.TestEnvironment(M = 'MD5', T = 'timestamp') - - exc_caught = None - try: - env.SourceSignatures('invalid_type') - except SCons.Errors.UserError: - exc_caught = 1 - assert exc_caught, "did not catch expected UserError" - - env.SourceSignatures('MD5') - assert env.src_sig_type == 'MD5', env.src_sig_type - - env.SourceSignatures('$M') - assert env.src_sig_type == 'MD5', env.src_sig_type - - env.SourceSignatures('timestamp') - assert env.src_sig_type == 'timestamp', env.src_sig_type - - env.SourceSignatures('$T') - assert env.src_sig_type == 'timestamp', env.src_sig_type - - try: - import SCons.Util - save_md5 = SCons.Util.md5 - SCons.Util.md5 = None - try: - env.SourceSignatures('MD5') - except SCons.Errors.UserError: - pass - else: - self.fail('Did not catch expected UserError') - finally: - SCons.Util.md5 = save_md5 - def test_Split(self): """Test the Split() method""" env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb') @@ -3334,56 +3300,6 @@ def generate(env): s = env.Split("$FOO$BAR") assert s == ["fffbbb"], s - def test_TargetSignatures(self): - """Test the TargetSignatures() method""" - import SCons.Errors - - env = self.TestEnvironment(B='build', C='content') - - exc_caught = None - try: - env.TargetSignatures('invalid_type') - except SCons.Errors.UserError: - exc_caught = 1 - assert exc_caught, "did not catch expected UserError" - assert not hasattr(env, '_build_signature') - - env.TargetSignatures('build') - assert env.tgt_sig_type == 'build', env.tgt_sig_type - - env.TargetSignatures('$B') - assert env.tgt_sig_type == 'build', env.tgt_sig_type - - env.TargetSignatures('content') - assert env.tgt_sig_type == 'content', env.tgt_sig_type - - env.TargetSignatures('$C') - assert env.tgt_sig_type == 'content', env.tgt_sig_type - - env.TargetSignatures('MD5') - assert env.tgt_sig_type == 'MD5', env.tgt_sig_type - - env.TargetSignatures('timestamp') - assert env.tgt_sig_type == 'timestamp', env.tgt_sig_type - - try: - import SCons.Util - save_md5 = SCons.Util.md5 - SCons.Util.md5 = None - try: - env.TargetSignatures('MD5') - except SCons.Errors.UserError: - pass - else: - self.fail('Did not catch expected UserError') - try: - env.TargetSignatures('content') - except SCons.Errors.UserError: - pass - else: - self.fail('Did not catch expected UserError') - finally: - SCons.Util.md5 = save_md5 def test_Value(self): """Test creating a Value() object @@ -3404,7 +3320,6 @@ def generate(env): assert v3.value == 'c', v3.value - def test_Environment_global_variable(self): """Test setting Environment variable to an Environment.Base subclass""" class MyEnv(SCons.Environment.Base): @@ -3746,8 +3661,6 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): # Environment() # FindFile() # Scanner() - # SourceSignatures() - # TargetSignatures() # It's unlikely Clone() will ever be called this way, so let the # other methods test that handling overridden values works. diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 33105fb..6b0fe98 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -3436,6 +3436,8 @@ class File(Base): Boolean - Indicates if node(File) has changed. """ + if node is None: + node = self # Now get sconsign name -> csig map and then get proper prev_ni if possible bi = node.get_stored_info().binfo rebuilt = False diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 72eaba7..eddfdf0 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -2545,11 +2545,10 @@ class FileTestCase(_tempdirTestCase): def get_ninfo(self): """ mocked to ensure csig will equal the filename""" - try: - return self.ninfo - except AttributeError: - self.ninfo = FakeNodeInfo(self.name, self.timestamp) + if self.ninfo is not None: return self.ninfo + self.ninfo = FakeNodeInfo(self.name, self.timestamp) + return self.ninfo def get_csig(self): ninfo = self.get_ninfo() diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 3073d59..daf79ba 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -614,6 +614,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)): self._func_rexists = 1 self._func_get_contents = 0 self._func_target_from_source = 0 + self.ninfo = None self.clear_memoized_values() @@ -1131,11 +1132,10 @@ class Node(object, with_metaclass(NoSlotsPyPy)): return ninfo def get_ninfo(self): - try: - return self.ninfo - except AttributeError: - self.ninfo = self.new_ninfo() + if self.ninfo is not None: return self.ninfo + self.ninfo = self.new_ninfo() + return self.ninfo def new_binfo(self): binfo = self.BuildInfo() @@ -1661,10 +1661,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)): if k not in old_bkids: lines.append("`%s' is a new dependency\n" % stringify(k)) else: - try: - changed = _decider_map[k.changed_since_last_build](k, self, osig[k]) - except DeciderNeedsNode as e: - changed = e.decider(self, osig[k], node=self) + changed = _decider_map[k.changed_since_last_build](k, self, osig[k]) if changed: lines.append("`%s' changed\n" % stringify(k)) diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index acc8678..58dbf64 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -75,6 +75,7 @@ print_objects = 0 print_memoizer = 0 print_stacktrace = 0 print_time = 0 +print_action_timestamps = 0 sconscript_time = 0 cumulative_command_time = 0 exit_status = 0 # final exit status, assume success by default @@ -209,7 +210,11 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): finish_time = time.time() last_command_end = finish_time cumulative_command_time = cumulative_command_time+finish_time-start_time + if print_action_timestamps: + sys.stdout.write("Command execution start time: %s: %f seconds\n"%(str(self.node), start_time)) sys.stdout.write("Command execution time: %s: %f seconds\n"%(str(self.node), finish_time-start_time)) + if print_action_timestamps: + sys.stdout.write("Command execution stop time: %s: %f seconds\n"%(str(self.node), finish_time)) def do_failed(self, status=2): _BuildFailures.append(self.exception[1]) @@ -636,7 +641,7 @@ def _SConstruct_exists(dirname='', repositories=[], filelist=None): return None def _set_debug_values(options): - global print_memoizer, print_objects, print_stacktrace, print_time + global print_memoizer, print_objects, print_stacktrace, print_time, print_action_timestamps debug_values = options.debug @@ -674,6 +679,9 @@ def _set_debug_values(options): options.tree_printers.append(TreePrinter(status=True)) if "time" in debug_values: print_time = 1 + if "action_timestamps" in debug_values: + print_time = 1 + print_action_timestamps = 1 if "tree" in debug_values: options.tree_printers.append(TreePrinter()) if "prepare" in debug_values: diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index c45cb01..7b5d523 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', } @@ -614,15 +622,16 @@ def Parser(version): debug_options = ["count", "duplicate", "explain", "findlibs", "includes", "memoizer", "memory", "objects", "pdb", "prepare", "presub", "stacktrace", - "time"] + "time", "action_timestamps"] def opt_debug(option, opt, value__, parser, debug_options=debug_options, - deprecated_debug_options=deprecated_debug_options): + deprecated_debug_options=deprecated_debug_options, + removed_debug_options=removed_debug_options): for value in value__.split(','): if value in debug_options: parser.values.debug.append(value) - elif value in list(deprecated_debug_options.keys()): + elif value in deprecated_debug_options: parser.values.debug.append(value) try: parser.values.delayed_warnings @@ -632,6 +641,9 @@ def Parser(version): w = "The --debug=%s option is deprecated%s." % (value, msg) t = (SCons.Warnings.DeprecatedDebugOptionsWarning, w) parser.values.delayed_warnings.append(t) + elif value in removed_debug_options: + msg = removed_debug_options[value] + raise OptionValueError(opt_invalid_rm('debug', value, msg)) else: raise OptionValueError(opt_invalid('debug', value, debug_options)) diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 007eb0d..24af73e 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -346,10 +346,8 @@ GlobalDefaultEnvironmentFunctions = [ 'SConsignFile', 'SideEffect', 'SourceCode', - 'SourceSignatures', 'Split', 'Tag', - 'TargetSignatures', 'Value', 'VariantDir', ] diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index 6f62198..2de64c5 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -409,7 +409,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ handles separating command lines into lists of arguments, so see that function if that's what you're looking for. """ - if isinstance(strSubst, str) and strSubst.find('$') < 0: + if (isinstance(strSubst, str) and '$' not in strSubst) or isinstance(strSubst, CmdStringHolder): return strSubst class StringSubber(object): diff --git a/src/engine/SCons/Tool/DCommon.xml b/src/engine/SCons/Tool/DCommon.xml index f42bea3..8c8c1b5 100644 --- a/src/engine/SCons/Tool/DCommon.xml +++ b/src/engine/SCons/Tool/DCommon.xml @@ -23,49 +23,339 @@ See its __doc__ string for a discussion of the format. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0/scons.xsd"> +<cvar name="DC"> +<summary> +<para> +The D compiler to use. +</para> +</summary> +</cvar> +<cvar name="DCOM"> +<summary> +<para> +The command line used to compile a D file to an object file. +Any options specified in the &cv-link-DFLAGS; construction variable +is included on this command line. +</para> +</summary> +</cvar> +<cvar name="DDEBUG"> +<summary> +<para> +List of debug tags to enable when compiling. +</para> +</summary> +</cvar> +<cvar name="DDEBUGPREFIX"> +<summary> +<para> +DDEBUGPREFIX. +</para> +</summary> +</cvar> - <cvar name="DRPATHPREFIX"> - <summary> - <para> - DRPATHPREFIX. - </para> - </summary> - </cvar> - - <cvar name="DRPATHSUFFIX"> - <summary> - <para> - DRPATHSUFFIX. - </para> - </summary> - </cvar> - - - <cvar name="DShLibSonameGenerator"> - <summary> - <para> - DShLibSonameGenerator. - </para> - </summary> - </cvar> - - <cvar name="SHDLIBVERSION"> - <summary> - <para> - SHDLIBVERSION. - </para> - </summary> - </cvar> - <cvar name="SHDLIBVERSIONFLAGS"> - <summary> - <para> - SHDLIBVERSIONFLAGS. - </para> - </summary> - </cvar> +<cvar name="DDEBUGSUFFIX"> +<summary> +<para> +DDEBUGSUFFIX. +</para> +</summary> +</cvar> +<cvar name="DFILESUFFIX"> +<summary> +<para> +DFILESUFFIX. +</para> +</summary> +</cvar> + +<cvar name="DFLAGPREFIX"> +<summary> +<para> +DFLAGPREFIX. +</para> +</summary> +</cvar> + +<cvar name="DFLAGS"> +<summary> +<para> +General options that are passed to the D compiler. +</para> +</summary> +</cvar> + +<cvar name="DFLAGSUFFIX"> +<summary> +<para> +DFLAGSUFFIX. +</para> +</summary> +</cvar> + +<cvar name="DINCSUFFIX"> +<summary> +<para> +DLIBFLAGSUFFIX. +</para> +</summary> +</cvar> + +<cvar name="DINCPREFIX"> +<summary> +<para> +DINCPREFIX. +</para> +</summary> +</cvar> + +<cvar name="DLIB"> +<summary> +<para> +Name of the lib tool to use for D codes. +</para> +</summary> +</cvar> + +<cvar name="DLIBCOM"> +<summary> +<para> +The command line to use when creating libraries. +</para> +</summary> +</cvar> + +<cvar name="DLIBDIRPREFIX"> +<summary> +<para> +DLIBLINKPREFIX. +</para> +</summary> +</cvar> + +<cvar name="DLIBDIRSUFFIX"> +<summary> +<para> +DLIBLINKSUFFIX. +</para> +</summary> +</cvar> + +<cvar name="DLIBFLAGSUFFIX"> +<summary> +<para> +DLIBFLAGSUFFIX. +</para> +</summary> +</cvar> + +<cvar name="DLIBFLAGPREFIX"> +<summary> +<para> +DLIBFLAGPREFIX. +</para> +</summary> +</cvar> + +<cvar name="DLIBLINKPREFIX"> +<summary> +<para> +DLIBLINKPREFIX. +</para> +</summary> +</cvar> + +<cvar name="DLIBLINKSUFFIX"> +<summary> +<para> +DLIBLINKSUFFIX. +</para> +</summary> +</cvar> + +<cvar name="DLINK"> +<summary> +<para> +Name of the linker to use for linking systems including D sources. +</para> +</summary> +</cvar> + +<cvar name="DLINKCOM"> +<summary> +<para> +The command line to use when linking systems including D sources. +</para> +</summary> +</cvar> + +<cvar name="DLINKFLAGS"> +<summary> +<para> +List of linker flags. +</para> +</summary> +</cvar> + +<cvar name="DLINKFLAGSUFFIX"> +<summary> +<para> +DLINKFLAGSUFFIX. +</para> +</summary> +</cvar> + +<cvar name="DLINKFLAGPREFIX"> +<summary> +<para> +DLINKFLAGPREFIX. +</para> +</summary> +</cvar> + +<cvar name="DPATH"> +<summary> +<para> + List of paths to search for import modules. +</para> +</summary> +</cvar> + +<cvar name="DRPATHPREFIX"> +<summary> +<para> +DRPATHPREFIX. +</para> +</summary> +</cvar> + +<cvar name="DRPATHSUFFIX"> +<summary> +<para> +DRPATHSUFFIX. +</para> +</summary> +</cvar> + +<cvar name="DShLibSonameGenerator"> +<summary> +<para> +DShLibSonameGenerator. +</para> +</summary> +</cvar> + +<cvar name="DVERPREFIX"> +<summary> +<para> +DVERPREFIX. +</para> +</summary> +</cvar> + +<cvar name="DVERSIONS"> +<summary> +<para> +List of version tags to enable when compiling. +</para> +</summary> +</cvar> + +<cvar name="DVERSUFFIX"> +<summary> +<para> +DVERSUFFIX. +</para> +</summary> +</cvar> + +<cvar name="SHDC"> +<summary> +<para> +The name of the compiler to use when compiling D source +destined to be in a shared objects. +</para> +</summary> +</cvar> + +<cvar name="SHDCOM"> +<summary> +<para> +The command line to use when compiling code to be part of shared objects. +</para> +</summary> +</cvar> + +<cvar name="SHDLIBVERSION"> +<summary> +<para> +SHDLIBVERSION. +</para> +</summary> +</cvar> + +<cvar name="SHDLIBVERSIONFLAGS"> +<summary> +<para> +SHDLIBVERSIONFLAGS. +</para> +</summary> +</cvar> + +<cvar name="SHDLINK"> +<summary> +<para> +The linker to use when creating shared objects for code bases +include D sources. +</para> +</summary> +</cvar> + +<cvar name="SHDLINKCOM"> +<summary> +<para> +The command line to use when generating shared objects. +</para> +</summary> +</cvar> + +<cvar name="SHDLINKFLAGS"> +<summary> +<para> +The list of flags to use when generating a shared object. +</para> +</summary> +</cvar> + + +<builder name="ProgramAllAtOnce"> +<summary> + <para> + Builds an executable from D sources without first creating individual + objects for each file. + </para> + <para> + D sources can be compiled file-by-file as C and C++ source are, and + D is integrated into the &scons; Object and Program builders for + this model of build. D codes can though do whole source + meta-programming (some of the testing frameworks do this). For this + it is imperative that all sources are compiled and linked in a single + call to the D compiler. This builder serves that purpose. + </para> + <example_commands> + env.ProgramAllAtOnce('executable', ['mod_a.d, mod_b.d', 'mod_c.d']) + </example_commands> + <para> + This command will compile the modules mod_a, mod_b, and mod_c in a + single compilation process without first creating object files for + the modules. Some of the D compilers will create executable.o others + will not. + </para> +</summary> +</builder> </sconsdoc> diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index c3ba8e5..bbccf61 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -28,28 +28,64 @@ from __future__ import print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import copy +import json import os -import subprocess import re +import subprocess +import sys import SCons.Util +# SCONS_MSCOMMON_DEBUG is internal-use so undocumented: +# set to '-' to print to console, else set to filename to log to LOGFILE = os.environ.get('SCONS_MSCOMMON_DEBUG') if LOGFILE == '-': def debug(message): print(message) elif LOGFILE: - try: - import logging - except ImportError: - debug = lambda message: open(LOGFILE, 'a').write(message + '\n') - else: - logging.basicConfig(filename=LOGFILE, level=logging.DEBUG) - debug = logging.getLogger(name=__name__).debug + import logging + logging.basicConfig( + format='%(relativeCreated)05dms:pid%(process)05d:MSCommon/%(filename)s:%(message)s', + filename=LOGFILE, + level=logging.DEBUG) + debug = logging.getLogger(name=__name__).debug else: debug = lambda x: None +# SCONS_CACHE_MSVC_CONFIG is public, and is documented. +CONFIG_CACHE = os.environ.get('SCONS_CACHE_MSVC_CONFIG') +if CONFIG_CACHE in ('1', 'true', 'True'): + CONFIG_CACHE = os.path.join(os.path.expanduser('~'), '.scons_msvc_cache') + +def read_script_env_cache(): + """ fetch cached msvc env vars if requested, else return empty dict """ + envcache = {} + if CONFIG_CACHE: + try: + with open(CONFIG_CACHE, 'r') as f: + envcache = json.load(f) + #TODO can use more specific FileNotFoundError when py2 dropped + except IOError: + # don't fail if no cache file, just proceed without it + pass + return envcache + + +def write_script_env_cache(cache): + """ write out cache of msvc env vars if requested """ + if CONFIG_CACHE: + try: + with open(CONFIG_CACHE, 'w') as f: + json.dump(cache, f, indent=2) + except TypeError: + # data can't serialize to json, don't leave partial file + os.remove(CONFIG_CACHE) + except IOError: + # can't write the file, just skip + pass + + _is_win64 = None def is_win64(): @@ -199,7 +235,6 @@ def get_output(vcbat, args = None, env = None): if stderr: # TODO: find something better to do with stderr; # this at least prevents errors from getting swallowed. - import sys sys.stderr.write(stderr) if popen.wait() != 0: raise IOError(stderr.decode("mbcs")) @@ -207,14 +242,15 @@ def get_output(vcbat, args = None, env = None): output = stdout.decode("mbcs") return output -def parse_output(output, keep=("INCLUDE", "LIB", "LIBPATH", "PATH", 'VSCMD_ARG_app_plat')): +KEEPLIST = ("INCLUDE", "LIB", "LIBPATH", "PATH", 'VSCMD_ARG_app_plat') +def parse_output(output, keep=KEEPLIST): """ Parse output from running visual c++/studios vcvarsall.bat and running set To capture the values listed in keep """ # dkeep is a dict associating key: path_list, where key is one item from - # keep, and pat_list the associated list of paths + # keep, and path_list the associated list of paths dkeep = dict([(i, []) for i in keep]) # rdk will keep the regex to match the .bat file output line starts diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py index ad57865..281c1e3 100644 --- a/src/engine/SCons/Tool/MSCommon/sdk.py +++ b/src/engine/SCons/Tool/MSCommon/sdk.py @@ -118,11 +118,11 @@ class SDKDefinition(object): if (host_arch != target_arch): arch_string='%s_%s'%(host_arch,target_arch) - debug("sdk.py: get_sdk_vc_script():arch_string:%s host_arch:%s target_arch:%s"%(arch_string, + debug("get_sdk_vc_script():arch_string:%s host_arch:%s target_arch:%s"%(arch_string, host_arch, target_arch)) file=self.vc_setup_scripts.get(arch_string,None) - debug("sdk.py: get_sdk_vc_script():file:%s"%file) + debug("get_sdk_vc_script():file:%s"%file) return file class WindowsSDK(SDKDefinition): @@ -286,14 +286,14 @@ InstalledSDKMap = None def get_installed_sdks(): global InstalledSDKList global InstalledSDKMap - debug('sdk.py:get_installed_sdks()') + debug('get_installed_sdks()') if InstalledSDKList is None: InstalledSDKList = [] InstalledSDKMap = {} for sdk in SupportedSDKList: - debug('MSCommon/sdk.py: trying to find SDK %s' % sdk.version) + debug('trying to find SDK %s' % sdk.version) if sdk.get_sdk_dir(): - debug('MSCommon/sdk.py:found SDK %s' % sdk.version) + debug('found SDK %s' % sdk.version) InstalledSDKList.append(sdk) InstalledSDKMap[sdk.version] = sdk return InstalledSDKList @@ -346,13 +346,13 @@ def get_default_sdk(): return InstalledSDKList[0] def mssdk_setup_env(env): - debug('sdk.py:mssdk_setup_env()') + debug('mssdk_setup_env()') if 'MSSDK_DIR' in env: sdk_dir = env['MSSDK_DIR'] if sdk_dir is None: return sdk_dir = env.subst(sdk_dir) - debug('sdk.py:mssdk_setup_env: Using MSSDK_DIR:{}'.format(sdk_dir)) + debug('mssdk_setup_env: Using MSSDK_DIR:{}'.format(sdk_dir)) elif 'MSSDK_VERSION' in env: sdk_version = env['MSSDK_VERSION'] if sdk_version is None: @@ -364,22 +364,22 @@ def mssdk_setup_env(env): msg = "SDK version %s is not installed" % sdk_version raise SCons.Errors.UserError(msg) sdk_dir = mssdk.get_sdk_dir() - debug('sdk.py:mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir) + debug('mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir) elif 'MSVS_VERSION' in env: msvs_version = env['MSVS_VERSION'] - debug('sdk.py:mssdk_setup_env:Getting MSVS_VERSION from env:%s'%msvs_version) + debug('mssdk_setup_env:Getting MSVS_VERSION from env:%s'%msvs_version) if msvs_version is None: - debug('sdk.py:mssdk_setup_env thinks msvs_version is None') + debug('mssdk_setup_env thinks msvs_version is None') return msvs_version = env.subst(msvs_version) from . import vs msvs = vs.get_vs_by_version(msvs_version) - debug('sdk.py:mssdk_setup_env:msvs is :%s'%msvs) + debug('mssdk_setup_env:msvs is :%s'%msvs) if not msvs: - debug('sdk.py:mssdk_setup_env: no VS version detected, bailingout:%s'%msvs) + debug('mssdk_setup_env: no VS version detected, bailingout:%s'%msvs) return sdk_version = msvs.sdk_version - debug('sdk.py:msvs.sdk_version is %s'%sdk_version) + debug('msvs.sdk_version is %s'%sdk_version) if not sdk_version: return mssdk = get_sdk_by_version(sdk_version) @@ -388,13 +388,13 @@ def mssdk_setup_env(env): if not mssdk: return sdk_dir = mssdk.get_sdk_dir() - debug('sdk.py:mssdk_setup_env: Using MSVS_VERSION:%s'%sdk_dir) + debug('mssdk_setup_env: Using MSVS_VERSION:%s'%sdk_dir) else: mssdk = get_default_sdk() if not mssdk: return sdk_dir = mssdk.get_sdk_dir() - debug('sdk.py:mssdk_setup_env: not using any env values. sdk_dir:%s'%sdk_dir) + debug('mssdk_setup_env: not using any env values. sdk_dir:%s'%sdk_dir) set_sdk_by_directory(env, sdk_dir) diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 0e4ef15..4f6048d 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -40,7 +40,10 @@ import SCons.Util import subprocess import os import platform +import sys from string import digits as string_digits +if sys.version_info[0] == 2: + import collections import SCons.Warnings from SCons.Tool import find_program_path @@ -152,20 +155,15 @@ def get_msvc_version_numeric(msvc_version): return ''.join([x for x in msvc_version if x in string_digits + '.']) def get_host_target(env): - debug('vc.py:get_host_target()') + debug('get_host_target()') host_platform = env.get('HOST_ARCH') if not host_platform: host_platform = platform.machine() - # TODO(2.5): the native Python platform.machine() function returns - # '' on all Python versions before 2.6, after which it also uses - # PROCESSOR_ARCHITECTURE. - if not host_platform: - host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '') # Retain user requested TARGET_ARCH req_target_platform = env.get('TARGET_ARCH') - debug('vc.py:get_host_target() req_target_platform:%s'%req_target_platform) + debug('get_host_target() req_target_platform:%s'%req_target_platform) if req_target_platform: # If user requested a specific platform then only try that one. @@ -403,7 +401,7 @@ def find_batch_file(env,msvc_version,host_arch,target_arch): if pdir is None: raise NoVersionFound("No version of Visual Studio found") - debug('vc.py: find_batch_file() in {}'.format(pdir)) + debug('find_batch_file() in {}'.format(pdir)) # filter out e.g. "Exp" from the version name msvc_ver_numeric = get_msvc_version_numeric(msvc_version) @@ -423,17 +421,17 @@ def find_batch_file(env,msvc_version,host_arch,target_arch): debug("Not found: %s" % batfilename) batfilename = None - installed_sdks=get_installed_sdks() + installed_sdks = get_installed_sdks() for _sdk in installed_sdks: sdk_bat_file = _sdk.get_sdk_vc_script(host_arch,target_arch) if not sdk_bat_file: - debug("vc.py:find_batch_file() not found:%s"%_sdk) + debug("find_batch_file() not found:%s"%_sdk) else: sdk_bat_file_path = os.path.join(pdir,sdk_bat_file) if os.path.exists(sdk_bat_file_path): - debug('vc.py:find_batch_file() sdk_bat_file_path:%s'%sdk_bat_file_path) - return (batfilename,sdk_bat_file_path) - return (batfilename,None) + debug('find_batch_file() sdk_bat_file_path:%s'%sdk_bat_file_path) + return (batfilename, sdk_bat_file_path) + return (batfilename, None) __INSTALLED_VCS_RUN = None @@ -592,21 +590,57 @@ def reset_installed_vcs(): # env2 = Environment(tools='msvs') # we can greatly improve the speed of the second and subsequent Environment # (or Clone) calls by memoizing the environment variables set by vcvars*.bat. -script_env_stdout_cache = {} +# +# Updated: by 2018, vcvarsall.bat had gotten so expensive (vs2017 era) +# it was breaking CI builds because the test suite starts scons so many +# times and the existing memo logic only helped with repeated calls +# within the same scons run. Windows builds on the CI system were split +# into chunks to get around single-build time limits. +# With VS2019 it got even slower and an optional persistent cache file +# was introduced. The cache now also stores only the parsed vars, +# not the entire output of running the batch file - saves a bit +# of time not parsing every time. + +script_env_cache = None + def script_env(script, args=None): - cache_key = (script, args) - stdout = script_env_stdout_cache.get(cache_key, None) - if stdout is None: + global script_env_cache + + if script_env_cache is None: + script_env_cache = common.read_script_env_cache() + cache_key = "{}--{}".format(script, args) + cache_data = script_env_cache.get(cache_key, None) + if cache_data is None: stdout = common.get_output(script, args) - script_env_stdout_cache[cache_key] = stdout - # Stupid batch files do not set return code: we take a look at the - # beginning of the output for an error message instead - olines = stdout.splitlines() - if olines[0].startswith("The specified configuration type is missing"): - raise BatchFileExecutionError("\n".join(olines[:2])) + # Stupid batch files do not set return code: we take a look at the + # beginning of the output for an error message instead + olines = stdout.splitlines() + if olines[0].startswith("The specified configuration type is missing"): + raise BatchFileExecutionError("\n".join(olines[:2])) + + cache_data = common.parse_output(stdout) + script_env_cache[cache_key] = cache_data + # once we updated cache, give a chance to write out if user wanted + common.write_script_env_cache(script_env_cache) + else: + #TODO: Python 2 cleanup + # If we "hit" data from the json file, we have a Py2 problem: + # keys & values will be unicode. don't detect, just convert. + if sys.version_info[0] == 2: + def convert(data): + if isinstance(data, basestring): + return str(data) + elif isinstance(data, collections.Mapping): + return dict(map(convert, data.iteritems())) + elif isinstance(data, collections.Iterable): + return type(data)(map(convert, data)) + else: + return data - return common.parse_output(stdout) + cache_data = convert(cache_data) + + return cache_data def get_default_version(env): debug('get_default_version()') @@ -635,12 +669,12 @@ def get_default_version(env): debug('installed_vcs:%s' % installed_vcs) if not installed_vcs: #msg = 'No installed VCs' - #debug('msv %s\n' % repr(msg)) + #debug('msv %s' % repr(msg)) #SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg) debug('msvc_setup_env: No installed VCs') return None msvc_version = installed_vcs[0] - debug('msvc_setup_env: using default installed MSVC version %s\n' % repr(msvc_version)) + debug('msvc_setup_env: using default installed MSVC version %s' % repr(msvc_version)) return msvc_version @@ -654,12 +688,12 @@ def msvc_setup_env_once(env): msvc_setup_env(env) env["MSVC_SETUP_RUN"] = True -def msvc_find_valid_batch_script(env,version): - debug('vc.py:msvc_find_valid_batch_script()') +def msvc_find_valid_batch_script(env, version): + debug('msvc_find_valid_batch_script()') # Find the host platform, target platform, and if present the requested # target platform platforms = get_host_target(env) - debug("vc.py: msvs_find_valid_batch_script(): host_platform %s, target_platform %s req_target_platform:%s" % platforms) + debug(" msvs_find_valid_batch_script(): host_platform %s, target_platform %s req_target_platform:%s" % platforms) host_platform, target_platform, req_target_platform = platforms try_target_archs = [target_platform] @@ -683,7 +717,7 @@ def msvc_find_valid_batch_script(env,version): # Set to current arch. env['TARGET_ARCH']=tp - debug("vc.py:msvc_find_valid_batch_script() trying target_platform:%s"%tp) + debug("msvc_find_valid_batch_script() trying target_platform:%s"%tp) host_target = (host_platform, tp) if not is_host_target_supported(host_target, version): warn_msg = "host, target = %s not supported for MSVC version %s" % \ @@ -701,8 +735,8 @@ def msvc_find_valid_batch_script(env,version): # Try to locate a batch file for this host/target platform combo try: - (vc_script,sdk_script) = find_batch_file(env,version,host_platform,tp) - debug('vc.py:msvc_find_valid_batch_script() vc_script:%s sdk_script:%s'%(vc_script,sdk_script)) + (vc_script, sdk_script) = find_batch_file(env, version, host_platform, tp) + debug('msvc_find_valid_batch_script() vc_script:%s sdk_script:%s'%(vc_script,sdk_script)) except VisualCException as e: msg = str(e) debug('Caught exception while looking for batch file (%s)' % msg) @@ -714,29 +748,29 @@ def msvc_find_valid_batch_script(env,version): continue # Try to use the located batch file for this host/target platform combo - debug('vc.py:msvc_find_valid_batch_script() use_script 2 %s, args:%s\n' % (repr(vc_script), arg)) + debug('msvc_find_valid_batch_script() use_script 2 %s, args:%s' % (repr(vc_script), arg)) found = None if vc_script: try: d = script_env(vc_script, args=arg) found = vc_script except BatchFileExecutionError as e: - debug('vc.py:msvc_find_valid_batch_script() use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e)) + debug('msvc_find_valid_batch_script() use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e)) vc_script=None continue if not vc_script and sdk_script: - debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script)) + debug('msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script)) try: d = script_env(sdk_script) found = sdk_script except BatchFileExecutionError as e: - debug('vc.py:msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e)) + debug('msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e)) continue elif not vc_script and not sdk_script: - debug('vc.py:msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found') + debug('msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found') continue - debug("vc.py:msvc_find_valid_batch_script() Found a working script/target: %s/%s"%(repr(found),arg)) + debug("msvc_find_valid_batch_script() Found a working script/target: %s/%s"%(repr(found),arg)) break # We've found a working target_platform, so stop looking # If we cannot find a viable installed compiler, reset the TARGET_ARCH @@ -756,7 +790,7 @@ def msvc_setup_env(env): "compilers most likely not set correctly" SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) return None - debug('msvc_setup_env: using specified MSVC version %s\n' % repr(version)) + debug('msvc_setup_env: using specified MSVC version %s' % repr(version)) # XXX: we set-up both MSVS version for backward # compatibility with the msvs tool @@ -767,11 +801,11 @@ def msvc_setup_env(env): use_script = env.get('MSVC_USE_SCRIPT', True) if SCons.Util.is_String(use_script): - debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script)) + debug('msvc_setup_env() use_script 1 %s' % repr(use_script)) d = script_env(use_script) elif use_script: d = msvc_find_valid_batch_script(env,version) - debug('vc.py:msvc_setup_env() use_script 2 %s\n' % d) + debug('msvc_setup_env() use_script 2 %s' % d) if not d: return d else: @@ -782,7 +816,7 @@ def msvc_setup_env(env): return None for k, v in d.items(): - debug('vc.py:msvc_setup_env() env:%s -> %s'%(k,v)) + debug('msvc_setup_env() env:%s -> %s'%(k,v)) env.PrependENVPath(k, v, delete_existing=True) # final check to issue a warning if the compiler is not present diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py index dfca48d..bac35d8 100644 --- a/src/engine/SCons/Tool/MSCommon/vs.py +++ b/src/engine/SCons/Tool/MSCommon/vs.py @@ -465,14 +465,14 @@ def get_vs_by_version(msvs): global InstalledVSMap global SupportedVSMap - debug('vs.py:get_vs_by_version()') + debug('get_vs_by_version()') if msvs not in SupportedVSMap: msg = "Visual Studio version %s is not supported" % repr(msvs) raise SCons.Errors.UserError(msg) get_installed_visual_studios() vs = InstalledVSMap.get(msvs) debug('InstalledVSMap:%s'%InstalledVSMap) - debug('vs.py:get_vs_by_version: found vs:%s'%vs) + debug('get_vs_by_version: found vs:%s'%vs) # Some check like this would let us provide a useful error message # if they try to set a Visual Studio version that's not installed. # However, we also want to be able to run tests (like the unit diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml index 69cc597..b6e5a43 100644 --- a/src/engine/SCons/Tool/__init__.xml +++ b/src/engine/SCons/Tool/__init__.xml @@ -468,7 +468,7 @@ as C++ files. Used to override &cv-link-SHLIBVERSION;/&cv-link-LDMODULEVERSION; when generating versioned import library for a shared library/loadable module. If undefined, the &cv-link-SHLIBVERSION;/&cv-link-LDMODULEVERSION; is used to -determine the version of versioned import library. +determine the version of versioned import library. </para> </summary> </cvar> @@ -476,7 +476,10 @@ determine the version of versioned import library. <cvar name="LIBEMITTER"> <summary> <para> -TODO +Contains the emitter specification for the +&b-link-StaticLibrary; builder. +The manpage section "Builder Objects" contains +general information on specifying emitters. </para> </summary> </cvar> @@ -494,10 +497,24 @@ format as &cv-link-SHLIBVERSION;. </summary> </cvar> +<cvar name="LDMODULEEMITTER"> +<summary> +<para> +Contains the emitter specification for the +&b-link-LoadableModule; builder. +The manpage section "Builder Objects" contains +general information on specifying emitters. +</para> +</summary> +</cvar> + <cvar name="SHLIBEMITTER"> <summary> <para> -TODO +Contains the emitter specification for the +&b-link-SharedLibrary; builder. +The manpage section "Builder Objects" contains +general information on specifying emitters. </para> </summary> </cvar> @@ -505,7 +522,10 @@ TODO <cvar name="PROGEMITTER"> <summary> <para> -TODO +Contains the emitter specification for the +&b-link-Program; builder. +The manpage section "Builder Objects" contains +general information on specifying emitters. </para> </summary> </cvar> @@ -514,7 +534,7 @@ TODO <summary> <para> When this construction variable is defined, a versioned shared library -is created by &b-link-SharedLibrary; builder. This activates the +is created by the &b-link-SharedLibrary; builder. This activates the &cv-link-_SHLIBVERSIONFLAGS; and thus modifies the &cv-link-SHLINKCOM; as required, adds the version number to the library name, and creates the symlinks that are needed. &cv-link-SHLIBVERSION; versions should exist as alpha-numeric, diff --git a/src/engine/SCons/Tool/cc.xml b/src/engine/SCons/Tool/cc.xml index 9330436..7ce8b36 100644 --- a/src/engine/SCons/Tool/cc.xml +++ b/src/engine/SCons/Tool/cc.xml @@ -26,7 +26,7 @@ See its __doc__ string for a discussion of the format. <tool name="cc"> <summary> <para> -Sets construction variables for generic POSIX C copmilers. +Sets construction variables for generic POSIX C compilers. </para> </summary> <sets> diff --git a/src/engine/SCons/Tool/default.xml b/src/engine/SCons/Tool/default.xml index 38eb122..4b862fb 100644 --- a/src/engine/SCons/Tool/default.xml +++ b/src/engine/SCons/Tool/default.xml @@ -26,10 +26,91 @@ See its __doc__ string for a discussion of the format. <tool name="default"> <summary> <para> -Sets variables by calling a default list of Tool modules -for the platform on which SCons is running. +Sets &consvars; for a default list of Tool modules. +Use <emphasis role="bold">default</emphasis> +in the tools list to retain the original defaults, +since the <parameter>tools</parameter> parameter +is treated as a literal statement of the tools +to be made available in that &consenv;, not an addition. </para> + +<para> +The list of tools selected by default is not static, +but is dependent both on +the platform and on the software installed on the platform. +Some tools will not initialize if an underlying command is +not found, and some tools are selected from a list of choices +on a first-found basis. The finished tool list can be +examined by inspecting the <envar>TOOLS</envar> &consvar; +in the &consenv;. +</para> + +<para> +On all platforms, all tools from the following list +are selected whose respective conditions are met: +filesystem, wix, lex, yacc, rpcgen, swig, +jar, javac, javah, rmic, dvipdf, dvips, gs, +tex, latex, pdflatex, pdftex, tar, zip, textfile. +</para> + +<para> +On Linux systems, the default tools list selects +(first-found): a C compiler from +gcc, intelc, icc, cc; +a C++ compiler from +g++, intelc, icc, cxx; +an assembler from +gas, nasm, masm; +a linker from +gnulink, ilink; +a Fortran compiler from +gfortran, g77, ifort, ifl, f95, f90, f77; +and a static archiver 'ar'. +It also selects all found from the list +m4, rpm. +</para> + +<para> +On Windows systems, the default tools list selects +(first-found): a C compiler from +msvc, mingw, gcc, intelc, icl, icc, cc, bcc32; +a C++ compiler from +msvc, intelc, icc, g++, cxx, bcc32; +an assembler from +masm, nasm, gas, 386asm; +a linker from +mslink, gnulink, ilink, linkloc, ilink32; +a Fortran compiler from +gfortran, g77, ifl, cvf, f95, f90, fortran; +and a static archiver from +mslib, ar, tlib; +It also selects all found from the list +msvs, midl. +</para> + +<para> +On MacOS systems, the default tools list selects +(first-found): a C compiler from +gcc, cc; +a C++ compiler from +g++, cxx; +an assembler 'as'; +a linker from +applelink, gnulink; +a Fortran compiler from +gfortran, f95, f90, g77; +and a static archiver ar. +It also selects all found from the list +m4, rpm. +</para> + +<para> +Default lists for other platforms can be found by +examining the &scons; +source code (see +<filename>SCons/Tool/__init__.py</filename>). +</para> + </summary> </tool> - </sconsdoc> diff --git a/src/engine/SCons/Tool/dmd.xml b/src/engine/SCons/Tool/dmd.xml index 7e220dc..a3620ce 100644 --- a/src/engine/SCons/Tool/dmd.xml +++ b/src/engine/SCons/Tool/dmd.xml @@ -73,299 +73,4 @@ Sets construction variables for D language compiler DMD. </uses> </tool> -<cvar name="DC"> -<summary> -<para> -The D compiler to use. -</para> -</summary> -</cvar> - -<cvar name="DCOM"> -<summary> -<para> - The command line used to compile a D file to an object file. - Any options specified in the &cv-link-DFLAGS; construction variable - is included on this command line. -</para> -</summary> -</cvar> - -<cvar name="DDEBUG"> -<summary> -<para> - List of debug tags to enable when compiling. -</para> -</summary> -</cvar> - -<cvar name="DFLAGS"> -<summary> -<para> - General options that are passed to the D compiler. -</para> -</summary> -</cvar> - -<cvar name="DLIB"> -<summary> -<para> - Name of the lib tool to use for D codes. -</para> -</summary> -</cvar> - -<cvar name="DLIBCOM"> -<summary> -<para> - The command line to use when creating libraries. -</para> -</summary> -</cvar> - -<cvar name="DLINK"> -<summary> -<para> - Name of the linker to use for linking systems including D sources. -</para> -</summary> -</cvar> - -<cvar name="DLINKCOM"> -<summary> -<para> - The command line to use when linking systems including D sources. -</para> -</summary> -</cvar> - -<cvar name="DLINKFLAGS"> -<summary> -<para> -List of linker flags. -</para> -</summary> -</cvar> - -<cvar name="DPATH"> -<summary> -<para> - List of paths to search for import modules. -</para> -</summary> -</cvar> - -<cvar name="DVERSIONS"> -<summary> -<para> - List of version tags to enable when compiling. -</para> -</summary> -</cvar> - -<cvar name="SHDC"> -<summary> -<para> - The name of the compiler to use when compiling D source - destined to be in a shared objects. -</para> -</summary> -</cvar> - -<cvar name="SHDCOM"> -<summary> -<para> - The command line to use when compiling code to be part of shared objects. -</para> -</summary> -</cvar> - -<cvar name="SHDLINK"> -<summary> -<para> - The linker to use when creating shared objects for code bases - include D sources. -</para> -</summary> -</cvar> - -<cvar name="SHDLINKCOM"> -<summary> -<para> - The command line to use when generating shared objects. -</para> -</summary> -</cvar> - -<cvar name="SHDLINKFLAGS"> -<summary> -<para> - The list of flags to use when generating a shared object. -</para> -</summary> -</cvar> - -<cvar name="DVERSUFFIX"> - <summary> - <para> - DVERSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DVERPREFIX"> - <summary> - <para> - DVERPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLINKFLAGSUFFIX"> - <summary> - <para> - DLINKFLAGSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLINKFLAGPREFIX"> - <summary> - <para> - DLINKFLAGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBLINKSUFFIX"> - <summary> - <para> - DLIBLINKSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBLINKPREFIX"> - <summary> - <para> - DLIBLINKPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBFLAGSUFFIX"> - <summary> - <para> - DLIBFLAGSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBFLAGPREFIX"> - <summary> - <para> - DLIBFLAGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBDIRSUFFIX"> - <summary> - <para> - DLIBLINKSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBDIRPREFIX"> - <summary> - <para> - DLIBLINKPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DINCSUFFIX"> - <summary> - <para> - DLIBFLAGSUFFIX. - </para> - </summary> -</cvar> - - -<cvar name="DINCPREFIX"> - <summary> - <para> - DINCPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DFLAGSUFFIX"> - <summary> - <para> - DFLAGSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DFLAGPREFIX"> - <summary> - <para> - DFLAGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DFILESUFFIX"> - <summary> - <para> - DFILESUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DDEBUGPREFIX"> - <summary> - <para> - DDEBUGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DDEBUGSUFFIX"> - <summary> - <para> - DDEBUGSUFFIX. - </para> - </summary> -</cvar> - -<builder name="ProgramAllAtOnce"> - <summary> - <para> - Builds an executable from D sources without first creating individual - objects for each file. - </para> - <para> - D sources can be compiled file-by-file as C and C++ source are, and - D is integrated into the &scons; Object and Program builders for - this model of build. D codes can though do whole source - meta-programming (some of the testing frameworks do this). For this - it is imperative that all sources are compiled and linked in a single call of - the D compiler. This builder serves that purpose. - </para> - <example_commands> - env.ProgramAllAtOnce('executable', ['mod_a.d, mod_b.d', 'mod_c.d']) - </example_commands> - <para> - This command will compile the modules mod_a, mod_b, and mod_c in a - single compilation process without first creating object files for - the modules. Some of the D compilers will create executable.o others - will not. - </para> - </summary> -</builder> - </sconsdoc> diff --git a/src/engine/SCons/Tool/gdc.xml b/src/engine/SCons/Tool/gdc.xml index d44489e..4c6c2f8 100644 --- a/src/engine/SCons/Tool/gdc.xml +++ b/src/engine/SCons/Tool/gdc.xml @@ -73,299 +73,4 @@ Sets construction variables for the D language compiler GDC. </uses> </tool> -<cvar name="DC"> -<summary> -<para> -The D compiler to use. -</para> -</summary> -</cvar> - -<cvar name="DCOM"> -<summary> -<para> - The command line used to compile a D file to an object file. - Any options specified in the &cv-link-DFLAGS; construction variable - is included on this command line. -</para> -</summary> -</cvar> - -<cvar name="DDEBUG"> -<summary> -<para> - List of debug tags to enable when compiling. -</para> -</summary> -</cvar> - -<cvar name="DFLAGS"> -<summary> -<para> - General options that are passed to the D compiler. -</para> -</summary> -</cvar> - -<cvar name="DLIB"> -<summary> -<para> - Name of the lib tool to use for D codes. -</para> -</summary> -</cvar> - -<cvar name="DLIBCOM"> -<summary> -<para> - The command line to use when creating libraries. -</para> -</summary> -</cvar> - -<cvar name="DLINK"> -<summary> -<para> - Name of the linker to use for linking systems including D sources. -</para> -</summary> -</cvar> - -<cvar name="DLINKCOM"> -<summary> -<para> - The command line to use when linking systems including D sources. -</para> -</summary> -</cvar> - -<cvar name="DLINKFLAGS"> -<summary> -<para> -List of linker flags. -</para> -</summary> -</cvar> - -<cvar name="DPATH"> -<summary> -<para> - List of paths to search for import modules. -</para> -</summary> -</cvar> - -<cvar name="DVERSIONS"> -<summary> -<para> - List of version tags to enable when compiling. -</para> -</summary> -</cvar> - -<cvar name="SHDC"> -<summary> -<para> - The name of the compiler to use when compiling D source - destined to be in a shared objects. -</para> -</summary> -</cvar> - -<cvar name="SHDCOM"> -<summary> -<para> - The command line to use when compiling code to be part of shared objects. -</para> -</summary> -</cvar> - -<cvar name="SHDLINK"> -<summary> -<para> - The linker to use when creating shared objects for code bases - include D sources. -</para> -</summary> -</cvar> - -<cvar name="SHDLINKCOM"> -<summary> -<para> - The command line to use when generating shared objects. -</para> -</summary> -</cvar> - -<cvar name="SHDLINKFLAGS"> -<summary> -<para> - The list of flags to use when generating a shared object. -</para> -</summary> -</cvar> - -<cvar name="DVERSUFFIX"> - <summary> - <para> - DVERSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DVERPREFIX"> - <summary> - <para> - DVERPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLINKFLAGSUFFIX"> - <summary> - <para> - DLINKFLAGSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLINKFLAGPREFIX"> - <summary> - <para> - DLINKFLAGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBLINKSUFFIX"> - <summary> - <para> - DLIBLINKSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBLINKPREFIX"> - <summary> - <para> - DLIBLINKPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBFLAGSUFFIX"> - <summary> - <para> - DLIBFLAGSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBFLAGPREFIX"> - <summary> - <para> - DLIBFLAGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBDIRSUFFIX"> - <summary> - <para> - DLIBLINKSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBDIRPREFIX"> - <summary> - <para> - DLIBLINKPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DINCSUFFIX"> - <summary> - <para> - DLIBFLAGSUFFIX. - </para> - </summary> -</cvar> - - -<cvar name="DINCPREFIX"> - <summary> - <para> - DINCPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DFLAGSUFFIX"> - <summary> - <para> - DFLAGSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DFLAGPREFIX"> - <summary> - <para> - DFLAGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DFILESUFFIX"> - <summary> - <para> - DFILESUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DDEBUGPREFIX"> - <summary> - <para> - DDEBUGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DDEBUGSUFFIX"> - <summary> - <para> - DDEBUGSUFFIX. - </para> - </summary> -</cvar> - -<builder name="ProgramAllAtOnce"> - <summary> - <para> - Builds an executable from D sources without first creating individual - objects for each file. - </para> - <para> - D sources can be compiled file-by-file as C and C++ source are, and - D is integrated into the &scons; Object and Program builders for - this model of build. D codes can though do whole source - meta-programming (some of the testing frameworks do this). For this - it is imperative that all sources are compiled and linked in a single call of - the D compiler. This builder serves that purpose. - </para> - <example_commands> - env.ProgramAllAtOnce('executable', ['mod_a.d, mod_b.d', 'mod_c.d']) - </example_commands> - <para> - This command will compile the modules mod_a, mod_b, and mod_c in a - single compilation process without first creating object files for - the modules. Some of the D compilers will create executable.o others - will not. - </para> - </summary> -</builder> - </sconsdoc> diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml index 6ae3e30..74169b3 100644 --- a/src/engine/SCons/Tool/install.xml +++ b/src/engine/SCons/Tool/install.xml @@ -52,6 +52,22 @@ a builder. <example_commands> env.Install('/usr/local/bin', source = ['foo', 'bar']) </example_commands> + +<para> +If the <option>--install-sandbox</option> command line +option is given, the target directory will be prefixed +by the directory path specified. +This is useful to test installs without installing to +a "live" location in the system. +</para> + +<para> +See also &FindInstalledFiles;. +For more thoughts on installation, see the User Guide +(particularly the section on Command-Line Targets +and the chapters on Installing Files and on Alias Targets). +</para> + </summary> </builder> diff --git a/src/engine/SCons/Tool/ldc.xml b/src/engine/SCons/Tool/ldc.xml index 495b8bc..6a80436 100644 --- a/src/engine/SCons/Tool/ldc.xml +++ b/src/engine/SCons/Tool/ldc.xml @@ -73,299 +73,4 @@ Sets construction variables for the D language compiler LDC2. </uses> </tool> -<cvar name="DC"> -<summary> -<para> -The D compiler to use. -</para> -</summary> -</cvar> - -<cvar name="DCOM"> -<summary> -<para> - The command line used to compile a D file to an object file. - Any options specified in the &cv-link-DFLAGS; construction variable - is included on this command line. -</para> -</summary> -</cvar> - -<cvar name="DDEBUG"> -<summary> -<para> - List of debug tags to enable when compiling. -</para> -</summary> -</cvar> - -<cvar name="DFLAGS"> -<summary> -<para> - General options that are passed to the D compiler. -</para> -</summary> -</cvar> - -<cvar name="DLIB"> -<summary> -<para> - Name of the lib tool to use for D codes. -</para> -</summary> -</cvar> - -<cvar name="DLIBCOM"> -<summary> -<para> - The command line to use when creating libraries. -</para> -</summary> -</cvar> - -<cvar name="DLINK"> -<summary> -<para> - Name of the linker to use for linking systems including D sources. -</para> -</summary> -</cvar> - -<cvar name="DLINKCOM"> -<summary> -<para> - The command line to use when linking systems including D sources. -</para> -</summary> -</cvar> - -<cvar name="DLINKFLAGS"> -<summary> -<para> -List of linker flags. -</para> -</summary> -</cvar> - -<cvar name="DPATH"> -<summary> -<para> - List of paths to search for import modules. -</para> -</summary> -</cvar> - -<cvar name="DVERSIONS"> -<summary> -<para> - List of version tags to enable when compiling. -</para> -</summary> -</cvar> - -<cvar name="SHDC"> -<summary> -<para> - The name of the compiler to use when compiling D source - destined to be in a shared objects. -</para> -</summary> -</cvar> - -<cvar name="SHDCOM"> -<summary> -<para> - The command line to use when compiling code to be part of shared objects. -</para> -</summary> -</cvar> - -<cvar name="SHDLINK"> -<summary> -<para> - The linker to use when creating shared objects for code bases - include D sources. -</para> -</summary> -</cvar> - -<cvar name="SHDLINKCOM"> -<summary> -<para> - The command line to use when generating shared objects. -</para> -</summary> -</cvar> - -<cvar name="SHDLINKFLAGS"> -<summary> -<para> - The list of flags to use when generating a shared object. -</para> -</summary> -</cvar> - -<cvar name="DVERSUFFIX"> - <summary> - <para> - DVERSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DVERPREFIX"> - <summary> - <para> - DVERPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLINKFLAGSUFFIX"> - <summary> - <para> - DLINKFLAGSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLINKFLAGPREFIX"> - <summary> - <para> - DLINKFLAGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBLINKSUFFIX"> - <summary> - <para> - DLIBLINKSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBLINKPREFIX"> - <summary> - <para> - DLIBLINKPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBFLAGSUFFIX"> - <summary> - <para> - DLIBFLAGSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBFLAGPREFIX"> - <summary> - <para> - DLIBFLAGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBDIRSUFFIX"> - <summary> - <para> - DLIBLINKSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DLIBDIRPREFIX"> - <summary> - <para> - DLIBLINKPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DINCSUFFIX"> - <summary> - <para> - DLIBFLAGSUFFIX. - </para> - </summary> -</cvar> - - -<cvar name="DINCPREFIX"> - <summary> - <para> - DINCPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DFLAGSUFFIX"> - <summary> - <para> - DFLAGSUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DFLAGPREFIX"> - <summary> - <para> - DFLAGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DFILESUFFIX"> - <summary> - <para> - DFILESUFFIX. - </para> - </summary> -</cvar> - -<cvar name="DDEBUGPREFIX"> - <summary> - <para> - DDEBUGPREFIX. - </para> - </summary> -</cvar> - -<cvar name="DDEBUGSUFFIX"> - <summary> - <para> - DDEBUGSUFFIX. - </para> - </summary> -</cvar> - -<builder name="ProgramAllAtOnce"> - <summary> - <para> - Builds an executable from D sources without first creating individual - objects for each file. - </para> - <para> - D sources can be compiled file-by-file as C and C++ source are, and - D is integrated into the &scons; Object and Program builders for - this model of build. D codes can though do whole source - meta-programming (some of the testing frameworks do this). For this - it is imperative that all sources are compiled and linked in a single call of - the D compiler. This builder serves that purpose. - </para> - <example_commands> - env.ProgramAllAtOnce('executable', ['mod_a.d, mod_b.d', 'mod_c.d']) - </example_commands> - <para> - This command will compile the modules mod_a, mod_b, and mod_c in a - single compilation process without first creating object files for - the modules. Some of the D compilers will create executable.o others - will not. - </para> - </summary> -</builder> - </sconsdoc> diff --git a/src/engine/SCons/Tool/link.xml b/src/engine/SCons/Tool/link.xml index 2f913fe..75b2ed8 100644 --- a/src/engine/SCons/Tool/link.xml +++ b/src/engine/SCons/Tool/link.xml @@ -26,7 +26,9 @@ See its __doc__ string for a discussion of the format. <tool name="link"> <summary> <para> -Sets construction variables for generic POSIX linkers. +Sets construction variables for generic POSIX linkers. This is +a "smart" linker tool which selects a compiler to complete the linking +based on the types of source files. </para> </summary> <sets> diff --git a/src/engine/SCons/Tool/midl.xml b/src/engine/SCons/Tool/midl.xml index efd83cc..63cf527 100644 --- a/src/engine/SCons/Tool/midl.xml +++ b/src/engine/SCons/Tool/midl.xml @@ -86,7 +86,7 @@ The command line used to pass files to the Microsoft IDL compiler. <summary> <para> The string displayed when -the Microsoft IDL copmiler is called. +the Microsoft IDL compiler is called. If this is not set, then &cv-link-MIDLCOM; (the command line) is displayed. </para> </summary> diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index d27294b..7dca9e1 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -652,7 +652,7 @@ class _GenerateV6DSP(_DSPGenerator): for base in ("BASE ",""): self.file.write('# PROP %sUse_MFC 0\n' '# PROP %sUse_Debug_Libraries ' % (base, base)) - if kind.lower().find('debug') < 0: + if 'debug' not in kind.lower(): self.file.write('0\n') else: self.file.write('1\n') @@ -731,7 +731,7 @@ class _GenerateV6DSP(_DSPGenerator): line = dspfile.readline() # skip until marker while line: - if line.find("# End Project") > -1: + if "# End Project" in line: break line = dspfile.readline() @@ -1049,7 +1049,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): line = dspfile.readline() # skip until marker while line: - if line.find('<!-- SCons Data:') > -1: + if '<!-- SCons Data:' in line: break line = dspfile.readline() diff --git a/src/engine/SCons/Tool/suncxx.py b/src/engine/SCons/Tool/suncxx.py index 9ac8d32..090df7d 100644 --- a/src/engine/SCons/Tool/suncxx.py +++ b/src/engine/SCons/Tool/suncxx.py @@ -74,7 +74,7 @@ def get_package_info(package_name, pkginfo, pkgchk): except EnvironmentError: pass else: - pkginfo_contents = p.communicate()[0] + pkginfo_contents = p.communicate()[0].decode() version_re = re.compile(r'^ *VERSION:\s*(.*)$', re.M) version_match = version_re.search(pkginfo_contents) if version_match: @@ -88,7 +88,7 @@ def get_package_info(package_name, pkginfo, pkgchk): except EnvironmentError: pass else: - pkgchk_contents = p.communicate()[0] + pkgchk_contents = p.communicate()[0].decode() pathname_re = re.compile(r'^Pathname:\s*(.*/bin/CC)$', re.M) pathname_match = pathname_re.search(pkgchk_contents) if pathname_match: diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index 6ed9d82..f139a09 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -80,7 +80,7 @@ def _find_modules(src): for m in matches: mnames.append(m[2]) - directors = directors or m[0].find('directors') >= 0 + directors = directors or 'directors' in m[0] return mnames, directors def _add_director_header_targets(target, env): diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py index a5b257b..718b3d5 100644 --- a/src/engine/SCons/Warnings.py +++ b/src/engine/SCons/Warnings.py @@ -132,12 +132,6 @@ class DeprecatedCopyWarning(MandatoryDeprecatedWarning): class DeprecatedOptionsWarning(MandatoryDeprecatedWarning): pass -class DeprecatedSourceSignaturesWarning(MandatoryDeprecatedWarning): - pass - -class DeprecatedTargetSignaturesWarning(MandatoryDeprecatedWarning): - pass - class DeprecatedDebugOptionsWarning(MandatoryDeprecatedWarning): pass diff --git a/src/script/scons-time.py b/src/script/scons-time.py index a7120c9..62d2784 100644 --- a/src/script/scons-time.py +++ b/src/script/scons-time.py @@ -274,8 +274,6 @@ class SConsTimer(object): return kw default_settings = makedict( - aegis = 'aegis', - aegis_project = None, chdir = None, config_file = None, initial_commands = [], @@ -1113,7 +1111,6 @@ class SConsTimer(object): help = """\ Usage: scons-time run [OPTIONS] [FILE ...] - --aegis=PROJECT Use SCons from the Aegis PROJECT --chdir=DIR Name of unpacked directory for chdir -f FILE, --file=FILE Read configuration from specified FILE -h, --help Print this help and exit @@ -1138,7 +1135,6 @@ class SConsTimer(object): short_opts = '?f:hnp:qs:v' long_opts = [ - 'aegis=', 'file=', 'help', 'no-exec', @@ -1157,9 +1153,7 @@ class SConsTimer(object): opts, args = getopt.getopt(argv[1:], short_opts, long_opts) for o, a in opts: - if o in ('--aegis',): - self.aegis_project = a - elif o in ('-f', '--file'): + if o in ('-f', '--file'): self.config_file = a elif o in ('-?', '-h', '--help'): self.do_help(['help', 'run']) @@ -1211,8 +1205,6 @@ class SConsTimer(object): prepare = None if self.subversion_url: prepare = self.prep_subversion_run - elif self.aegis_project: - prepare = self.prep_aegis_run for run_number in run_number_list: self.individual_run(run_number, self.archive_list, prepare) @@ -1234,20 +1226,6 @@ class SConsTimer(object): def scons_lib_dir_path(self, dir): return os.path.join(dir, 'src', 'engine') - def prep_aegis_run(self, commands, removals): - self.aegis_tmpdir = tempfile.mkdtemp(prefix=self.name + '-aegis-') - removals.append((shutil.rmtree, 'rm -rf %%s', self.aegis_tmpdir)) - - self.aegis_parent_project = os.path.splitext(self.aegis_project)[0] - self.scons = self.scons_path(self.aegis_tmpdir) - self.scons_lib_dir = self.scons_lib_dir_path(self.aegis_tmpdir) - - commands.extend([ - (lambda: os.chdir(self.aegis_tmpdir), 'cd %(aegis_tmpdir)s'), - '%(aegis)s -cp -ind -p %(aegis_parent_project)s .', - '%(aegis)s -cp -ind -p %(aegis_project)s -delta %(run_number)s .', - ]) - def prep_subversion_run(self, commands, removals): self.svn_tmpdir = tempfile.mkdtemp(prefix=self.name + '-svn-') removals.append((shutil.rmtree, 'rm -rf %%s', self.svn_tmpdir)) diff --git a/src/test_setup.py b/src/test_setup.py index 09865f5..d9fa5b5 100644 --- a/src/test_setup.py +++ b/src/test_setup.py @@ -176,7 +176,7 @@ tar_gz = os.path.join(cwd, 'build', 'dist', '%s.tar.gz' % scons_version) zip = os.path.join(cwd, 'build', 'dist', '%s.zip' % scons_version) if os.path.isfile(zip): - try: + try: import zipfile except ImportError: pass @@ -185,9 +185,9 @@ if os.path.isfile(zip): for name in zf.namelist(): dname = os.path.dirname(name) - try: + try: os.makedirs(dname) - except FileExistsError: + except FileExistsError: pass # if the file exists, then delete it before writing # to it so that we don't end up trying to write to a symlink: @@ -325,8 +325,7 @@ test.must_have_installed(test.man_page_paths()) other_prefix = test.workpath('other-prefix') test.subdir(other_prefix) test.run(arguments = 'setup.py install --prefix=%s' % other_prefix) -test.fail_test(test.stderr().find("you'll have to change the search path yourself") - != -1) +test.fail_test("you'll have to change the search path yourself" in test.stderr()) # All done. test.pass_test() diff --git a/test/Configure/config-h.py b/test/Configure/config-h.py index a5c1998..405f259 100644 --- a/test/Configure/config-h.py +++ b/test/Configure/config-h.py @@ -46,25 +46,27 @@ env.AppendENVPath('PATH', os.environ['PATH']) conf = Configure(env, config_h = 'config.h') r1 = conf.CheckFunc('printf') r2 = conf.CheckFunc('noFunctionCall') -r3 = conf.CheckType('int') -r4 = conf.CheckType('noType') -r5 = conf.CheckCHeader('stdio.h', '<>') -r6 = conf.CheckCHeader('hopefullynoc-header.h') -r7 = conf.CheckCXXHeader('vector', '<>') -r8 = conf.CheckCXXHeader('hopefullynocxx-header.h') +r3 = conf.CheckFunc('memmove') +r4 = conf.CheckType('int') +r5 = conf.CheckType('noType') +r6 = conf.CheckCHeader('stdio.h', '<>') +r7 = conf.CheckCHeader('hopefullynoc-header.h') +r8 = conf.CheckCXXHeader('vector', '<>') +r9 = conf.CheckCXXHeader('hopefullynocxx-header.h') env = conf.Finish() conf = Configure(env, config_h = 'config.h') -r9 = conf.CheckLib('%(lib)s', 'sin') -r10 = conf.CheckLib('hopefullynolib', 'sin') -r11 = conf.CheckLibWithHeader('%(lib)s', 'math.h', 'c') -r12 = conf.CheckLibWithHeader('%(lib)s', 'hopefullynoheader2.h', 'c') -r13 = conf.CheckLibWithHeader('hopefullynolib2', 'math.h', 'c') +r10 = conf.CheckLib('%(lib)s', 'sin') +r11 = conf.CheckLib('hopefullynolib', 'sin') +r12 = conf.CheckLibWithHeader('%(lib)s', 'math.h', 'c') +r13 = conf.CheckLibWithHeader('%(lib)s', 'hopefullynoheader2.h', 'c') +r14 = conf.CheckLibWithHeader('hopefullynolib2', 'math.h', 'c') env = conf.Finish() """ % locals()) expected_read_str = """\ Checking for C function printf()... yes Checking for C function noFunctionCall()... no +Checking for C function memmove()... yes Checking for C type int... yes Checking for C type noType... no Checking for C header file stdio.h... yes @@ -96,6 +98,9 @@ expected_config_h = ("""\ /* Define to 1 if the system has the function `noFunctionCall'. */ /* #undef HAVE_NOFUNCTIONCALL */ +/* Define to 1 if the system has the function `memmove'. */ +#define HAVE_MEMMOVE 1 + /* Define to 1 if the system has the type `int'. */ #define HAVE_INT 1 diff --git a/test/Configure/option--config.py b/test/Configure/option--config.py index 02f10ce..838409d 100644 --- a/test/Configure/option--config.py +++ b/test/Configure/option--config.py @@ -126,8 +126,6 @@ test.checkLogAndStdout(["Checking for C header file non_system_header0.h... ", test.file_fixture('test_main.c') # Check the combination of --config=force and Decider('MD5-timestamp') -# On second run there was an issue where the decider would throw DeciderNeedsNode -# exception which the configure code didn't handle. SConstruct_path = test.workpath('SConstruct') test.write(SConstruct_path, """ env = Environment() @@ -146,7 +144,7 @@ test.must_not_contain(test.workpath('config.log'), "TypeError: 'NoneType' object # This fixes an issue where --config=force overwrites the Environments decider and is not reset when # the configure context is done. # https://github.com/SCons/scons/issues/3303 -test.fail_test(test.stdout().find('test_main.o') != -1) +test.fail_test('test_main.o' in test.stdout()) test.pass_test() diff --git a/test/Decider/MD5-timestamp-explain.py b/test/Decider/MD5-timestamp-explain.py new file mode 100644 index 0000000..357d924 --- /dev/null +++ b/test/Decider/MD5-timestamp-explain.py @@ -0,0 +1,56 @@ +#!/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__" + +""" +Verify behavior of the MD5-timestamp Decider() setting. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.write('SConstruct', """\ +import random +env = Environment() +env.Decider('MD5-timestamp') +# for testing use raw python API +with open("hello.h.in","w") as outfile: + outfile.write("// {}".format(random.randint(1,100))) +env.Command("hello.h","hello.h.in",[Copy("$TARGET","$SOURCE")]) +""") + + +test.run(arguments = '--debug=explain') +# this should not be up-to-date and it should not crash +test.not_up_to_date(arguments = '--debug=explain') + +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-dtree.py b/test/Deprecated/debug-dtree.py deleted file mode 100644 index 1e7366f..0000000 --- a/test/Deprecated/debug-dtree.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -""" -Test that the --debug=dtree option correctly prints just the explicit -dependencies (sources or Depends()) of a target. -""" - -import TestSCons - -test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) - -test.write('SConstruct', """ -env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx') -env.Program('foo', Split('foo.c bar.c')) -""") - -test.write('foo.c', r""" -#include <stdio.h> -#include <stdlib.h> -#include "foo.h" -int main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("f1.c\n"); - exit (0); -} -""") - -test.write('bar.c', """ -#include "bar.h" -int local = 1; -""") - -test.write('foo.h', """ -#ifndef FOO_H -#define FOO_H -#include "bar.h" -#endif -""") - -test.write('bar.h', """ -#ifndef BAR_H -#define BAR_H -#include "foo.h" -#endif -""") - -expect = """ -scons: warning: The --debug=dtree option is deprecated; please use --tree=derived instead. -""" - -stderr = TestSCons.re_escape(expect) + TestSCons.file_expr - -dtree1 = """ -+-foo.xxx - +-foo.ooo - +-bar.ooo -""" - -test.run(arguments = "--debug=dtree foo.xxx", - stderr = stderr) -test.must_contain_all_lines(test.stdout(), [dtree1]) - -dtree2 = """ -+-. - +-bar.ooo - +-foo.ooo - +-foo.xxx - +-foo.ooo - +-bar.ooo -""" -test.run(arguments = "--debug=dtree .", - stderr = stderr) -test.must_contain_all_lines(test.stdout(), [dtree2]) - -# Make sure we print the debug stuff even if there's a build failure. -test.write('bar.h', """ -#ifndef BAR_H -#define BAR_H -#include "foo.h" -#endif -THIS SHOULD CAUSE A BUILD FAILURE -""") - -test.run(arguments = "--debug=dtree foo.xxx", - status = 2, - stderr = None) -test.must_contain_all_lines(test.stdout(), [dtree1]) - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Deprecated/debug-stree.py b/test/Deprecated/debug-stree.py deleted file mode 100644 index 907dedf..0000000 --- a/test/Deprecated/debug-stree.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -""" -Test that the --debug=stree option prints a dependency tree with output -that indicates the state of various Node status flags. -""" - -import TestSCons - -test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) - -CC = test.detect('CC') -LINK = test.detect('LINK') -if LINK is None: LINK = CC - -test.write('SConstruct', """ -env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx') -env.Program('foo', Split('foo.c bar.c')) -""") - -test.write('foo.c', r""" -#include <stdio.h> -#include <stdlib.h> -#include "foo.h" -int main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("f1.c\n"); - exit (0); -} -""") - -test.write('bar.c', """ -#include "bar.h" -int local = 1; -""") - -test.write('foo.h', """ -#ifndef FOO_H -#define FOO_H -#include "bar.h" -#endif -""") - -test.write('bar.h', """ -#ifndef BAR_H -#define BAR_H -#include "foo.h" -#endif -""") - -expect = """ -scons: warning: The --debug=stree option is deprecated; please use --tree=all,status instead. -""" - -stderr = TestSCons.re_escape(expect) + TestSCons.file_expr - -stree = """ -[E B C ]+-foo.xxx -[E B C ] +-foo.ooo -[E C ] | +-foo.c -[E C ] | +-foo.h -[E C ] | +-bar.h -[E C ] | +-%(CC)s -[E B C ] +-bar.ooo -[E C ] | +-bar.c -[E C ] | +-bar.h -[E C ] | +-foo.h -[E C ] | +-%(CC)s -[E C ] +-%(LINK)s -""" % locals() - -test.run(arguments = "--debug=stree foo.xxx", - stderr = stderr) -test.fail_test(test.stdout().count(stree) != 1) - -stree2 = """ - E = exists - R = exists in repository only - b = implicit builder - B = explicit builder - S = side effect - P = precious - A = always build - C = current - N = no clean - H = no cache - -[ B ]+-foo.xxx -[ B ] +-foo.ooo -[E C ] | +-foo.c -[E C ] | +-foo.h -[E C ] | +-bar.h -[E C ] | +-%(CC)s -[ B ] +-bar.ooo -[E C ] | +-bar.c -[E C ] | +-bar.h -[E C ] | +-foo.h -[E C ] | +-%(CC)s -[E C ] +-%(LINK)s -""" % locals() - -test.run(arguments = '-c foo.xxx') - -test.run(arguments = "--no-exec --debug=stree foo.xxx", - stderr = stderr) -test.fail_test(test.stdout().count(stree2) != 1) - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Deprecated/debug-tree.py b/test/Deprecated/debug-tree.py deleted file mode 100644 index 51ff7f2..0000000 --- a/test/Deprecated/debug-tree.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -""" -Test that the --debug=tree option prints a tree representation of the -complete dependencies of a target. -""" - -import TestSCons - -test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) - -CC = test.detect('CC') -LINK = test.detect('LINK') -if LINK is None: LINK = CC - -test.write('SConstruct', """ -env = Environment(OBJSUFFIX = '.ooo', PROGSUFFIX = '.xxx') -env.Program('Foo', Split('Foo.c Bar.c')) -""") - -# N.B.: We use upper-case file names (Foo* and Bar*) so that the sorting -# order with our upper-case SConstruct file is the same on case-sensitive -# (UNIX/Linux) and case-insensitive (Windows) systems. - -test.write('Foo.c', r""" -#include <stdio.h> -#include <stdlib.h> -#include "Foo.h" -int main(int argc, char *argv[]) -{ - argv[argc++] = "--"; - printf("f1.c\n"); - exit (0); -} -""") - -test.write('Bar.c', """ -#include "Bar.h" -int local = 1; -""") - -test.write('Foo.h', """ -#ifndef FOO_H -#define FOO_H -#include "Bar.h" -#endif -""") - -test.write('Bar.h', """ -#ifndef BAR_H -#define BAR_H -#include "Foo.h" -#endif -""") - -expect = """ -scons: warning: The --debug=tree option is deprecated; please use --tree=all instead. -""" - -stderr = TestSCons.re_escape(expect) + TestSCons.file_expr - -tree1 = """ -+-Foo.xxx - +-Foo.ooo - | +-Foo.c - | +-Foo.h - | +-Bar.h - | +-%(CC)s - +-Bar.ooo - | +-Bar.c - | +-Bar.h - | +-Foo.h - | +-%(CC)s - +-%(LINK)s -""" % locals() - -test.run(arguments = "--debug=tree Foo.xxx", - stderr = stderr) -test.must_contain_all_lines(test.stdout(), tree1) - -tree2 = """ -+-. - +-Bar.c - +-Bar.h - +-Bar.ooo - | +-Bar.c - | +-Bar.h - | +-Foo.h - | +-%(CC)s - +-Foo.c - +-Foo.h - +-Foo.ooo - | +-Foo.c - | +-Foo.h - | +-Bar.h - | +-%(CC)s - +-Foo.xxx - | +-Foo.ooo - | | +-Foo.c - | | +-Foo.h - | | +-Bar.h - | | +-%(CC)s - | +-Bar.ooo - | | +-Bar.c - | | +-Bar.h - | | +-Foo.h - | | +-%(CC)s - | +-%(LINK)s - +-SConstruct -""" % locals() - -test.run(arguments = "--debug=tree .", - stderr = stderr) -test.must_contain_all_lines(test.stdout(), tree2) - -# Make sure we print the debug stuff even if there's a build failure. -test.write('Bar.h', """ -#ifndef BAR_H -#define BAR_H -#include "Foo.h" -#endif -THIS SHOULD CAUSE A BUILD FAILURE -""") - -test.run(arguments = "--debug=tree Foo.xxx", - status = 2, - stderr = None) -test.must_contain_all_lines(test.stdout(), tree1) - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Errors/execute-a-directory.py b/test/Errors/execute-a-directory.py index 1d2036e..95fa7b6 100644 --- a/test/Errors/execute-a-directory.py +++ b/test/Errors/execute-a-directory.py @@ -55,34 +55,34 @@ Bad command or file name unrecognized = """\ '.+' is not recognized as an internal or external command, operable program or batch file. -scons: \*\*\* \[%s\] Error 1 +scons: \\*\\*\\* \\[%s\\] Error 1 """ unspecified = """\ The name specified is not recognized as an internal or external command, operable program or batch file. -scons: \*\*\* \[%s\] Error 1 +scons: \\*\\*\\* \\[%s\\] Error 1 """ cannot_execute = """\ (sh: )*.+: cannot execute -scons: \*\*\* \[%s\] Error %s +scons: \\*\\*\\* \\[%s\\] Error %s """ permission_denied = """\ .+: (p|P)ermission denied -scons: \*\*\* \[%s\] Error %s +scons: \\*\\*\\* \\[%s\\] Error %s """ is_a_directory = """\ .+: (i|I)s a directory -scons: \*\*\* \[%s\] Error %s +scons: \\*\\*\\* \\[%s\\] Error %s """ konnte_nicht_gefunden_werden = """\ Der Befehl ".+" ist entweder falsch geschrieben oder konnte nicht gefunden werden. -scons: \*\*\* \[%s\] Error %s +scons: \\*\\*\\* \\[%s\\] Error %s """ test.description_set("Incorrect STDERR:\n%s\n" % test.stderr()) diff --git a/test/Errors/non-executable-file.py b/test/Errors/non-executable-file.py index e1b8f4e..0e00c77 100644 --- a/test/Errors/non-executable-file.py +++ b/test/Errors/non-executable-file.py @@ -44,29 +44,29 @@ Bad command or file name unrecognized = """\ '.+' is not recognized as an internal or external command, operable program or batch file. -scons: \*\*\* \[%s\] Error 1 +scons: \\*\\*\\* \\[%s\\] Error 1 """ unspecified = """\ The name specified is not recognized as an internal or external command, operable program or batch file. -scons: \*\*\* \[%s\] Error 1 +scons: \\*\\*\\* \\[%s\\] Error 1 """ cannot_execute = """\ (sh: )*.+: cannot execute -scons: \*\*\* \[%s\] Error %s +scons: \\*\\*\\* \\[%s\\] Error %s """ permission_denied = """\ .+: (p|P)ermission denied -scons: \*\*\* \[%s\] Error %s +scons: \\*\\*\\* \\[%s\\] Error %s """ konnte_nicht_gefunden_werden = """\ Der Befehl ".+" ist entweder falsch geschrieben oder konnte nicht gefunden werden. -scons: \*\*\* \[%s\] Error %s +scons: \\*\\*\\* \\[%s\\] Error %s """ test.write('SConstruct', r""" diff --git a/test/Interactive/shell.py b/test/Interactive/shell.py index 40df86f..dd13504 100644 --- a/test/Interactive/shell.py +++ b/test/Interactive/shell.py @@ -89,8 +89,8 @@ if sys.platform == 'win32': else: no_such_error = 'scons: no_such_command: No such file or directory' -expect_stdout = """\ -scons>>> Copy\("foo.out", "foo.in"\) +expect_stdout = \ +r"""scons>>> Copy\("foo.out", "foo.in"\) Touch\("1"\) scons>>> hello from shell_command.py scons>>> ![^"]+ ".*" diff --git a/test/Interactive/tree.py b/test/Interactive/tree.py index 61faa22..c10962a 100644 --- a/test/Interactive/tree.py +++ b/test/Interactive/tree.py @@ -69,23 +69,6 @@ test.must_match(test.workpath('foo.out'), "foo.in 2\n") -scons.send("build --debug=tree foo.out\n") - -expect_stdout = """\ -scons>>> Copy("foo.out", "foo.in") -scons>>> Touch("1") -scons>>> Copy("foo.out", "foo.in") -+-foo.out - +-foo.in -scons>>> Touch("2") -scons>>> scons: `foo.out' is up to date. -scons>>> -""" - -test.finish(scons, stdout = expect_stdout) - - - test.pass_test() # Local Variables: diff --git a/test/Interactive/version.py b/test/Interactive/version.py index d0f362a..88416ad 100644 --- a/test/Interactive/version.py +++ b/test/Interactive/version.py @@ -40,7 +40,7 @@ test.write('SConstruct', "") # Standard copyright marker is mangled so it doesn't get replaced # by the packaging build. copyright_line = """\ -(_{2}COPYRIGHT__|Copyright \\(c\\) 2001[-\d, ]+ The SCons Foundation) +(_{2}COPYRIGHT__|Copyright \\(c\\) 2001[-\\d, ]+ The SCons Foundation) """ expect1 = """\ @@ -53,8 +53,8 @@ scons>>> scons>>> """ -test.run(arguments = '-Q --interactive', - stdin = "version\nexit\n") +test.run(arguments='-Q --interactive', + stdin="version\nexit\n") # Windows may or may not print a line for the script version # depending on whether it's invoked through scons.py or scons.bat. diff --git a/test/Java/JARFLAGS.py b/test/Java/JARFLAGS.py index 39a0a6c..6983bf7 100644 --- a/test/Java/JARFLAGS.py +++ b/test/Java/JARFLAGS.py @@ -59,10 +59,10 @@ public class Example1 """) expect = test.wrap_stdout("""\ -javac -d classes -sourcepath src src.Example1\.java -jar cvf test.jar -C classes src.Example1\.class +javac -d classes -sourcepath src src.Example1\\.java +jar cvf test.jar -C classes src.Example1\\.class .* -adding: src.Example1\.class.* +adding: src.Example1\\.class.* """ % locals()) diff --git a/test/Java/JAVABOOTCLASSPATH.py b/test/Java/JAVABOOTCLASSPATH.py index 196cc54..8aaf869 100644 --- a/test/Java/JAVABOOTCLASSPATH.py +++ b/test/Java/JAVABOOTCLASSPATH.py @@ -84,8 +84,8 @@ public class Example2 bootclasspath = os.pathsep.join(['dir1', 'dir2']) expect = """\ -javac -bootclasspath %(bootclasspath)s -d class -sourcepath com com.Example1\.java -javac -bootclasspath %(bootclasspath)s -d class -sourcepath com com.Example2\.java +javac -bootclasspath %(bootclasspath)s -d class -sourcepath com com.Example1\\.java +javac -bootclasspath %(bootclasspath)s -d class -sourcepath com com.Example2\\.java """ % locals() test.run(arguments = '-Q -n .', stdout = expect, match=TestSCons.match_re) diff --git a/test/Java/RMIC.py b/test/Java/RMIC.py index c8848e9..67135b9 100644 --- a/test/Java/RMIC.py +++ b/test/Java/RMIC.py @@ -95,7 +95,7 @@ line 3 where_javac, java_version = test.java_where_javac() where_rmic = test.java_where_rmic() -# Try to get the major/minor Java version +# Try to get the major/minor Java version curver = (1, 0) if java_version.count('.') == 1: # Check Java version @@ -138,7 +138,7 @@ bar_classes = bar.Java(target = 'class2', source = 'com/sub/bar') # XXX This is kind of a Python brute-force way to do what Ant # does with its "excludes" attribute. We should probably find # a similar friendlier way to do this. -bar_classes = [c for c in bar_classes if str(c).find('Hello') == -1] +bar_classes = [c for c in bar_classes if 'Hello' not in str(c)] bar.RMIC(target = Dir('outdir2'), source = bar_classes) """ % locals() ) @@ -149,7 +149,7 @@ bar.RMIC(target = Dir('outdir2'), source = bar_classes) ['com', 'sub', 'bar'], 'src3a', 'src3b') - + test.write(['com', 'sub', 'foo', 'Hello.java'], """\ package com.sub.foo; @@ -329,16 +329,16 @@ public class Example4 extends UnicastRemoteObject implements Hello { """) test.run(arguments = '.') - + test.must_match('wrapper.out', "wrapper_with_args.py rmic -d outdir2 -classpath class2 com.sub.bar.Example3 com.sub.bar.Example4\n", mode='r') - + test.must_exist(test.workpath('outdir1', 'com', 'sub', 'foo', 'Example1_Stub.class')) test.must_exist(test.workpath('outdir1', 'com', 'sub', 'foo', 'Example2_Stub.class')) test.must_exist(test.workpath('outdir2', 'com', 'sub', 'bar', 'Example3_Stub.class')) test.must_exist(test.workpath('outdir2', 'com', 'sub', 'bar', 'Example4_Stub.class')) - + # We used to check for _Skel.class files as well, but they're not # generated by default starting with Java 1.5, and they apparently # haven't been needed for a while. Don't bother looking, even if we're @@ -348,7 +348,7 @@ public class Example4 extends UnicastRemoteObject implements Hello { #test.must_exist(test.workpath('outdir1', 'com', 'sub', 'foo', 'Example2_Skel.class')) #test.must_exist(test.workpath('outdir2', 'com', 'sub', 'bar', 'Example3_Skel.class')) #test.must_exist(test.workpath('outdir2', 'com', 'sub', 'bar', 'Example4_Skel.class')) - + test.up_to_date(arguments = '.') test.pass_test() 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/MSVS/vs-14.2-exec.py b/test/MSVS/vs-14.2-exec.py new file mode 100644 index 0000000..1894031 --- /dev/null +++ b/test/MSVS/vs-14.2-exec.py @@ -0,0 +1,114 @@ +#!/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 we can actually build a simple program using our generated +Visual Studio 14.0 project (.vcxproj) and solution (.sln) files +using Visual Studio 14.2 +""" + +import os +import sys + +import TestSConsMSVS + +test = TestSConsMSVS.TestSConsMSVS() + +if sys.platform != 'win32': + msg = "Skipping Visual Studio test on non-Windows platform '%s'\n" % sys.platform + test.skip_test(msg) + +msvs_version = '14.2' + +if not msvs_version in test.msvs_versions(): + msg = "Visual Studio %s not installed; skipping test.\n" % msvs_version + test.skip_test(msg) + + + +# Let SCons figure out the Visual Studio environment variables for us and +# print out a statement that we can exec to suck them into our external +# environment so we can execute devenv and really try to build something. + +test.run(arguments = '-n -q -Q -f -', stdin = """\ +env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s') +if env.WhereIs('cl'): + print("os.environ.update(%%s)" %% repr(env['ENV'])) +""" % locals()) + +if(test.stdout() == ""): + msg = "Visual Studio %s missing cl.exe; skipping test.\n" % msvs_version + test.skip_test(msg) + +exec(test.stdout()) + + + +test.subdir('sub dir') + +test.write(['sub dir', 'SConstruct'], """\ +env=Environment(MSVS_VERSION = '%(msvs_version)s') + +env.MSVSProject(target = 'foo.vcxproj', + srcs = ['foo.c'], + buildtarget = 'foo.exe', + variant = 'Release', + DebugSettings = {'LocalDebuggerCommandArguments':'echo "<foo.c>" > output.txt'}) +env.Program('foo.c') +""" % locals()) + +test.write(['sub dir', 'foo.c'], r""" +int +main(int argc, char *argv) +{ + printf("foo.c\n"); + exit (0); +} +""") + +test.run(chdir='sub dir', arguments='.') + +test.vcproj_sys_path(test.workpath('sub dir', 'foo.vcxproj')) + +import SCons.Platform.win32 +system_dll_path = os.path.join( SCons.Platform.win32.get_system_root(), 'System32' ) +os.environ['PATH'] = os.environ['PATH'] + os.pathsep + system_dll_path + +test.run(chdir='sub dir', + program=[test.get_msvs_executable(msvs_version)], + arguments=['foo.sln', '/build', 'Release']) + +test.run(program=test.workpath('sub dir', 'foo'), stdout="foo.c\n") +test.validate_msvs_file(test.workpath('sub dir', 'foo.vcxproj.user')) + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/QT/installed.py b/test/QT/installed.py index 2661377..c3ba168 100644 --- a/test/QT/installed.py +++ b/test/QT/installed.py @@ -42,7 +42,7 @@ if not os.environ.get('QTDIR', None): test.Qt_dummy_installation() QTDIR=os.environ['QTDIR'] - + test.write('SConstruct', """\ import os @@ -109,17 +109,17 @@ class MyClass2 : public QObject { }; void mocFromH(); """) - + test.write('mocFromH.cpp', """\ #include "mocFromH.h" - + MyClass2::MyClass2() : QObject() {} void MyClass2::myslot() {} void mocFromH() { MyClass2 myclass; } """) - + test.write('anUiFile.ui', """\ <!DOCTYPE UI><UI> <class>MyWidget</class> @@ -158,7 +158,7 @@ test.write('main.cpp', r""" #include "mocFromH.h" #include "anUiFile.h" #include <stdio.h> - + int main(int argc, char **argv) { QApplication app(argc, argv); mocFromCpp(); @@ -190,7 +190,7 @@ if test.stdout() != "Hello World\n" or test.stderr() != '' or test.status: # an indication that it built correctly) but don't fail the test. expect = 'cannot connect to X server' test.fail_test(test.stdout()) - test.fail_test(test.stderr().find(expect) == -1) + test.fail_test(expect not in test.stderr()) if test.status != 1 and (test.status>>8) != 1: sys.stdout.write('test_realqt returned status %s\n' % test.status) test.fail_test() @@ -205,8 +205,8 @@ test.run(stderr=None, arguments="-c bld/test_realqt" + TestSCons._exe) expect1 = "scons: warning: Could not detect qt, using empty QTDIR" expect2 = "scons: warning: Could not detect qt, using moc executable as a hint" -test.fail_test(test.stderr().find(expect1) == -1 and - test.stderr().find(expect2) == -1) +test.fail_test(expect1 not in test.stderr() and + expect2 not in test.stderr()) test.pass_test() diff --git a/test/Removed/CacheDir/Old/sconstest.skip b/test/Removed/CacheDir/Old/sconstest.skip new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Removed/CacheDir/Old/sconstest.skip diff --git a/test/Deprecated/CacheDir/timestamp-content.py b/test/Removed/CacheDir/Old/timestamp-content.py index 860d0f3..860d0f3 100644 --- a/test/Deprecated/CacheDir/timestamp-content.py +++ b/test/Removed/CacheDir/Old/timestamp-content.py diff --git a/test/Deprecated/CacheDir/timestamp-timestamp.py b/test/Removed/CacheDir/Old/timestamp-timestamp.py index eec70b5..eec70b5 100644 --- a/test/Deprecated/CacheDir/timestamp-timestamp.py +++ b/test/Removed/CacheDir/Old/timestamp-timestamp.py diff --git a/test/Removed/CacheDir/README.md b/test/Removed/CacheDir/README.md new file mode 100644 index 0000000..c5b75bf --- /dev/null +++ b/test/Removed/CacheDir/README.md @@ -0,0 +1,4 @@ +CacheDir/Old contains old tests of CacheDir which used the now removed +SourceSignatures and TargetSignatures methods, preserved here for +reference; the presence of an scontest.skip file means they are never +executed. diff --git a/test/Deprecated/SourceSignatures/basic.py b/test/Removed/SourceSignatures/Old/basic.py index 7951dbd..7951dbd 100644 --- a/test/Deprecated/SourceSignatures/basic.py +++ b/test/Removed/SourceSignatures/Old/basic.py diff --git a/test/Deprecated/SourceSignatures/env.py b/test/Removed/SourceSignatures/Old/env.py index c63b176..bf86d4d 100644 --- a/test/Deprecated/SourceSignatures/env.py +++ b/test/Removed/SourceSignatures/Old/env.py @@ -29,7 +29,6 @@ Test that use of env.SourceSignatures() correctly overrides the default behavior. """ -import os import re import TestSCons diff --git a/test/Deprecated/SourceSignatures/implicit-cache.py b/test/Removed/SourceSignatures/Old/implicit-cache.py index a4bdc78..a4bdc78 100644 --- a/test/Deprecated/SourceSignatures/implicit-cache.py +++ b/test/Removed/SourceSignatures/Old/implicit-cache.py diff --git a/test/Deprecated/SourceSignatures/no-csigs.py b/test/Removed/SourceSignatures/Old/no-csigs.py index c4f2a78..60c0460 100644 --- a/test/Deprecated/SourceSignatures/no-csigs.py +++ b/test/Removed/SourceSignatures/Old/no-csigs.py @@ -25,8 +25,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import os - import TestSCons import TestSConsign diff --git a/test/Deprecated/SourceSignatures/overrides.py b/test/Removed/SourceSignatures/Old/overrides.py index 4303c0e..4303c0e 100644 --- a/test/Deprecated/SourceSignatures/overrides.py +++ b/test/Removed/SourceSignatures/Old/overrides.py diff --git a/test/Removed/SourceSignatures/Old/sconstest.skip b/test/Removed/SourceSignatures/Old/sconstest.skip new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Removed/SourceSignatures/Old/sconstest.skip diff --git a/test/Deprecated/SourceSignatures/switch-rebuild.py b/test/Removed/SourceSignatures/Old/switch-rebuild.py index b9cc3d5..b9cc3d5 100644 --- a/test/Deprecated/SourceSignatures/switch-rebuild.py +++ b/test/Removed/SourceSignatures/Old/switch-rebuild.py diff --git a/test/Removed/SourceSignatures/README.md b/test/Removed/SourceSignatures/README.md new file mode 100644 index 0000000..05d8d05 --- /dev/null +++ b/test/Removed/SourceSignatures/README.md @@ -0,0 +1,6 @@ +SourceSignatures.py is the "new" test, only makes sure scons actually +fails in the presence of the method or setoption call. + +The Old directory is the former tests from the deprecated state, +preserved here for reference; the presence of an scontest.skip file +means they are never executed. diff --git a/test/Removed/SourceSignatures/SConstruct.method b/test/Removed/SourceSignatures/SConstruct.method new file mode 100644 index 0000000..e68d6bf --- /dev/null +++ b/test/Removed/SourceSignatures/SConstruct.method @@ -0,0 +1 @@ +SourceSignatures('MD5') diff --git a/test/Removed/SourceSignatures/SConstruct.setopt b/test/Removed/SourceSignatures/SConstruct.setopt new file mode 100644 index 0000000..6e1161f --- /dev/null +++ b/test/Removed/SourceSignatures/SConstruct.setopt @@ -0,0 +1 @@ +SetOption('warn', 'deprecated-source-signatures') diff --git a/test/Removed/SourceSignatures/SourceSignatures.py b/test/Removed/SourceSignatures/SourceSignatures.py new file mode 100644 index 0000000..014c163 --- /dev/null +++ b/test/Removed/SourceSignatures/SourceSignatures.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 SourceSignatures and its associated warning flag +are definitely gone. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.file_fixture('SConstruct.method', 'SConstruct') +expect = """\ +NameError: name 'SourceSignatures' is not defined: + File "{}", line 1: + SourceSignatures('MD5') +""".format(test.workpath('SConstruct')) +test.run(arguments='-Q -s', status=2, stdout=None, stderr=expect) + +test.file_fixture('SConstruct.setopt', 'SConstruct') +test.run(arguments='-Q -s', status=0, stdout=None, + stderr="""\ +No warning type: 'deprecated-source-signatures' +No warning type: 'deprecated-source-signatures' +""") + +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/TargetSignatures/build-content.py b/test/Removed/TargetSignatures/Old/build-content.py index efdaaee..efdaaee 100644 --- a/test/Deprecated/TargetSignatures/build-content.py +++ b/test/Removed/TargetSignatures/Old/build-content.py diff --git a/test/Deprecated/TargetSignatures/content.py b/test/Removed/TargetSignatures/Old/content.py index aca63f3..aca63f3 100644 --- a/test/Deprecated/TargetSignatures/content.py +++ b/test/Removed/TargetSignatures/Old/content.py diff --git a/test/Deprecated/TargetSignatures/overrides.py b/test/Removed/TargetSignatures/Old/overrides.py index 54a66d4..54a66d4 100644 --- a/test/Deprecated/TargetSignatures/overrides.py +++ b/test/Removed/TargetSignatures/Old/overrides.py diff --git a/test/Removed/TargetSignatures/Old/sconstest.skip b/test/Removed/TargetSignatures/Old/sconstest.skip new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Removed/TargetSignatures/Old/sconstest.skip diff --git a/test/Removed/TargetSignatures/README.md b/test/Removed/TargetSignatures/README.md new file mode 100644 index 0000000..00a8b6b --- /dev/null +++ b/test/Removed/TargetSignatures/README.md @@ -0,0 +1,6 @@ +TargetSignatures.py is the "new" test, only makes sure scons actually +fails in the presence of the method or setoption call. + +The Old directory is the former tests from the deprecated state, +preserved here for reference; the presence of an scontest.skip file +means they are never executed. diff --git a/test/Removed/TargetSignatures/SConstruct.method b/test/Removed/TargetSignatures/SConstruct.method new file mode 100644 index 0000000..5e974b6 --- /dev/null +++ b/test/Removed/TargetSignatures/SConstruct.method @@ -0,0 +1 @@ +TargetSignatures('MD5') diff --git a/test/Removed/TargetSignatures/SConstruct.setopt b/test/Removed/TargetSignatures/SConstruct.setopt new file mode 100644 index 0000000..c887ce4 --- /dev/null +++ b/test/Removed/TargetSignatures/SConstruct.setopt @@ -0,0 +1 @@ +SetOption('warn', 'deprecated-target-signatures') diff --git a/test/Removed/TargetSignatures/TargetSignatures.py b/test/Removed/TargetSignatures/TargetSignatures.py new file mode 100644 index 0000000..889f992 --- /dev/null +++ b/test/Removed/TargetSignatures/TargetSignatures.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 TargetSignatures and its associated warning flag +are definitely gone. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.file_fixture('SConstruct.method', 'SConstruct') +expect = """\ +NameError: name 'TargetSignatures' is not defined: + File "{}", line 1: + TargetSignatures('MD5') +""".format(test.workpath('SConstruct')) +test.run(arguments='-Q -s', status=2, stdout=None, stderr=expect) + +test.file_fixture('SConstruct.setopt', 'SConstruct') +test.run(arguments="-Q -s", status=0, stdout=None, + stderr="""\ +No warning type: 'deprecated-target-signatures' +No warning type: 'deprecated-target-signatures' +""") + +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..06287de --- /dev/null +++ b/test/Removed/debug-tree.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Test that the --debug=tree option fails with expected exception +Check command-line, SCONSFLAGS and interactive +""" + +import os + +import TestSCons + +test = TestSCons.TestSCons() + + +test.write('SConstruct', "") + +expect = r"""usage: scons [OPTION] [TARGET] ... + +SCons Error: `tree' is not a valid debug option type ; please use --tree=all instead +""" + +test.run(arguments='-Q --debug=tree', status=2, stderr=expect) + +os.environ['SCONSFLAGS'] = '--debug=tree' +test.run(arguments="-H", status=2, stderr=expect) + + +# moved test from test/Interactive/tree.py +scons = test.start(arguments = '-Q --interactive') +scons.send("build --debug=tree\n") +test.finish(scons, status=2, stderr=expect) + + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Repository/RMIC.py b/test/Repository/RMIC.py index aa4a57e..7c37dd9 100644 --- a/test/Repository/RMIC.py +++ b/test/Repository/RMIC.py @@ -37,7 +37,7 @@ test = TestSCons.TestSCons() where_javac, java_version = test.java_where_javac() -# Try to get the major/minor Java version +# Try to get the major/minor Java version curver = (1, 0) if java_version.count('.') == 1: # Check Java version @@ -97,7 +97,7 @@ env = Environment(tools = ['javac', 'rmic'], RMIC = r'"%s"') classes = env.Java(target = 'classes', source = 'src') # Brute-force removal of the "Hello" class. -classes = [c for c in classes if str(c).find('Hello') == -1] +classes = [c for c in classes if 'Hello' not in str(c)] env.RMIC(target = 'outdir', source = classes) """ % (javac, rmic)) @@ -365,7 +365,7 @@ env = Environment(tools = ['javac', 'rmic'], RMIC = r'"%s"') classes = env.Java(target = 'classes', source = 'src') # Brute-force removal of the "Hello" class. -classes = [c for c in classes if str(c).find('Hello') == -1] +classes = [c for c in classes if 'Hello' not in str(c)] rmi_classes = env.RMIC(target = 'outdir', source = classes) Local(rmi_classes) """ % (javac, rmic)) diff --git a/test/Scanner/CrossLanguageNoExtension.py b/test/Scanner/CrossLanguageNoExtension.py index 0016ca5..fa38d2f 100644 --- a/test/Scanner/CrossLanguageNoExtension.py +++ b/test/Scanner/CrossLanguageNoExtension.py @@ -34,7 +34,7 @@ test = TestSCons.TestSCons() # for nodes that do not have mappings from their scanner_key # to a scanner instance -test.write('SConstruct', """ +test.write('SConstruct', r""" import re include_re = re.compile(r'^include\s+(\S+)$', re.M) @@ -77,7 +77,7 @@ env2.Append(SCANNERS = [ k2scan2 ] ) env2.Command( 'k2', 'foo.k', Copy( '$TARGET', '$SOURCE' ) ) """) -test.write('foo.k', +test.write('foo.k', """foo.k 1 line 1 include xxx.k include yyy diff --git a/test/Scanner/FindPathDirs.py b/test/Scanner/FindPathDirs.py index 34eb779..3f5204a 100644 --- a/test/Scanner/FindPathDirs.py +++ b/test/Scanner/FindPathDirs.py @@ -71,7 +71,7 @@ test.write('SConstruct', """\ SConscript('SConscript') """) -test.write('SConscript', """\ +test.write('SConscript', r""" import os.path import re @@ -86,7 +86,7 @@ def kfile_scan(node, env, path, arg): for inc in includes: for dir in path: file = str(dir) + os.sep + inc - if os.path.exists(file): + if os.path.exists(file): results.append(file) break return results @@ -109,7 +109,7 @@ env.Command('foo', 'foo.k', r'%(_python_)s build.py "$KPATH" $SOURCES $TARGET') -test.write('foo.k', +test.write('foo.k', """foo.k 1 line 1 include xxx include yyy diff --git a/test/Scanner/Scanner.py b/test/Scanner/Scanner.py index 272f26a..7e39134 100644 --- a/test/Scanner/Scanner.py +++ b/test/Scanner/Scanner.py @@ -60,7 +60,7 @@ test.write('SConstruct', """ SConscript('SConscript') """, mode='w') -test.write('SConscript', """ +test.write('SConscript', r""" import re include_re = re.compile(r'^include\s+(\S+)\s*$', re.M) @@ -137,7 +137,7 @@ Alias('make_ork', ork) """ % locals(),mode='w') -test.write('foo.k', +test.write('foo.k', """foo.k 1 line 1 include xxx include yyy @@ -151,7 +151,7 @@ bar.in 1 line 3 include zzz """, mode='w') -test.write('junk.k2', +test.write('junk.k2', """include yyy junk.k2 1 line 2 junk.k2 1 line 3 diff --git a/test/Scanner/dictionary.py b/test/Scanner/dictionary.py index efe3cd2..f80c7e5 100644 --- a/test/Scanner/dictionary.py +++ b/test/Scanner/dictionary.py @@ -61,7 +61,7 @@ test.write('SConstruct', """ SConscript('SConscript') """) -test.write('SConscript', """ +test.write('SConscript', r""" import re include1_re = re.compile(r'^include1\s+(\S+)$', re.M) @@ -100,7 +100,7 @@ env.Command('bbb', 'bbb.k2', r'%(_python_)s build.py $SOURCES $TARGET') env.Command('ccc', 'ccc.k3', r'%(_python_)s build.py $SOURCES $TARGET') """ % locals()) -test.write('aaa.k1', +test.write('aaa.k1', """aaa.k1 1 line 2 include1 xxx @@ -109,7 +109,7 @@ include3 zzz line 6 """) -test.write('bbb.k2', +test.write('bbb.k2', """bbb.k2 1 line 2 include1 xxx @@ -118,7 +118,7 @@ include3 zzz line 6 """) -test.write('ccc.k3', +test.write('ccc.k3', """ccc.k3 1 line 2 include1 xxx diff --git a/test/Scanner/exception.py b/test/Scanner/exception.py index ec19842..90791cb 100644 --- a/test/Scanner/exception.py +++ b/test/Scanner/exception.py @@ -37,7 +37,7 @@ test.write('SConstruct', """ SConscript('SConscript') """) -test.write('SConscript', """ +test.write('SConscript', r""" import re include_re = re.compile(r'^include\s+(\S+)$', re.M) @@ -82,14 +82,14 @@ bar_in = File('bar.in') env.Cat('bar', bar_in) """) -test.write('foo.k', +test.write('foo.k', """foo.k 1 line 1 include xxx include yyy foo.k 1 line 4 """) -test.write('bar.in', +test.write('bar.in', """include yyy bar.in 1 line 2 bar.in 1 line 3 diff --git a/test/Scanner/generated.py b/test/Scanner/generated.py index 5e808e1..f0fb0cc 100644 --- a/test/Scanner/generated.py +++ b/test/Scanner/generated.py @@ -188,7 +188,7 @@ env = env.Clone() # Yes, clobber intentionally """) -test.write(['src', 'lib_geng', 'SConscript'], """\ +test.write(['src', 'lib_geng', 'SConscript'], r""" # --- Begin SConscript boilerplate --- import sys import Mylib @@ -280,7 +280,7 @@ env.Command(generated_hdrs.split(), cmd_generated) recurse_env.Command([lib_fullname] + lib_objs, lib_srcs + (generated_hdrs + " " + static_hdrs).split(), - cmd_justlib) + cmd_justlib) """) test.write(['src', 'lib_geng', 'MAKE-HEADER.py'], """\ @@ -395,7 +395,7 @@ int g_1() test.write(['src', 'lib_geng', 'libg_2.c'], """\ #include <libg_w.h> -#include <libg_gx.h> +#include <libg_gx.h> #include <libg_gy.h> #include <libg_gz.h> diff --git a/test/Scanner/multi-env.py b/test/Scanner/multi-env.py index 1cc85d0..e9c231d 100644 --- a/test/Scanner/multi-env.py +++ b/test/Scanner/multi-env.py @@ -37,7 +37,7 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() -test.write('SConstruct', """ +test.write('SConstruct', r""" import re include_re = re.compile(r'^include\s+(\S+)$', re.M) diff --git a/test/Scanner/no-Dir-node.py b/test/Scanner/no-Dir-node.py index a230ea6..ef90934 100644 --- a/test/Scanner/no-Dir-node.py +++ b/test/Scanner/no-Dir-node.py @@ -89,7 +89,7 @@ Command('list.out', 'subdir', foo, source_scanner = DirScanner) SConscript('subdir/SConscript') """) -test.write(['subdir', 'SConscript'], """\ +test.write(['subdir', 'SConscript'], r""" import SCons.Scanner kscan = SCons.Scanner.Classic(name = 'kfile', suffixes = ['.k'], diff --git a/test/Scanner/source_scanner-dict.py b/test/Scanner/source_scanner-dict.py index f719f00..115c19e 100644 --- a/test/Scanner/source_scanner-dict.py +++ b/test/Scanner/source_scanner-dict.py @@ -65,7 +65,7 @@ test.write('SConstruct', """ SConscript('SConscript') """) -test.write('SConscript', """ +test.write('SConscript', r""" import re include1_re = re.compile(r'^include1\s+(\S+)$', re.M) @@ -101,7 +101,7 @@ env.Build('ccc', 'ccc.k3') env.Build('ddd', ['ddd.k4', 'aaa.k1', 'bbb.k2', 'ccc.k3']) """ % locals()) -test.write('aaa.k1', +test.write('aaa.k1', """aaa.k1 1 line 2 include1 xxx @@ -110,7 +110,7 @@ include3 zzz line 6 """) -test.write('bbb.k2', +test.write('bbb.k2', """bbb.k2 1 line 2 include1 xxx @@ -119,7 +119,7 @@ include3 zzz line 6 """) -test.write('ccc.k3', +test.write('ccc.k3', """ccc.k3 1 line 2 include1 xxx @@ -128,7 +128,7 @@ include3 zzz line 6 """) -test.write('ddd.k4', +test.write('ddd.k4', """ddd.k4 1 line 2 line 3 diff --git a/test/Scanner/unicode.py b/test/Scanner/unicode.py index 227c72e..0edd5b6 100644 --- a/test/Scanner/unicode.py +++ b/test/Scanner/unicode.py @@ -77,7 +77,7 @@ with open(sys.argv[2], 'w') as ofp: sys.exit(0) """) -test.write('SConstruct', """ +test.write('SConstruct', r""" import re include_re = re.compile(r'^include\s+(\S+)$', re.M) diff --git a/test/Deprecated/debug-nomemoizer.py b/test/Subst/bug3428.py index 6d05cb2..00587e6 100644 --- a/test/Deprecated/debug-nomemoizer.py +++ b/test/Subst/bug3428.py @@ -25,30 +25,26 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ -Test calling the (deprecated) --debug=nomemoizer option. +Verify that CmdStringHolder doesn't trip in Subst on doing +a string-only operation that does not work on UserString class. +Issue: https://github.com/SCons/scons/issues/3428 """ import TestSCons -test = TestSCons.TestSCons(match = TestSCons.match_re) +test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) -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.write('SConstruct', """\ +env = Environment() +env.Append(LIBPATH=["path1/sub1","path1/sub2"]) +lst = env.Flatten(env.subst_list("$LIBPATH")) +for i in lst: + env.Dir(i) +""") -test.run(arguments = "--debug=nomemoizer", stderr = expect) +test.run(status=0) -test.must_match('file.out', "file.in\n") test.pass_test() diff --git a/test/TaskMaster/bug_2811/fixture_dir/SConstruct b/test/TaskMaster/bug_2811/fixture_dir/SConstruct index c124902..d453368 100644 --- a/test/TaskMaster/bug_2811/fixture_dir/SConstruct +++ b/test/TaskMaster/bug_2811/fixture_dir/SConstruct @@ -10,6 +10,7 @@ This issue requires the following. Nth target's implicit lists changing when compared to SConsign's which have been loaded. 7. This forces rebuild of source file and this propagates to massive recompile """ +import sys import SCons.Tool @@ -27,12 +28,15 @@ def _dwo_emitter(target, source, env): targets = target + new_targets return (targets, source) +build_string = '$MYCOPY $SOURCE $TARGET' -bld = Builder(action='cp $SOURCE $TARGET') -env = Environment(BUILDERS={'Foo': bld}) +bld = Builder(action=build_string) + +env = Environment(BUILDERS={'Foo': bld}, MYCOPY="%s mycopy.py"%sys.executable) + +env['SHCCCOM'] = '$MYCOPY $SOURCE $TARGET && $MYCOPY $SOURCE ${TARGETS[1]}' -env['SHCCCOM'] = 'cp $SOURCE $TARGET && cp $SOURCE ${TARGETS[1]}' env['SHCCCOMSTR'] = env['SHCCCOM'] diff --git a/test/TaskMaster/bug_2811/fixture_dir/mycopy.py b/test/TaskMaster/bug_2811/fixture_dir/mycopy.py new file mode 100644 index 0000000..c1a57f5 --- /dev/null +++ b/test/TaskMaster/bug_2811/fixture_dir/mycopy.py @@ -0,0 +1,8 @@ +import sys +import shutil + +ffrom = sys.argv[1] +to = sys.argv[2] +shutil.copyfile(ffrom, to) + +sys.exit(0) diff --git a/test/Win32/mingw.py b/test/Win32/mingw.py index 80067bc..ca31f6b 100644 --- a/test/Win32/mingw.py +++ b/test/Win32/mingw.py @@ -52,7 +52,7 @@ sys.exit(0) """) test.run() -if test.stdout().find('mingw exists') == -1: +if 'mingw exists' not in test.stdout(): test.skip_test("No MinGW on this system, skipping test.\n") test.subdir('header') @@ -76,8 +76,8 @@ void shared_func(void); void static_func(void); extern "C" void cshared_func(void); -int main(void) -{ +int main(void) +{ printf("%s\\n", "test.cpp"); shared_func(); static_func(); @@ -95,7 +95,7 @@ test.write('resource.rc', ''' #include "resource.h" #include <resource2.h> -STRINGTABLE DISCARDABLE +STRINGTABLE DISCARDABLE BEGIN IDS_TEST RESOURCE_RC END @@ -148,8 +148,8 @@ test.write('header/resource2.h', ''' # that comes out of stderr: test.run(arguments='test.exe', stderr='.*') # ensure the source def for cshared.def got used, and there wasn't a target def for chshared.dll: -test.fail_test(test.stdout().find('cshared.def') == -1) -test.fail_test(test.stdout().find('-Wl,--output-def,cshared.def') != -1) +test.fail_test('cshared.def' not in test.stdout()) +test.fail_test('-Wl,--output-def,cshared.def' in test.stdout()) # ensure the target def got generated for the shared.dll: test.fail_test(not os.path.exists(test.workpath('cshared.def'))) test.fail_test(os.path.exists(test.workpath('shared.def'))) @@ -176,8 +176,8 @@ test.write('test.cpp', ''' void shared_func(void); -int main(void) -{ +int main(void) +{ printf("%s\\n", "test.cpp2"); shared_func(); return 0; 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/fixture/SConstruct_test_main.py b/test/fixture/SConstruct_test_main.py new file mode 100644 index 0000000..8d2d2b0 --- /dev/null +++ b/test/fixture/SConstruct_test_main.py @@ -0,0 +1,3 @@ +DefaultEnvironment(tools=[]) +env = Environment() +env.Program('main.exe', ['main.c']) diff --git a/test/implicit-cache/basic.py b/test/implicit-cache/basic.py index c03a320..7eece88 100644 --- a/test/implicit-cache/basic.py +++ b/test/implicit-cache/basic.py @@ -27,11 +27,8 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify basic interactions of the --implicit-cache-* options. -This test used to set TargetSignatures('build') because we were -relying on the old behavior of non-essential changes in .h files -propagate to cause a rebuilt executable. We now just rely on -the default Decider('content') behavior and only check for the -rebuild of the object file itself when necessary. +We rely on the default Decider('content') behavior and only +check for the rebuild of the object file itself when necessary. """ import os.path diff --git a/test/import.py b/test/import.py index 9799850..2725705 100644 --- a/test/import.py +++ b/test/import.py @@ -114,8 +114,8 @@ scons: warning: Can't find Intel compiler top dir for version='None', abi='[^']* """ + TestSCons.file_expr # Intel no license directory warning -intel_license_warning = re.escape(""" -scons: warning: Intel license dir was not found. Tried using the INTEL_LICENSE_FILE environment variable (), the registry () and the default path (C:\Program Files\Common Files\Intel\Licenses). Using the default path as a last resort. +intel_license_warning = re.escape( +r"""scons: warning: Intel license dir was not found. Tried using the INTEL_LICENSE_FILE environment variable (), the registry () and the default path (C:\Program Files\Common Files\Intel\Licenses). Using the default path as a last resort. """) + TestSCons.file_expr intel_warnings = [ diff --git a/test/option--tree.py b/test/option--tree.py index 0bf2c06..1b34176 100644 --- a/test/option--tree.py +++ b/test/option--tree.py @@ -45,13 +45,6 @@ SCons Error: `foofoo' is not a valid --tree option type, try: """, status=2) -test.run(arguments='--debug=tree', - stderr=""" -scons: warning: The --debug=tree option is deprecated; please use --tree=all instead. -.* -""", - status=0, match=TestSCons.match_re_dotall) - # Test that unicode characters can be printed (escaped) with the --tree option test.write('SConstruct', diff --git a/test/option-v.py b/test/option-v.py index 4a67df0..ed8c4e5 100644 --- a/test/option-v.py +++ b/test/option-v.py @@ -35,7 +35,7 @@ test.write('SConstruct', "") # Standard copyright marker is mangled so it doesn't get replaced # by the packaging build. copyright_line = """\ -(_{2}COPYRIGHT__|Copyright \\(c\\) 2001[-\d, ]+ The SCons Foundation) +(_{2}COPYRIGHT__|Copyright \\(c\\) 2001[-\\d, ]+ The SCons Foundation) """ # Windows may or may not print a line for the script version @@ -64,7 +64,7 @@ if not test.match_re(stdout, expect1) and not test.match_re(stdout, expect2): test.fail_test() test.pass_test() - + # Local Variables: # tab-width:4 diff --git a/test/option/debug-action-timestamps.py b/test/option/debug-action-timestamps.py new file mode 100644 index 0000000..0277516 --- /dev/null +++ b/test/option/debug-action-timestamps.py @@ -0,0 +1,101 @@ +#!/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. +from __future__ import division, print_function + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons +import re + +_python_ = TestSCons._python_ + +def setup_fixtures(): + test.file_fixture('../fixture/test_main.c', 'main.c') + test.file_fixture('../fixture/SConstruct_test_main.py', 'SConstruct') + +def test_help_function(): + # Before anything else, make sure we get valid --debug=action_timestamps results + # when just running the help option. + test.run(arguments = "-h --debug=action_timestamps") + +def build(): + # Execute build + test.run(arguments='--debug=action_timestamps') + build_output = test.stdout() + return build_output + +def get_matches_from_output(build_output): + return [re.findall(pattern, build_output) for pattern in debug_time_patterns] + +def test_presence_of_debug_time_strings(build_output): + # Check presence of duration and timestamps + if None in get_matches_from_output(build_output): + print("One or more of the time debug strings were not found in the build output") + test.fail_test(1) + +def test_equal_number_of_debug_time_strings(build_output): + matches = get_matches_from_output(build_output) + num_of_matches = [len(match) for match in matches] + + # Check that the number of matches for each pattern is the same + if num_of_matches.count(num_of_matches[0]) != len(num_of_matches): + print("Debug time strings differs in quantity") + test.fail_test(2) + +def test_correctness_of_timestamps(build_output): + # Check if difference between timestamps is equal to duration + matches = get_matches_from_output(build_output) + + def match_to_float(m): + return float(m[1][1]) + + execution_time = match_to_float(matches[0]) + start_time = match_to_float(matches[1]) + stop_time = match_to_float(matches[2]) + delta_time = stop_time - start_time + + def within_tolerance(expected, actual, tolerance): + return abs((expected-actual)/actual) <= tolerance + + if not within_tolerance(execution_time, delta_time, 0.001): + print("Difference of timestamps differ from action duration") + print("Execution time = {}. Start time = {}. Stop time = {}. Delta time = {}".format(execution_time, start_time, stop_time, delta_time)) + test.fail_test(3) + +debug_time_patterns = [ + r'Command execution time: (.*): (\d+\.\d+) seconds', + r'Command execution start time: (.*): (\d+\.\d+) seconds', + r'Command execution stop time: (.*): (\d+\.\d+) seconds' +] + +test = TestSCons.TestSCons() +setup_fixtures() + +test_help_function() + +build_output = build() +test_presence_of_debug_time_strings(build_output) +test_equal_number_of_debug_time_strings(build_output) +test_correctness_of_timestamps(build_output) + +test.pass_test() diff --git a/test/packaging/guess-package-name.py b/test/packaging/guess-package-name.py index 8ba4c9e..1786c11 100644 --- a/test/packaging/guess-package-name.py +++ b/test/packaging/guess-package-name.py @@ -33,6 +33,8 @@ Also overriding this default package name is tested Furthermore that targz is the default packager is tested. """ +import sys + import TestSCons python = TestSCons.python @@ -88,8 +90,12 @@ test.must_exist('src.tar.gz') # # TEST: default package name creation with overridden packager. # +# Windows 10 since at least 1803 supplies bsdtar, so tool +# detection will find it - but doesn't supply bzip2, so a +# test using it will fail. As a hack, just skip. -test.write('SConstruct', """ +if sys.platform != 'win32': + test.write('SConstruct', """ env=Environment(tools=['default', 'packaging']) env.Program( 'src/main.c' ) env.Package( NAME = 'libfoo', @@ -98,15 +104,19 @@ env.Package( NAME = 'libfoo', source = [ 'src/main.c', 'SConstruct' ] ) """) -test.run(stderr=None) + test.run(stderr=None) -test.must_exist('libfoo-1.2.3.tar.bz2') + test.must_exist('libfoo-1.2.3.tar.bz2') # # TEST: default package name creation with another packager. # +# Windows 10 since at least 1803 supplies bsdtar, so tool +# detection will find it - but it doesn't support xz +# compression so test using it will fail. As a hack, just skip. -test.write('SConstruct', """ +if sys.platform != 'win32': + test.write('SConstruct', """ env=Environment(tools=['default', 'packaging']) env.Program( 'src/main.c' ) env.Package( NAME = 'libfoo', @@ -115,9 +125,9 @@ env.Package( NAME = 'libfoo', source = [ 'src/main.c', 'SConstruct' ] ) """) -test.run(stderr=None) + test.run(stderr=None) -test.must_exist('libfoo-1.2.3.tar.xz') + test.must_exist('libfoo-1.2.3.tar.xz') test.pass_test() diff --git a/test/packaging/rpm/explicit-target.py b/test/packaging/rpm/explicit-target.py index 48b5c83..fba0237 100644 --- a/test/packaging/rpm/explicit-target.py +++ b/test/packaging/rpm/explicit-target.py @@ -67,7 +67,7 @@ env.Package( NAME = 'foo', LICENSE = 'gpl', SUMMARY = 'balalalalal', X_RPM_GROUP = 'Application/fu', - X_RPM_INSTALL = r'%(_python_)s %(scons)s --debug=tree --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"', + X_RPM_INSTALL = r'%(_python_)s %(scons)s --tree=all --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"', DESCRIPTION = 'this should be really really long', source = [ prog ], target = "my_rpm_package.rpm", diff --git a/test/packaging/rpm/multipackage.py b/test/packaging/rpm/multipackage.py index 2f106f4..4a29a40 100644 --- a/test/packaging/rpm/multipackage.py +++ b/test/packaging/rpm/multipackage.py @@ -67,7 +67,7 @@ env.Package( NAME = 'foo', LICENSE = 'gpl', SUMMARY = 'balalalalal', X_RPM_GROUP = 'Application/fu', - X_RPM_INSTALL = r'%(_python_)s %(scons)s --debug=tree --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"', + X_RPM_INSTALL = r'%(_python_)s %(scons)s --tree=all --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"', DESCRIPTION = 'this should be really really long', source = [ prog ], SOURCE_URL = 'http://foo.org/foo-1.2.3.tar.gz' @@ -80,7 +80,7 @@ env.Package( NAME = 'foo2', LICENSE = 'gpl', SUMMARY = 'balalalalal', X_RPM_GROUP = 'Application/fu', - X_RPM_INSTALL = r'%(_python_)s %(scons)s --debug=tree --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"', + X_RPM_INSTALL = r'%(_python_)s %(scons)s --tree=all --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"', DESCRIPTION = 'this should be really really long', source = [ prog ], ) diff --git a/test/packaging/rpm/package.py b/test/packaging/rpm/package.py index 23ebe05..0ef5fad 100644 --- a/test/packaging/rpm/package.py +++ b/test/packaging/rpm/package.py @@ -66,7 +66,7 @@ env.Package( NAME = 'foo', LICENSE = 'gpl', SUMMARY = 'balalalalal', X_RPM_GROUP = 'Application/fu', - X_RPM_INSTALL = r'%(_python_)s %(scons)s --debug=tree --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"', + X_RPM_INSTALL = r'%(_python_)s %(scons)s --tree=all --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"', DESCRIPTION = 'this should be really really long', source = [ prog ], SOURCE_URL = 'http://foo.org/foo-1.2.3.tar.gz' diff --git a/test/packaging/tar/bz2_packaging.py b/test/packaging/tar/bz2_packaging.py index 875f1c9..812c08e 100644 --- a/test/packaging/tar/bz2_packaging.py +++ b/test/packaging/tar/bz2_packaging.py @@ -31,6 +31,9 @@ This tests the SRC bz2 packager, which does the following: import TestSCons +import os +import sys + python = TestSCons.python test = TestSCons.TestSCons() @@ -39,9 +42,16 @@ tar = test.detect('TAR', 'tar') if not tar: test.skip_test('tar not found, skipping test\n') -bz2 = test.where_is('bzip2') -if not bz2: - test.skip_test('tar found, but helper bzip2 not found, skipping test\n') +if sys.platform == 'win32': + # windows 10 causes fresh problems by supplying a tar, not bzip2 + # but if git is installed, there's a bzip2 there, but can't be used + bz2 = test.where_is('bzip2') + if not bz2: + test.skip_test('tar found, but helper bzip2 not found, skipping test\n') + bz2 = os.path.splitdrive(bz2)[1] + tar = os.path.splitdrive(test.where_is('tar'))[1] + if tar[:8] != bz2[:8]: # catch one in \WINDOWS, one not + test.skip_test('tar found, but usable bzip2 not, skipping test\n') test.subdir('src') diff --git a/test/packaging/tar/xz_packaging.py b/test/packaging/tar/xz_packaging.py index f12292e..1d80f7f 100644 --- a/test/packaging/tar/xz_packaging.py +++ b/test/packaging/tar/xz_packaging.py @@ -39,6 +39,9 @@ tar = test.detect('TAR', 'tar') if not tar: test.skip_test('tar not found, skipping test\n') +# Windows 10 now supplies tar, but doesn't support xz compression +# assume it's just okay to check for an xz command, because don't +# want to probe the command itself to see what it supports xz = test.where_is('xz') if not xz: test.skip_test('tar found, but helper xz not found, skipping test\n') diff --git a/test/runtest/xml/output.py b/test/runtest/xml/output.py index 88bca04..cd20dbd 100644 --- a/test/runtest/xml/output.py +++ b/test/runtest/xml/output.py @@ -65,7 +65,7 @@ expect = """\ </stdout> <stderr>FAILING TEST STDERR </stderr> - <time>\\d+\.\d</time> + <time>\\d+\\.\\d</time> </test> <test> <file_name>%(test_no_result_py)s</file_name> @@ -75,7 +75,7 @@ expect = """\ </stdout> <stderr>NO RESULT TEST STDERR </stderr> - <time>\\d+\.\d</time> + <time>\\d+\\.\\d</time> </test> <test> <file_name>%(test_pass_py)s</file_name> @@ -85,9 +85,9 @@ expect = """\ </stdout> <stderr>PASSING TEST STDERR </stderr> - <time>\\d+\.\d</time> + <time>\\d+\\.\\d</time> </test> - <time>\\d+\.\d</time> + <time>\\d+\\.\\d</time> </results> """ % locals() diff --git a/test/scons-time/run/aegis.py b/test/scons-time/run/aegis.py deleted file mode 100644 index 5235d98..0000000 --- a/test/scons-time/run/aegis.py +++ /dev/null @@ -1,79 +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__" - -""" -Verify the ability to "check out" an SCons delta from a fake -Aegis utility. -""" - -import re - -import TestSCons_time - -test = TestSCons_time.TestSCons_time() - -test.write_sample_project('foo.tar') - -my_aegis_py = test.write_fake_aegis_py('my_aegis.py') - -test.write('config', """\ -aegis = r'%(my_aegis_py)s' -""" % locals()) - -test.run(arguments = 'run -f config --aegis xyzzy.0.1 --number 321,329 foo.tar') - -test.must_exist('foo-321-0.log', - 'foo-321-0.prof', - 'foo-321-1.log', - 'foo-321-1.prof', - 'foo-321-2.log', - 'foo-321-2.prof') - -test.must_exist('foo-329-0.log', - 'foo-329-0.prof', - 'foo-329-1.log', - 'foo-329-1.prof', - 'foo-329-2.log', - 'foo-329-2.prof') - -expect = [ - test.tempdir_re('src', 'script', 'scons.py'), - 'SCONS_LIB_DIR = %s' % test.tempdir_re('src', 'engine'), -] - -content = test.read(test.workpath('foo-321-2.log'),mode='r') - -def re_find(content, line): - return re.search(line, content) -test.must_contain_all_lines(content, expect, 'foo-617-2.log', re_find) - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/sconsign/script/Signatures.py b/test/sconsign/script/Signatures.py index 24ffaf7..34737d5 100644 --- a/test/sconsign/script/Signatures.py +++ b/test/sconsign/script/Signatures.py @@ -28,9 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" Verify that the sconsign script works when using a .sconsign file in each subdirectory (SConsignFile(None)) written with the non-default value of Decider('timestamp-newer'). - -This used to test the non-default combination of -SourceSignatures('timestamp') with TargetSignatures('content'). """ import TestSCons diff --git a/test/srcchange.py b/test/srcchange.py index e396fb8..c2356b6 100644 --- a/test/srcchange.py +++ b/test/srcchange.py @@ -29,9 +29,8 @@ Test changing the C source files based on an always-executed revision extraction and substitution. This makes sure we evaluate the content of intermediate files as -expected. We used to configure this explicitly using -TargetSignatures('content') but we now rely on the default behavior -being the equivalent of Decider('content'). +expected. This relies on the default behavior being the equivalent +of Decider('content'). """ import os.path @@ -42,13 +41,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 +62,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/subdivide.py b/test/subdivide.py index a4a128e..9461d4b 100644 --- a/test/subdivide.py +++ b/test/subdivide.py @@ -29,9 +29,8 @@ Verify that rebuilds do not occur when SConsignFile(None) is used to put a .sconsign file in each directory and we subdvide the dependency tree with subsidiary *SConstruct* files in various subdirectories. -This depends on using content signatures for evaluation of intermediate -Nodes. We used to configure this explicitly using -TargetSignatures('content'), but we now rely on the default behavior +This depends on using content signatures for evaluation of +intermediate Nodes. This relies on the default behavior being the equivalent of Decider('content'). """ diff --git a/test/timestamp-fallback.py b/test/timestamp-fallback.py index f4e2e4d..2dd50a2 100644 --- a/test/timestamp-fallback.py +++ b/test/timestamp-fallback.py @@ -25,11 +25,14 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ -Verify falling back to 'timestamp' behavior if there is no native -hashlib and no underlying md5 module available. +Verify falling back to 'timestamp' behavior if there is no md5 +module. Formerly checked for hashlib first, but that has been +standard library since 2.5; test is kept in case one of those +rare no-md5 Pythons comes into play (some entities ban the use +of md5 as unsafe, although SCons does not use it in a security context. """ -import imp +import sys import os import TestSCons @@ -37,24 +40,14 @@ import TestSCons test = TestSCons.TestSCons() try: - file, name, desc = imp.find_module('hashlib') + from hashlib import md5 except ImportError: pass else: - msg = "This version of Python has a 'hashlib' module.\n" + \ - "Skipping test of falling back to timestamps.\n" + msg = "The 'md5' algorithm is built in to hashlib in this version of Python.\n" + \ + "Cannot test falling back to timestamps.\n" test.skip_test(msg) -try: - file, name, desc = imp.find_module('md5') -except ImportError: - pass -else: - if desc[2] == imp.C_BUILTIN: - msg = "The 'md5' module is built in to this version of Python.\n" + \ - "Cannot test falling back to timestamps.\n" - test.skip_test(msg) - test.write('md5.py', r""" raise ImportError """) @@ -66,7 +59,7 @@ DefaultEnvironment(tools=[]) def build(env, target, source): with open(str(target[0]), 'wt') as ofp, open(str(source[0]), 'rt') as ifp: - opf.write(ifp.read()) + ofp.write(ifp.read()) B = Builder(action = build) env = Environment(tools = [], BUILDERS = { 'B' : B }) diff --git a/testing/framework/TestSCons.py b/testing/framework/TestSCons.py index 89ad43b..7dc9e74 100644 --- a/testing/framework/TestSCons.py +++ b/testing/framework/TestSCons.py @@ -35,7 +35,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '3.1.0' +default_version = '3.1.1' python_version_unsupported = (2, 6, 0) python_version_deprecated = (2, 7, 0) diff --git a/testing/framework/TestSCons_time.py b/testing/framework/TestSCons_time.py index 8363e8d..f27e0e3 100644 --- a/testing/framework/TestSCons_time.py +++ b/testing/framework/TestSCons_time.py @@ -55,19 +55,6 @@ with open('SConstruct', 'r') as f: exec(script) """ -aegis_py = """\ -#!/usr/bin/env python -import os -import sys - -script_dir = 'src/script' -if not os.path.exists(script_dir): - os.makedirs(script_dir) -with open(script_dir + '/scons.py', 'w') as f: - f.write(r'''%s''') -""" % scons_py - - svn_py = """\ #!/usr/bin/env python import os @@ -243,12 +230,6 @@ class TestSCons_time(TestCommon): x = x.replace('time\\-', 'time\\-[^%s]*' % sep) return x - def write_fake_aegis_py(self, name): - name = self.workpath(name) - self.write(name, aegis_py) - os.chmod(name, 0o755) - return name - def write_fake_scons_py(self): self.subdir('src', ['src', 'script']) self.write('src/script/scons.py', scons_py) 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() |