diff options
author | William Deegan <bill@baddogconsulting.com> | 2021-05-24 23:06:13 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-24 23:06:13 (GMT) |
commit | 548d1ffa13be5ed5521f4650089c5e9d7d043811 (patch) | |
tree | 9276cb26f9b9fb34efa46615ba15dfbdacefabfe | |
parent | 08ea935321ab8858e15573e44c270da563e12ea0 (diff) | |
parent | 0d9a99d630169277689e95e39ae64ccf9b9215bf (diff) | |
download | SCons-548d1ffa13be5ed5521f4650089c5e9d7d043811.zip SCons-548d1ffa13be5ed5521f4650089c5e9d7d043811.tar.gz SCons-548d1ffa13be5ed5521f4650089c5e9d7d043811.tar.bz2 |
Merge branch 'master' into ninja-generation
134 files changed, 2592 insertions, 2029 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index c259c77..6a817ba 100755 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,6 +9,10 @@ NOTE: The 4.2.0 Release of SCons will drop Python 3.5 Support RELEASE VERSION/DATE TO BE FILLED IN LATER + From Joseph Brill: + - Internal MSVS update: Remove unnecessary calls to find all installed versions of msvc + when constructing the installed visual studios list. + From William Deegan: - Improve Subst()'s logic to check for proper callable function or class's argument list. It will now allow callables with expected args, and any extra args as long as they @@ -20,7 +24,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER IMPLIBNOVERSIONSYMLINKS and LDMODULENOVERSIONSYMLINKS to True. - Added --experimental flag, to enable various experimental features/tools. You can specify 'all', 'none', or any combination of available experimental features. - + - Fix Issue #3933 - Remove unguarded print of debug information in SharedLibrary logic when + SHLIBVERSION is specified. + - Fix versioned shared library naming for MacOS platform. (Previously was libxyz.dylib.1.2.3, + has been fixed to libxyz.1.2.3.dylib. Additionally the sonamed symlink had the same issue, + that is now resolved as well) From David H: - Fix Issue #3906 - `IMPLICIT_COMMAND_DEPENDENCIES` was not properly disabled when @@ -74,12 +82,32 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Don't strip spaces in INSTALLSTR by using raw subst (issue 2018) - Deprecate Python 3.5 as a supported version. - CPPDEFINES now expands construction variable references (issue 2363) + - Restore behavior that Install()'d files are writable (issue 3927) + - Simplified Mkdir(), the internal mkdir_func no longer needs to handle + existing directories, it can now pass exist_ok=True to os.makedirs(). + - Avoid WhereIs exception if user set a tool name to empty (from issue 1742) + - Maintenance: remove obsolete __getslice__ definitions (Py3 never calls); + add Node.fs.scandir to call new (Py3.5) os.scandir; Node.fs.makedirs + now passes the exist_ok flag; Cachedir creation now uses this flag. + - Maintenance: remove unneeded imports and reorganize some. Fix uses + of warnings in some tools which instantiated the class but did nothing + with them, need to instead call SCons.Warnings.warn with the warn class. + - Drop overridden changed_since_last_build method in Value class. + - Resync the SetOption implementation and the manpage, making sure new + options are available and adding a notes column for misc information. + SetOption equivalents to --hash-chunksize, --implicit-deps-unchanged + and --implicit-deps-changed are enabled. + - Add tests for SetOption failing on disallowed options and value types. From Dillan Mills: - Add support for the (TARGET,SOURCE,TARGETS,SOURCES,CHANGED_TARGETS,CHANGED_SOURCES}.relpath property. This will provide a path relative to the top of the build tree (where the SConstruct is located) Fixes #396 + From Andrew Morrow: + - Fix issue #3790: Generators in CPPDEFINES now have access to populated source + and target lists + RELEASE 4.1.0 - Tues, 19 Jan 2021 15:04:42 -0700 From James Benton: @@ -129,6 +157,8 @@ RELEASE 4.1.0 - Tues, 19 Jan 2021 15:04:42 -0700 SCons.Node.Node.clear() clear out all caching-related state. - Change Environment.SideEffect() to not add duplicate side effects. NOTE: The list of returned side effect Nodes will not include any duplicate side effect Nodes. + - Add support to the Python scanner for finding dynamically generated dependencies. + Previously the scanner only found imports if they existed on disk at scanning time. From David H: - Add ZIP_OVERRIDE_TIMESTAMP env option to Zip builder which allows for overriding of the file diff --git a/RELEASE.txt b/RELEASE.txt index fe4d82f..f5c1af3 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -59,6 +59,11 @@ FIXES - DocbookXslt tool: The XSLT stylesheet file is now initialized to an env.File() Node, such that dependencies work correctly in hierarchical builds (eg when using DocbookXslt in SConscript('subdir/SConscript') context. + - The Install builder will now set the writable mode on the file(s) it + copies. This restores the (previously undocumented) SCons behavior + that regressed as of 4.0.0. + - Fix issue #3790: Generators in CPPDEFINES now have access to populated source + and target lists IMPROVEMENTS diff --git a/SCons/Action.py b/SCons/Action.py index c5d3ea9..67eeb1d 100644 --- a/SCons/Action.py +++ b/SCons/Action.py @@ -106,7 +106,6 @@ import re import sys import subprocess from subprocess import DEVNULL -import itertools import inspect from collections import OrderedDict diff --git a/SCons/Builder.py b/SCons/Builder.py index 34bd330..38eadf8 100644 --- a/SCons/Builder.py +++ b/SCons/Builder.py @@ -103,12 +103,12 @@ from collections import UserDict, UserList import SCons.Action import SCons.Debug -from SCons.Debug import logInstanceCreation -from SCons.Errors import InternalError, UserError import SCons.Executor import SCons.Memoize import SCons.Util import SCons.Warnings +from SCons.Debug import logInstanceCreation +from SCons.Errors import InternalError, UserError class _Null: pass diff --git a/SCons/BuilderTests.py b/SCons/BuilderTests.py index 9828ef7..29b1cf0 100644 --- a/SCons/BuilderTests.py +++ b/SCons/BuilderTests.py @@ -38,7 +38,6 @@ import sys import unittest import TestCmd -import TestUnit import SCons.Action import SCons.Builder diff --git a/SCons/CacheDir.py b/SCons/CacheDir.py index 90c70e5..f021751 100644 --- a/SCons/CacheDir.py +++ b/SCons/CacheDir.py @@ -106,16 +106,11 @@ def CachePushFunc(target, source, env): tempfile = "%s.tmp%s"%(cachefile,cache_tmp_uuid) errfmt = "Unable to copy %s to cache. Cache file is %s" - if not fs.isdir(cachedir): - try: - fs.makedirs(cachedir) - except EnvironmentError: - # We may have received an exception because another process - # has beaten us creating the directory. - if not fs.isdir(cachedir): - msg = errfmt % (str(target), cachefile) - raise SCons.Errors.SConsEnvironmentError(msg) - + try: + fs.makedirs(cachedir, exist_ok=True) + except OSError: + msg = errfmt % (str(target), cachefile) + raise SCons.Errors.SConsEnvironmentError(msg) try: if fs.islink(t.get_internal_path()): fs.symlink(fs.readlink(t.get_internal_path()), tempfile) diff --git a/SCons/Defaults.py b/SCons/Defaults.py index 6dabfb5..95a2e52 100644 --- a/SCons/Defaults.py +++ b/SCons/Defaults.py @@ -31,7 +31,6 @@ The code that reads the registry to find MSVC components was borrowed from distutils.msvccompiler. """ -import errno import os import shutil import stat @@ -309,16 +308,7 @@ def mkdir_func(dest): if not SCons.Util.is_List(dest): dest = [dest] for entry in dest: - try: - os.makedirs(str(entry)) - except os.error as e: - p = str(entry) - if (e.args[0] == errno.EEXIST or - (sys.platform == 'win32' and e.args[0] == 183)) \ - and os.path.isdir(str(entry)): - pass # not an error if already exists - else: - raise + os.makedirs(str(entry), exist_ok=True) Mkdir = ActionFactory(mkdir_func, @@ -508,12 +498,12 @@ def processDefines(defs): return l -def _defines(prefix, defs, suffix, env, c=_concat_ixes): +def _defines(prefix, defs, suffix, env, target, source, c=_concat_ixes): """A wrapper around _concat_ixes that turns a list or string into a list of C preprocessor command-line definitions. """ - return c(prefix, env.subst_list(processDefines(defs)), suffix, env) + return c(prefix, env.subst_list(processDefines(defs), target=target, source=source), suffix, env) class NullCmdGenerator: @@ -618,7 +608,7 @@ ConstructionEnvironment = { '_LIBFLAGS': '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}', '_LIBDIRFLAGS': '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', '_CPPINCFLAGS': '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)', - '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}', + '_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__, TARGET, SOURCE)}', '__libversionflags': __libversionflags, '__SHLIBVERSIONFLAGS': '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}', diff --git a/SCons/DefaultsTests.py b/SCons/DefaultsTests.py index 1e1ebdd..6a7ce9c 100644 --- a/SCons/DefaultsTests.py +++ b/SCons/DefaultsTests.py @@ -21,15 +21,11 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import SCons.compat - import os import unittest import TestCmd -import SCons.Errors - from SCons.Defaults import mkdir_func class DefaultsTestCase(unittest.TestCase): diff --git a/SCons/Environment.py b/SCons/Environment.py index 92fd583..8a31b33 100644 --- a/SCons/Environment.py +++ b/SCons/Environment.py @@ -1877,9 +1877,10 @@ class Base(SubstitutionEnvironment): tool = SCons.Tool.Tool(tool, toolpath, **kw) tool(self) - def WhereIs(self, prog, path=None, pathext=None, reject=[]): - """Find prog in the path. - """ + def WhereIs(self, prog, path=None, pathext=None, reject=None): + """Find prog in the path. """ + if not prog: # nothing to search for, just give up + return None if path is None: try: path = self['ENV']['PATH'] @@ -1894,9 +1895,10 @@ class Base(SubstitutionEnvironment): pass elif is_String(pathext): pathext = self.subst(pathext) - prog = CLVar(self.subst(prog)) # support "program --with-args" + prog = CLVar(self.subst(prog)) # support "program --with-args" path = WhereIs(prog[0], path, pathext, reject) - if path: return path + if path: + return path return None ####################################################################### diff --git a/SCons/Environment.xml b/SCons/Environment.xml index 945ed9c..27e7302 100644 --- a/SCons/Environment.xml +++ b/SCons/Environment.xml @@ -258,7 +258,7 @@ a subclass of the SCons.CacheDir.CacheDir class. <scons_function name="Action"> <arguments> -(action, [cmd/str/fun, [var, ...]] [option=value, ...]) +(action, [output, [var, ...]] [key=value, ...]) </arguments> <summary> <para> diff --git a/SCons/EnvironmentTests.py b/SCons/EnvironmentTests.py index b4d5d0d..7155969 100644 --- a/SCons/EnvironmentTests.py +++ b/SCons/EnvironmentTests.py @@ -869,7 +869,7 @@ sys.exit(0) # avoid SubstitutionEnvironment for these, has no .Append method, # which is needed for unique=False test - env = Environment(CCFLAGS=None) + env = Environment(CCFLAGS="") # merge with existing but empty flag env.MergeFlags('-X') assert env['CCFLAGS'] == ['-X'], env['CCFLAGS'] @@ -2583,6 +2583,8 @@ def generate(env): path = os.pathsep.join(pathdirs_1234) env = self.TestEnvironment(ENV = {'PATH' : path}) + wi = env.WhereIs('') + assert wi is None wi = env.WhereIs('xxx.exe') assert wi == test.workpath(sub3_xxx_exe), wi wi = env.WhereIs('xxx.exe', pathdirs_1243) diff --git a/SCons/ErrorsTests.py b/SCons/ErrorsTests.py index cc63d9b..9f2f1a2 100644 --- a/SCons/ErrorsTests.py +++ b/SCons/ErrorsTests.py @@ -21,7 +21,6 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import errno import unittest import SCons.Errors diff --git a/SCons/Executor.py b/SCons/Executor.py index 005906f..492ebe3 100644 --- a/SCons/Executor.py +++ b/SCons/Executor.py @@ -25,12 +25,12 @@ import collections -import SCons.Debug -from SCons.Debug import logInstanceCreation import SCons.Errors import SCons.Memoize import SCons.Util from SCons.compat import NoSlotsPyPy +import SCons.Debug +from SCons.Debug import logInstanceCreation class Batch: """Remembers exact association between targets @@ -63,10 +63,6 @@ class TSList(collections.UserList): def __getitem__(self, i): nl = self.func() return nl[i] - def __getslice__(self, i, j): - nl = self.func() - i, j = max(i, 0), max(j, 0) - return nl[i:j] def __str__(self): nl = self.func() return str(nl) @@ -274,10 +270,8 @@ class Executor(object, metaclass=NoSlotsPyPy): return self.get_lvars()[targets_string] def set_action_list(self, action): - import SCons.Util if not SCons.Util.is_List(action): if not action: - import SCons.Errors raise SCons.Errors.UserError("Executor must have an action.") action = [action] self.action_list = action diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py index 2773960..909e5b6 100644 --- a/SCons/Node/FS.py +++ b/SCons/Node/FS.py @@ -1116,56 +1116,81 @@ class LocalFS: needs to use os.chdir() directly to avoid recursion. Will we really need this one? """ - #def chdir(self, path): - # return os.chdir(path) + def chmod(self, path, mode): return os.chmod(path, mode) + def copy(self, src, dst): return shutil.copy(src, dst) + def copy2(self, src, dst): return shutil.copy2(src, dst) + def exists(self, path): return os.path.exists(path) + def getmtime(self, path): return os.path.getmtime(path) + def getsize(self, path): return os.path.getsize(path) + def isdir(self, path): return os.path.isdir(path) + def isfile(self, path): return os.path.isfile(path) + def link(self, src, dst): return os.link(src, dst) + def lstat(self, path): return os.lstat(path) + def listdir(self, path): return os.listdir(path) - def makedirs(self, path): - return os.makedirs(path) - def mkdir(self, path): - return os.mkdir(path) + + def scandir(self, path): + return os.scandir(path) + + def makedirs(self, path, mode=0o777, exist_ok=False): + return os.makedirs(path, mode=mode, exist_ok=exist_ok) + + def mkdir(self, path, mode=0o777): + return os.mkdir(path, mode=mode) + def rename(self, old, new): return os.rename(old, new) + def stat(self, path): return os.stat(path) + def symlink(self, src, dst): return os.symlink(src, dst) + def open(self, path): return open(path) + def unlink(self, path): return os.unlink(path) if hasattr(os, 'symlink'): + def islink(self, path): return os.path.islink(path) + else: + def islink(self, path): - return 0 # no symlinks + return False # no symlinks if hasattr(os, 'readlink'): + def readlink(self, file): return os.readlink(file) + else: + def readlink(self, file): return '' @@ -3729,7 +3754,10 @@ class FileFinder: return None def _find_file_key(self, filename, paths, verbose=None): - return (filename, paths) + # Note: paths could be a list, which is not hashable. If it is, convert + # it to a tuple, which is hashable. + paths_entry = tuple(paths) if isinstance(paths, list) else paths + return (filename, paths_entry) @SCons.Memoize.CountDictCall(_find_file_key) def find_file(self, filename, paths, verbose=None): diff --git a/SCons/Node/FSTests.py b/SCons/Node/FSTests.py index d2a1ebe..d78940e 100644 --- a/SCons/Node/FSTests.py +++ b/SCons/Node/FSTests.py @@ -31,7 +31,6 @@ import shutil import stat from TestCmd import TestCmd, IS_WINDOWS -import TestUnit import SCons.Errors import SCons.Node.FS diff --git a/SCons/Node/Python.py b/SCons/Node/Python.py index 738682c..c6850ab 100644 --- a/SCons/Node/Python.py +++ b/SCons/Node/Python.py @@ -146,13 +146,6 @@ class Value(SCons.Node.Node): """Get contents for signature calculations.""" return self.get_text_contents().encode() - def changed_since_last_build(self, target, prev_ni): - cur_csig = self.get_csig() - try: - return cur_csig != prev_ni.csig - except AttributeError: - return True - def get_csig(self, calc=None): """Because we're a Python value node and don't have a real timestamp, we get to ignore the calculator and just use the diff --git a/SCons/Node/__init__.py b/SCons/Node/__init__.py index 0744be4..ec742a6 100644 --- a/SCons/Node/__init__.py +++ b/SCons/Node/__init__.py @@ -47,14 +47,9 @@ from itertools import chain, zip_longest import SCons.Debug import SCons.Executor import SCons.Memoize -import SCons.Util -from SCons.Util import hash_signature - -from SCons.Debug import Trace - from SCons.compat import NoSlotsPyPy from SCons.Debug import logInstanceCreation, Trace -from SCons.Util import MD5signature +from SCons.Util import hash_signature, is_List, UniqueList, render_tree print_duplicate = 0 @@ -1283,7 +1278,7 @@ class Node(object, metaclass=NoSlotsPyPy): self._add_child(self.depends, self.depends_set, depend) except TypeError as e: e = e.args[0] - if SCons.Util.is_List(e): + if is_List(e): s = list(map(str, e)) else: s = str(e) @@ -1292,7 +1287,7 @@ class Node(object, metaclass=NoSlotsPyPy): def add_prerequisite(self, prerequisite): """Adds prerequisites""" if self.prerequisites is None: - self.prerequisites = SCons.Util.UniqueList() + self.prerequisites = UniqueList() self.prerequisites.extend(prerequisite) self._children_reset() @@ -1302,7 +1297,7 @@ class Node(object, metaclass=NoSlotsPyPy): self._add_child(self.ignore, self.ignore_set, depend) except TypeError as e: e = e.args[0] - if SCons.Util.is_List(e): + if is_List(e): s = list(map(str, e)) else: s = str(e) @@ -1316,7 +1311,7 @@ class Node(object, metaclass=NoSlotsPyPy): self._add_child(self.sources, self.sources_set, source) except TypeError as e: e = e.args[0] - if SCons.Util.is_List(e): + if is_List(e): s = list(map(str, e)) else: s = str(e) @@ -1560,7 +1555,7 @@ class Node(object, metaclass=NoSlotsPyPy): path = None def f(node, env=env, scanner=scanner, path=path): return node.get_found_includes(env, scanner, path) - return SCons.Util.render_tree(s, f, 1) + return render_tree(s, f, 1) else: return None diff --git a/SCons/PathListTests.py b/SCons/PathListTests.py index ea7cecd..e62baad 100644 --- a/SCons/PathListTests.py +++ b/SCons/PathListTests.py @@ -23,8 +23,6 @@ import unittest -import TestUnit - import SCons.PathList diff --git a/SCons/Platform/darwin.py b/SCons/Platform/darwin.py index 68cb7df..d9d7f2d 100644 --- a/SCons/Platform/darwin.py +++ b/SCons/Platform/darwin.py @@ -44,7 +44,7 @@ def generate(env): # make sure this works on Macs with Tiger or earlier try: dirlist = os.listdir('/etc/paths.d') - except: + except FileNotFoundError: dirlist = [] for file in dirlist: diff --git a/SCons/Platform/posix.py b/SCons/Platform/posix.py index 4c9f8f9..dc98408 100644 --- a/SCons/Platform/posix.py +++ b/SCons/Platform/posix.py @@ -28,11 +28,8 @@ will usually be imported through the generic SCons.Platform.Platform() selection method. """ -import errno import subprocess -import select -import SCons.Util from SCons.Platform import TempFileMunge from SCons.Platform.virtualenv import ImportVirtualenv from SCons.Platform.virtualenv import ignore_virtualenv, enable_virtualenv diff --git a/SCons/SConf.py b/SCons/SConf.py index d024600..68e890a 100644 --- a/SCons/SConf.py +++ b/SCons/SConf.py @@ -234,8 +234,10 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): bi. """ if not isinstance(bi, SConfBuildInfo): - SCons.Warnings.warn(SConfWarning, - "The stored build information has an unexpected class: %s" % bi.__class__) + SCons.Warnings.warn( + SConfWarning, + "The stored build information has an unexpected class: %s" % bi.__class__ + ) else: self.display("The original builder output was:\n" + (" |" + str(bi.string)).replace("\n", "\n |")) diff --git a/SCons/SConfTests.py b/SCons/SConfTests.py index a6fe508..008dfc2 100644 --- a/SCons/SConfTests.py +++ b/SCons/SConfTests.py @@ -21,8 +21,6 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import SCons.compat - import io import os import re diff --git a/SCons/SConsignTests.py b/SCons/SConsignTests.py index fdce588..d4f4418 100644 --- a/SCons/SConsignTests.py +++ b/SCons/SConsignTests.py @@ -25,10 +25,8 @@ import os import unittest import TestCmd -import TestUnit import SCons.dblite - import SCons.SConsign class BuildInfo: diff --git a/SCons/Scanner/Python.py b/SCons/Scanner/Python.py index dc6812c..86aa001 100644 --- a/SCons/Scanner/Python.py +++ b/SCons/Scanner/Python.py @@ -82,6 +82,40 @@ def find_include_names(node): return all_matches +def find_import(import_path, search_paths): + """ + Finds the specified import in the various search paths. + For an import of "p", it could either result in a file named p.py or + p/__init__.py. We can't do two consecutive searches for p then p.py + because the first search could return a result that is lower in the + search_paths precedence order. As a result, it is safest to iterate over + search_paths and check whether p or p.py exists in each path. This allows + us to cleanly respect the precedence order. + + If the import is found, returns a tuple containing: + 1. Discovered dependency node (e.g. p/__init__.py or p.py) + 2. True if the import was a package, False if the import was a module. + 3. The Dir node in search_paths that the import is relative to. + If the import is not found, returns a tuple containing (None, False, None). + Callers should check for failure by checking whether the first entry in the + tuple is not None. + """ + for search_path in search_paths: + paths = [search_path] + # Note: if the same import is present as a package and a module, Python + # prefers the package. As a result, we always look for x/__init__.py + # before looking for x.py. + node = SCons.Node.FS.find_file(import_path + '/__init__.py', paths) + if node: + return node, True, search_path + else: + node = SCons.Node.FS.find_file(import_path + '.py', paths) + if node: + return node, False, search_path + + return None, False, None + + def scan(node, env, path=()): # cache the includes list in node so we only scan it once: if node.includes is not None: @@ -92,10 +126,10 @@ def scan(node, env, path=()): # if the same header is included many times. node.includes = list(map(SCons.Util.silent_intern, includes)) - # XXX TODO: Sort? nodes = [] if callable(path): path = path() + for module, imports in includes: is_relative = module.startswith('.') if is_relative: @@ -108,48 +142,57 @@ def scan(node, env, path=()): for i in itertools.repeat(None, num_parents): current_dir = current_dir.up() - search_paths = [current_dir.abspath] + search_paths = [current_dir] search_string = module_lstripped else: - search_paths = path + search_paths = [env.Dir(p) for p in path] search_string = module - module_components = search_string.split('.') - for search_path in search_paths: - candidate_path = os.path.join(search_path, *module_components) - # The import stored in "module" could refer to a directory or file. - import_dirs = [] - if os.path.isdir(candidate_path): - import_dirs = module_components - - # Because this resolved to a directory, there is a chance that - # additional imports (e.g. from module import A, B) could refer - # to files to import. - if imports: - for imp in imports: - file = os.path.join(candidate_path, imp + '.py') - if os.path.isfile(file): - nodes.append(file) - elif os.path.isfile(candidate_path + '.py'): - nodes.append(candidate_path + '.py') - import_dirs = module_components[:-1] - - # We can ignore imports because this resolved to a file. Any - # additional imports (e.g. from module.file import A, B) would - # only refer to functions in this file. - - # Take a dependency on all __init__.py files from all imported - # packages unless it's a relative import. If it's a relative - # import, we don't need to take the dependency because Python - # requires that all referenced packages have already been imported, - # which means that the dependency has already been established. - if import_dirs and not is_relative: - for i in range(len(import_dirs)): - init_components = module_components[:i+1] + ['__init__.py'] - init_path = os.path.join(search_path, *(init_components)) - if os.path.isfile(init_path): - nodes.append(init_path) - break + # If there are no paths, there is no point in parsing includes for this + # iteration of the loop. + if not search_paths: + continue + + module_components = [x for x in search_string.split('.') if x] + package_dir = None + hit_dir = None + if not module_components: + # This is just a "from . import x". + package_dir = search_paths[0] + else: + # Translate something like "import x.y" to a call to find_import + # with 'x/y' as the path. find_import will then determine whether + # we can find 'x/y/__init__.py' or 'x/y.py'. + import_node, is_dir, hit_dir = find_import( + '/'.join(module_components), search_paths) + if import_node: + nodes.append(import_node) + if is_dir: + package_dir = import_node.dir + + # If the statement was something like "from x import y, z", whether we + # iterate over imports depends on whether x was a package or module. + # If it was a module, y and z are just functions so we don't need to + # search for them. If it was a package, y and z are either packages or + # modules and we do need to search for them. + if package_dir and imports: + for i in imports: + import_node, _, _ = find_import(i, [package_dir]) + if import_node: + nodes.append(import_node) + + # Take a dependency on all __init__.py files from all imported + # packages unless it's a relative import. If it's a relative + # import, we don't need to take the dependency because Python + # requires that all referenced packages have already been imported, + # which means that the dependency has already been established. + if hit_dir and not is_relative: + import_dirs = module_components + for i in range(len(import_dirs)): + init_path = '/'.join(import_dirs[:i+1] + ['__init__.py']) + init_node = SCons.Node.FS.find_file(init_path, [hit_dir]) + if init_node and init_node not in nodes: + nodes.append(init_node) return sorted(nodes) diff --git a/SCons/Scanner/PythonTests.py b/SCons/Scanner/PythonTests.py index faf548a..84acd0c 100644 --- a/SCons/Scanner/PythonTests.py +++ b/SCons/Scanner/PythonTests.py @@ -21,6 +21,21 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +""" +Unit tests for the Python scanner. These tests validate proper working of the +Python scanner by confirming that the results of the scan match expectations. + +The absolute path tests have strongly-defined behavior in that there is no real +ambiguity to what they should result in. For example, if you import package x, +you expect to get x/__init__.py as a dependency. + +The relative path tests that reach into ancestor directories do have some +ambiguity in whether to depend upon __init__.py in those referenced ancestor +directories. Python only allows these kinds of relative imports if the file is +part of a package, in which case those ancestor directories' __init__.py files +have already been imported. +""" + import SCons.compat import collections @@ -226,9 +241,6 @@ class PythonScannerTestImportsGrandparentModule(unittest.TestCase): 'nested1/nested2/nested3/imports_grandparent_module.py') path = s.path(env, source=[node]) deps = s(node, env, path) - # Note: there is some ambiguity here in what the scanner should return. - # Relative imports require that the referenced packages have already - # been imported. files = ['nested1/module.py'] deps_match(self, deps, files) @@ -253,7 +265,59 @@ class PythonScannerTestImportsParentThenSubmodule(unittest.TestCase): 'nested1/nested2/nested3/imports_parent_then_submodule.py') path = s.path(env, source=[node]) deps = s(node, env, path) - files = ['nested1/nested2a/module.py'] + files = ['nested1/nested2a/__init__.py', 'nested1/nested2a/module.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportsModuleWithFunc(unittest.TestCase): + def runTest(self): + """ + This test case tests the following import statement: + `from simple_package.module1 import somefunc` with somefunc.py existing + in the same folder as module1.py. It validates that the scanner doesn't + accidentally take a dependency somefunc.py. + """ + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + env['ENV']['PYTHONPATH'] = test.workpath('') + deps = s(env.File('from_import_simple_package_module1_func.py'), env, + lambda : s.path(env)) + files = ['simple_package/__init__.py', 'simple_package/module1.py'] + deps_match(self, deps, files) + + +class PythonScannerTestFromNested1ImportNested2(unittest.TestCase): + def runTest(self): + """ + This test case tests the following import statement: + `from nested1 import module, nested2`. In this test, module is a Python + module and nested2 is a package. Validates that the scanner can handle + such mixed imports. + """ + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + env['ENV']['PYTHONPATH'] = test.workpath('') + deps = s(env.File('from_nested1_import_multiple.py'), env, + lambda : s.path(env)) + files = ['nested1/__init__.py', 'nested1/module.py', + 'nested1/nested2/__init__.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportUnknownFiles(unittest.TestCase): + def runTest(self): + """ + This test case tests importing files that are not found. If Python + really can't find those files, it will fail. But this is intended to + test the various failure paths in the scanner to make sure that they + don't raise exceptions. + """ + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + env['ENV']['PYTHONPATH'] = test.workpath('') + deps = s(env.File('imports_unknown_files.py'), env, + lambda : s.path(env)) + files = [] deps_match(self, deps, files) diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 15f7ece..b674692 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -44,7 +44,6 @@ import re import sys import time import traceback -import sysconfig import platform import threading diff --git a/SCons/Script/Main.xml b/SCons/Script/Main.xml index 4935f88..f4f4705 100644 --- a/SCons/Script/Main.xml +++ b/SCons/Script/Main.xml @@ -317,261 +317,242 @@ atexit.register(print_build_failures) <summary> <para> This function provides a way to query the value of -SCons options set on scons command line -(or set using the -&f-link-SetOption; -function). -The options supported are: +options which can be set via the command line or using the +&f-link-SetOption; function. </para> - -<para> -<variablelist> -<varlistentry> -<term><literal>cache_debug</literal></term> -<listitem> -<para> -which corresponds to <option>--cache-debug</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>cache_disable</literal></term> -<listitem> -<para> -which corresponds to <option>--cache-disable</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>cache_force</literal></term> -<listitem> -<para> -which corresponds to <option>--cache-force</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>cache_show</literal></term> -<listitem> -<para> -which corresponds to <option>--cache-show</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>clean</literal></term> -<listitem> -<para> -which corresponds to <option>-c</option>, <option>--clean</option> -and <option>--remove</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>config</literal></term> -<listitem> -<para> -which corresponds to <option>--config</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>directory</literal></term> -<listitem> -<para> -which corresponds to <option>-C</option> and <option>--directory</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>diskcheck</literal></term> -<listitem> -<para> -which corresponds to <option>--diskcheck</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>duplicate</literal></term> -<listitem> -<para> -which corresponds to <option>--duplicate</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>file</literal></term> -<listitem> -<para> -which corresponds to <option>-f</option>, <option>--file</option>, <option>--makefile</option> and <option>--sconstruct</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>help</literal></term> -<listitem> -<para> -which corresponds to <option>-h</option> and <option>--help</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>ignore_errors</literal></term> -<listitem> <para> -which corresponds to <option>--ignore-errors</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>implicit_cache</literal></term> -<listitem> -<para> -which corresponds to <option>--implicit-cache</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>implicit_deps_changed</literal></term> -<listitem> -<para> -which corresponds to <option>--implicit-deps-changed</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>implicit_deps_unchanged</literal></term> -<listitem> -<para> -which corresponds to <option>--implicit-deps-unchanged</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>interactive</literal></term> -<listitem> -<para> -which corresponds to <option>--interact</option> and <option>--interactive</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>keep_going</literal></term> -<listitem> -<para> -which corresponds to <option>-k</option> and <option>--keep-going</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>max_drift</literal></term> -<listitem> -<para> -which corresponds to <option>--max-drift</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>no_exec</literal></term> -<listitem> -<para> -which corresponds to <option>-n</option>, -<option>--no-exec</option>, <option>--just-print</option>, -<option>--dry-run</option> and <option>--recon</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>no_site_dir</literal></term> -<listitem> -<para> -which corresponds to <option>--no-site-dir</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>num_jobs</literal></term> -<listitem> -<para> -which corresponds to <option>-j</option> and <option>--jobs</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>profile_file</literal></term> -<listitem> -<para> -which corresponds to <option>--profile</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>question</literal></term> -<listitem> -<para> -which corresponds to <option>-q</option> and <option>--question</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>random</literal></term> -<listitem> -<para> -which corresponds to <option>--random</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>repository</literal></term> -<listitem> -<para> -which corresponds to <option>-Y</option>, <option>--repository</option> and <option>--srcdir</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>silent</literal></term> -<listitem> -<para> -which corresponds to <option>-s</option>, <option>--silent</option> and <option>--quiet</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>site_dir</literal></term> -<listitem> -<para> -which corresponds to <option>--site-dir</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>stack_size</literal></term> -<listitem> -<para> -which corresponds to <option>--stack-size</option>; -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>taskmastertrace_file</literal></term> -<listitem> -<para> -which corresponds to <option>--taskmastertrace</option>; and -</para> -</listitem> -</varlistentry> -<varlistentry> -<term><literal>warn</literal></term> -<listitem> -<para> -which corresponds to <option>--warn</option> and <option>--warning</option>. -</para> -</listitem> -</varlistentry> -</variablelist> +<parameter>name</parameter> can be an entry from the following table, +which shows the corresponding command line arguments +that could affect the value. +<parameter>name</parameter> can be also be the destination +variable name from a project-specific option added using the +&f-link-AddOption; function, as long as the addition +happens prior to the &f-GetOption; call in the SConscript files. </para> +<informaltable rowsep="1" colsep="1" frame="topbot"> +<tgroup cols="3"> +<thead> +<row> + <entry align="left">Query name</entry> + <entry align="left">Command-line options</entry> + <entry align="left">Notes</entry> +</row> +</thead> + +<tbody> +<row> + <entry><varname>cache_debug</varname></entry> + <entry><option>--cache-debug</option></entry> +</row> +<row> + <entry><varname>cache_disable</varname></entry> + <entry> + <option>--cache-disable</option>, + <option>--no-cache</option> + </entry> +</row> +<row> + <entry><varname>cache_force</varname></entry> + <entry> + <option>--cache-force</option>, + <option>--cache-populate</option> + </entry> +</row> +<row> + <entry><varname>cache_readonly</varname></entry> + <entry><option>--cache-readonly</option></entry> +</row> +<row> + <entry><varname>cache_show</varname></entry> + <entry><option>--cache-show</option></entry> +</row> +<row> + <entry><varname>clean</varname></entry> + <entry> + <option>-c</option>, + <option>--clean</option>, + <option>--remove</option> + </entry> +</row> +<row> + <entry><varname>climb_up</varname></entry> + <entry> + <option>-D</option> + <option>-U</option> + <option>-u</option> + <option>--up</option> + <option>--search_up</option> + </entry> +</row> +<row> + <entry><varname>config</varname></entry> + <entry><option>--config</option></entry> +</row> +<row> + <entry><varname>debug</varname></entry> + <entry><option>--debug</option></entry> +</row> +<row> + <entry><varname>directory</varname></entry> + <entry><option>-C</option>, <option>--directory</option></entry> +</row> +<row> + <entry><varname>diskcheck</varname></entry> + <entry><option>--diskcheck</option></entry> +</row> +<row> + <entry><varname>duplicate</varname></entry> + <entry><option>--duplicate</option></entry> +</row> +<row> + <entry><varname>enable_virtualenv</varname></entry> + <entry><option>--enable-virtualenv</option></entry> +</row> +<row> + <entry><varname>experimental</varname></entry> + <entry><option>--experimental</option></entry> + <entry><emphasis>since 4.2</emphasis></entry> +</row> +<row> + <entry><varname>file</varname></entry> + <entry> + <option>-f</option>, + <option>--file</option>, + <option>--makefile</option>, + <option>--sconstruct</option> + </entry> +</row> +<row> + <entry><varname>hash_format</varname></entry> + <entry><option>--hash-format</option></entry> + <entry><emphasis>since 4.2</emphasis></entry> +</row> +<row> + <entry><varname>help</varname></entry> + <entry><option>-h</option>, <option>--help</option></entry> +</row> +<row> + <entry><varname>ignore_errors</varname></entry> + <entry><option>-i</option>, <option>--ignore-errors</option></entry> +</row> +<row> + <entry><varname>ignore_virtualenv</varname></entry> + <entry><option>--ignore-virtualenv</option></entry> +</row> +<row> + <entry><varname>implicit_cache</varname></entry> + <entry><option>--implicit-cache</option></entry> +</row> +<row> + <entry><varname>implicit_deps_changed</varname></entry> + <entry><option>--implicit-deps-changed</option></entry> +</row> +<row> + <entry><varname>implicit_deps_unchanged</varname></entry> + <entry><option>--implicit-deps-unchanged</option></entry> +</row> +<row> + <entry><varname>include_dir</varname></entry> + <entry><option>-I</option>, <option>--include-dir</option></entry> +</row> +<row> + <entry><varname>install_sandbox</varname></entry> + <entry><option>--install-sandbox</option></entry> + <entry>Available only if the &t-link-install; tool has been called</entry> +</row> +<row> + <entry><varname>keep_going</varname></entry> + <entry><option>-k</option>, <option>--keep-going</option></entry> +</row> +<row> + <entry><varname>max_drift</varname></entry> + <entry><option>--max-drift</option></entry> +</row> +<row> + <entry><varname>md5_chunksize</varname></entry> + <entry> + <option>--hash-chunksize</option>, + <option>--md5-chunksize</option> + </entry> + <entry><emphasis><option>--hash-chunksize</option> since 4.2</emphasis></entry> +</row> +<row> + <entry><varname>no_exec</varname></entry> + <entry> + <option>-n</option>, + <option>--no-exec</option>, + <option>--just-print</option>, + <option>--dry-run</option>, + <option>--recon</option> + </entry> +</row> +<row> + <entry><varname>no_progress</varname></entry> + <entry><option>-Q</option></entry> +</row> +<row> + <entry><varname>num_jobs</varname></entry> + <entry><option>-j</option>, <option>--jobs</option></entry> +</row> +<row> + <entry><varname>package_type</varname></entry> + <entry><option>--package-type</option></entry> + <entry>Available only if the &t-link-packaging; tool has been called</entry> +</row> +<row> + <entry><varname>profile_file</varname></entry> + <entry><option>--profile</option></entry> +</row> +<row> + <entry><varname>question</varname></entry> + <entry><option>-q</option>, <option>--question</option></entry> +</row> +<row> + <entry><varname>random</varname></entry> + <entry><option>--random</option></entry> +</row> +<row> + <entry><varname>repository</varname></entry> + <entry> + <option>-Y</option>, + <option>--repository</option>, + <option>--srcdir</option> + </entry> +</row> +<row> + <entry><varname>silent</varname></entry> + <entry> + <option>-s</option>, + <option>--silent</option>, + <option>--quiet</option> + </entry> +</row> +<row> + <entry><varname>site_dir</varname></entry> + <entry><option>--site-dir</option>, <option>--no-site-dir</option></entry> +</row> +<row> + <entry><varname>stack_size</varname></entry> + <entry><option>--stack-size</option></entry> +</row> +<row> + <entry><varname>taskmastertrace_file</varname></entry> + <entry><option>--taskmastertrace</option></entry> +</row> +<row> + <entry><varname>tree_printers</varname></entry> + <entry><option>--tree</option></entry> +</row> +<row> + <entry><varname>warn</varname></entry> + <entry><option>--warn</option>, <option>--warning</option></entry> +</row> + +</tbody> +</tgroup> +</informaltable> + <para> See the documentation for the corresponding command line option for information about each specific @@ -768,15 +749,33 @@ Multiple targets can be passed in to a single call to Sets &scons; option variable <parameter>name</parameter> to <parameter>value</parameter>. These options are all also settable via -&scons; command-line options but the variable name -may differ from the command-line option name (see table). +command-line options but the variable name +may differ from the command-line option name - +see the table for correspondences. A value set via command-line option will take precedence over one set with &f-SetOption;, which allows setting a project default in the scripts and temporarily overriding it via command line. +&f-SetOption; calls can also be placed in the +<filename>site_init.py</filename> file. +</para> + +<para> +See the documentation in the manpage for the +corresponding command line option for information about each specific option. +The <parameter>value</parameter> parameter is mandatory, +for option values which are boolean in nature +(that is, the command line option does not take an argument) +use a <parameter>value</parameter> +which evaluates to true (e.g. <constant>True</constant>, +<constant>1</constant>) or false (e.g. <constant>False</constant>, +<constant>0</constant>). +</para> + +<para> Options which affect the reading and processing of SConscript files -are not settable this way, since those files must -be read in order to find the &f-SetOption; call. +are not settable using &f-SetOption; since those files must +be read in order to find the &f-SetOption; call in the first place. </para> <para> @@ -787,126 +786,161 @@ The settable variables with their associated command-line options are: <!-- This list comes directly from SConsValues.settable. Keep in sync. --> <informaltable rowsep="1" colsep="1" frame="topbot"> -<tgroup cols="2"> +<tgroup cols="3"> <thead> -<row><entry>Variable</entry><entry>Command-line options</entry></row> +<row> + <entry align="left">Settable name</entry> + <entry align="left">Command-line options</entry> + <entry align="left">Notes</entry> +</row> </thead> + <tbody> -<row><entry> -<varname>clean</varname> -</entry><entry> -<option>-c</option>, <option>--clean</option>, <option>--remove</option> -</entry></row> -<row><entry> -<varname>diskcheck</varname> -</entry><entry> -<option>--diskcheck</option> -</entry></row> - - <row><entry> -<varname>duplicate</varname> -</entry><entry> -<option>--duplicate</option> -</entry></row> - - - <row> - <entry> - <varname>experimental</varname> - </entry> - <entry> - <option>--experimental</option> - </entry> - </row> - - -<row><entry> -<varname>help</varname> -</entry><entry> -<option>-h</option>, <option>--help</option> -</entry></row> -<row><entry> -<varname>implicit_cache</varname> -</entry><entry> -<option>--implicit-cache</option> -</entry></row> -<!--TODO: add implicit-deps-changed, implicit-deps-unchanged ? --> -<row><entry> -<varname>max_drift</varname> -</entry><entry> -<option>--max-drift</option> -</entry></row> -<row><entry> -<varname>md5_chunksize</varname> -</entry><entry> -<option>--md5-chunksize</option> -</entry></row> -<row><entry> -<varname>no_exec</varname> -</entry><entry> -<option>-n</option>, <option>--no-exec</option>, -<option>--just-print</option>, <option>--dry-run</option>, -<option>--recon</option> -</entry></row> -<row><entry> -<varname>no_progress</varname> -</entry><entry> -<option>-Q</option> -</entry></row> -<row><entry> -<varname>num_jobs</varname> -</entry><entry> -<option>-j</option>, <option>--jobs</option> -</entry></row> -<row><entry> -<varname>random</varname> -</entry><entry> -<option>--random</option> -</entry></row> -<row><entry> -<varname>silent</varname> -</entry><entry> -<option>--silent</option>. -</entry></row> -<row><entry> -<varname>stack_size</varname> -</entry><entry> -<option>--stack-size</option> -</entry></row> -<row><entry> -<varname>warn</varname> -</entry><entry> -<option>--warn</option>. -</entry></row> +<row> + <entry><varname>clean</varname></entry> + <entry> + <option>-c</option>, + <option>--clean</option>, + <option>--remove</option> + </entry> +</row> + +<row> + <entry><varname>diskcheck</varname></entry> + <entry><option>--diskcheck</option></entry> +</row> + +<row> + <entry><varname>duplicate</varname></entry> + <entry><option>--duplicate</option></entry> +</row> + +<row> + <entry><varname>experimental</varname></entry> + <entry><option>--experimental</option></entry> + <entry><emphasis>since 4.2</emphasis></entry> +</row> + +<row> + <entry><varname>hash_chunksize</varname></entry> + <entry><option>--hash-chunksize</option></entry> + <entry> + Actually sets <varname>md5_chunksize</varname>. + <emphasis>since 4.2</emphasis> + </entry> +</row> + +<row> + <entry><varname>hash_format</varname></entry> + <entry><option>--hash-format</option></entry> + <entry><emphasis>since 4.2</emphasis></entry> +</row> + +<row> + <entry><varname>help</varname></entry> + <entry><option>-h</option>, <option>--help</option></entry> +</row> + +<row> + <entry><varname>implicit_cache</varname></entry> + <entry><option>--implicit-cache</option></entry> +</row> + +<row> + <entry><varname>implicit_deps_changed</varname></entry> + <entry><option>--implicit-deps-changed</option></entry> + <entry> + Also sets <varname>implicit_cache</varname>. + <emphasis>(settable since 4.2)</emphasis> + </entry> +</row> + +<row> + <entry><varname>implicit_deps_unchanged</varname></entry> + <entry><option>--implicit-deps-unchanged</option></entry> + <entry> + Also sets <varname>implicit_cache</varname>. + <emphasis>(settable since 4.2)</emphasis> + </entry> +</row> + +<row> + <entry><varname>max_drift</varname></entry> + <entry><option>--max-drift</option></entry> +</row> + +<row> + <entry><varname>md5_chunksize</varname></entry> + <entry><option>--md5-chunksize</option></entry> +</row> + +<row> + <entry><varname>no_exec</varname></entry> + <entry> + <option>-n</option>, + <option>--no-exec</option>, + <option>--just-print</option>, + <option>--dry-run</option>, + <option>--recon</option> + </entry> +</row> + +<row> + <entry><varname>no_progress</varname></entry> + <entry><option>-Q</option></entry> + <entry>See + <footnote> + <para>If <varname>no_progress</varname> is set via &f-SetOption; + in an SConscript file + (but not if set in a <filename>site_init.py</filename> file) + there will still be an initial status message about + reading SConscript files since &SCons; has + to start reading them before it can see the + &f-SetOption;. + </para> + </footnote> + </entry> +</row> + +<row> + <entry><varname>num_jobs</varname></entry> + <entry><option>-j</option>, <option>--jobs</option></entry> +</row> + +<row> + <entry><varname>random</varname></entry> + <entry><option>--random</option></entry> +</row> + +<row> + <entry><varname>silent</varname></entry> + <entry> + <option>-s</option>, + <option>--silent</option>, + <option>--quiet</option> + </entry> +</row> + +<row> + <entry><varname>stack_size</varname></entry> + <entry><option>--stack-size</option></entry> +</row> + +<row> + <entry><varname>warn</varname></entry> + <entry><option>--warn</option></entry> +</row> + </tbody> </tgroup> </informaltable> <para> -See the documentation in the manpage for the -corresponding command line option for information about each specific option. -Option values which are boolean in nature (that is, they are -either on or off) should be set to a true value (<constant>True</constant>, -<constant>1</constant>) or a false value (<constant>False</constant>, -<constant>0</constant>). -</para> - -<note> -<para> -If <varname>no_progress</varname> is set via &f-SetOption; -there will still be initial progress output as &SCons; has -to start reading SConscript files before it can see the -&f-SetOption; in an SConscript file: -<computeroutput>scons: Reading SConscript files ...</computeroutput> -</para> -</note> - -<para> Example: </para> <example_commands> -SetOption('max_drift', True) +SetOption('max_drift', 0) </example_commands> </summary> </scons_function> diff --git a/SCons/Script/MainTests.py b/SCons/Script/MainTests.py index 232a8a2..f7e3263 100644 --- a/SCons/Script/MainTests.py +++ b/SCons/Script/MainTests.py @@ -23,9 +23,6 @@ import unittest -import SCons.Errors -import SCons.Script.Main - # Unit tests of various classes within SCons.Script.Main.py. # # Most of the tests of this functionality are actually end-to-end scripts diff --git a/SCons/Script/SConsOptions.py b/SCons/Script/SConsOptions.py index c8c9cf8..def8663 100644 --- a/SCons/Script/SConsOptions.py +++ b/SCons/Script/SConsOptions.py @@ -129,47 +129,60 @@ class SConsValues(optparse.Values): 'clean', 'diskcheck', 'duplicate', + 'experimental', + 'hash_chunksize', 'hash_format', 'help', 'implicit_cache', + 'implicit_deps_changed', + 'implicit_deps_unchanged', 'max_drift', 'md5_chunksize', 'no_exec', + 'no_progress', 'num_jobs', 'random', + 'silent', 'stack_size', 'warn', - 'silent', - 'no_progress', - 'experimental', ] def set_option(self, name, value): + """Sets an option from an SConscript file. + + Raises: + UserError: invalid or malformed option ("error in your script") """ - Sets an option from an SConscript file. - """ + if name not in self.settable: - raise SCons.Errors.UserError("This option is not settable from a SConscript file: %s"%name) + raise SCons.Errors.UserError( + "This option is not settable from a SConscript file: %s" % name + ) + # the following are for options that need some extra processing if name == 'num_jobs': try: value = int(value) if value < 1: raise ValueError except ValueError: - raise SCons.Errors.UserError("A positive integer is required: %s"%repr(value)) + raise SCons.Errors.UserError( + "A positive integer is required: %s" % repr(value) + ) elif name == 'max_drift': try: value = int(value) except ValueError: - raise SCons.Errors.UserError("An integer is required: %s"%repr(value)) + raise SCons.Errors.UserError("An integer is required: %s" % repr(value)) elif name == 'duplicate': try: value = str(value) except ValueError: - raise SCons.Errors.UserError("A string is required: %s"%repr(value)) + raise SCons.Errors.UserError("A string is required: %s" % repr(value)) if value not in SCons.Node.FS.Valid_Duplicates: - raise SCons.Errors.UserError("Not a valid duplication style: %s" % value) + raise SCons.Errors.UserError( + "Not a valid duplication style: %s" % value + ) # Set the duplicate style right away so it can affect linking # of SConscript files. SCons.Node.FS.set_duplicate(value) @@ -177,7 +190,7 @@ class SConsValues(optparse.Values): try: value = diskcheck_convert(value) except ValueError as v: - raise SCons.Errors.UserError("Not a valid diskcheck value: %s"%v) + raise SCons.Errors.UserError("Not a valid diskcheck value: %s" % v) if 'diskcheck' not in self.__dict__: # No --diskcheck= option was specified on the command line. # Set this right away so it can affect the rest of the @@ -187,12 +200,13 @@ class SConsValues(optparse.Values): try: value = int(value) except ValueError: - raise SCons.Errors.UserError("An integer is required: %s"%repr(value)) - elif name == 'md5_chunksize': + raise SCons.Errors.UserError("An integer is required: %s" % repr(value)) + elif name in ('md5_chunksize', 'hash_chunksize'): try: value = int(value) except ValueError: - raise SCons.Errors.UserError("An integer is required: %s"%repr(value)) + raise SCons.Errors.UserError("An integer is required: %s" % repr(value)) + name = 'md5_chunksize' # for now, the old name is used elif name == 'warn': if SCons.Util.is_String(value): value = [value] @@ -204,8 +218,9 @@ class SConsValues(optparse.Values): if SCons.Util.is_String(value): value = [value] value = self.__SConscript_settings__.get(name, []) + value - - + elif name in ('implicit_deps_changed', 'implicit_deps_unchanged'): + if value: + self.__SConscript_settings__['implicit_cache'] = True self.__SConscript_settings__[name] = value diff --git a/SCons/Script/SConscriptTests.py b/SCons/Script/SConscriptTests.py index bb88dfa..e6a8be5 100644 --- a/SCons/Script/SConscriptTests.py +++ b/SCons/Script/SConscriptTests.py @@ -21,8 +21,6 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -import SCons.Script.SConscript - # all of the SConscript.py tests are in test/SConscript.py # Local Variables: diff --git a/SCons/Script/__init__.py b/SCons/Script/__init__.py index dff1567..5f58d99 100644 --- a/SCons/Script/__init__.py +++ b/SCons/Script/__init__.py @@ -255,7 +255,7 @@ def HelpFunction(text, append=False): if help_text is None: if append: s = StringIO() - PrintHelp(s) + PrintHelp(s) help_text = s.getvalue() s.close() else: diff --git a/SCons/Subst.py b/SCons/Subst.py index f23b2d0..4d732c3 100644 --- a/SCons/Subst.py +++ b/SCons/Subst.py @@ -217,10 +217,6 @@ class Targets_or_Sources(collections.UserList): def __getitem__(self, i): nl = self.nl._create_nodelist() return nl[i] - def __getslice__(self, i, j): - nl = self.nl._create_nodelist() - i = max(i, 0); j = max(j, 0) - return nl[i:j] def __str__(self): nl = self.nl._create_nodelist() return str(nl) diff --git a/SCons/Tool/GettextCommon.py b/SCons/Tool/GettextCommon.py index 5da4517..16900e0 100644 --- a/SCons/Tool/GettextCommon.py +++ b/SCons/Tool/GettextCommon.py @@ -1,9 +1,6 @@ -"""SCons.Tool.GettextCommon module - -Used by several tools of `gettext` toolset. -""" - -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -24,38 +21,49 @@ Used by several tools of `gettext` toolset. # 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__" +"""Common routines for gettext tools -import SCons.Warnings +Used by several tools of `gettext` toolset. +""" + +import os import re +import SCons.Util +import SCons.Warnings -############################################################################# -class XgettextToolWarning(SCons.Warnings.SConsWarning): pass +class XgettextToolWarning(SCons.Warnings.SConsWarning): + pass -class XgettextNotFound(XgettextToolWarning): pass +class XgettextNotFound(XgettextToolWarning): + pass -class MsginitToolWarning(SCons.Warnings.SConsWarning): pass +class MsginitToolWarning(SCons.Warnings.SConsWarning): + pass -class MsginitNotFound(MsginitToolWarning): pass +class MsginitNotFound(MsginitToolWarning): + pass -class MsgmergeToolWarning(SCons.Warnings.SConsWarning): pass +class MsgmergeToolWarning(SCons.Warnings.SConsWarning): + pass -class MsgmergeNotFound(MsgmergeToolWarning): pass +class MsgmergeNotFound(MsgmergeToolWarning): + pass -class MsgfmtToolWarning(SCons.Warnings.SConsWarning): pass +class MsgfmtToolWarning(SCons.Warnings.SConsWarning): + pass -class MsgfmtNotFound(MsgfmtToolWarning): pass +class MsgfmtNotFound(MsgfmtToolWarning): + pass -############################################################################# SCons.Warnings.enableWarningClass(XgettextToolWarning) SCons.Warnings.enableWarningClass(XgettextNotFound) SCons.Warnings.enableWarningClass(MsginitToolWarning) @@ -66,9 +74,6 @@ SCons.Warnings.enableWarningClass(MsgfmtToolWarning) SCons.Warnings.enableWarningClass(MsgfmtNotFound) -############################################################################# - -############################################################################# class _POTargetFactory: """ A factory of `PO` target files. @@ -101,7 +106,6 @@ class _POTargetFactory: def _create_node(self, name, factory, directory=None, create=1): """ Create node, and set it up to factory settings. """ - import SCons.Util node = factory(name, directory, create) node.set_noclean(self.noclean) node.set_precious(self.precious) @@ -120,18 +124,12 @@ class _POTargetFactory: return self._create_node(name, self.env.fs.File, directory, create) -############################################################################# - -############################################################################# _re_comment = re.compile(r'(#[^\n\r]+)$', re.M) _re_lang = re.compile(r'([a-zA-Z0-9_]+)', re.M) -############################################################################# def _read_linguas_from_files(env, linguas_files=None): """ Parse `LINGUAS` file and return list of extracted languages """ - import SCons.Util - import SCons.Environment global _re_comment global _re_lang if not SCons.Util.is_List(linguas_files) \ @@ -151,13 +149,9 @@ def _read_linguas_from_files(env, linguas_files=None): return linguas -############################################################################# - -############################################################################# from SCons.Builder import BuilderBase -############################################################################# class _POFileBuilder(BuilderBase): """ `PO` file builder. @@ -222,7 +216,6 @@ class _POFileBuilder(BuilderBase): The arguments and return value are same as for `SCons.Builder.BuilderBase._execute()`. """ - import SCons.Util import SCons.Node linguas_files = None if 'LINGUAS_FILE' in env and env['LINGUAS_FILE']: @@ -252,12 +245,6 @@ class _POFileBuilder(BuilderBase): return SCons.Node.NodeList(result) -############################################################################# - -import SCons.Environment - - -############################################################################# def _translate(env, target=None, source=SCons.Environment._null, *args, **kw): """ Function for `Translate()` pseudo-builder """ if target is None: target = [] @@ -266,9 +253,6 @@ def _translate(env, target=None, source=SCons.Environment._null, *args, **kw): return po -############################################################################# - -############################################################################# class RPaths: """ Callable object, which returns pathnames relative to SCons current working directory. @@ -342,7 +326,6 @@ class RPaths: - Tuple of strings, which represent paths relative to current working directory (for given environment). """ - import os import SCons.Node.FS rpaths = () cwd = self.env.fs.getcwd().get_abspath() @@ -356,9 +339,6 @@ class RPaths: return rpaths -############################################################################# - -############################################################################# def _init_po_files(target, source, env): """ Action function for `POInit` builder. """ nop = lambda target, source, env: 0 @@ -383,9 +363,6 @@ def _init_po_files(target, source, env): return 0 -############################################################################# - -############################################################################# def _detect_xgettext(env): """ Detects *xgettext(1)* binary """ if 'XGETTEXT' in env: @@ -397,14 +374,10 @@ def _detect_xgettext(env): return None -############################################################################# def _xgettext_exists(env): return _detect_xgettext(env) -############################################################################# - -############################################################################# def _detect_msginit(env): """ Detects *msginit(1)* program. """ if 'MSGINIT' in env: @@ -416,14 +389,10 @@ def _detect_msginit(env): return None -############################################################################# def _msginit_exists(env): return _detect_msginit(env) -############################################################################# - -############################################################################# def _detect_msgmerge(env): """ Detects *msgmerge(1)* program. """ if 'MSGMERGE' in env: @@ -435,14 +404,10 @@ def _detect_msgmerge(env): return None -############################################################################# def _msgmerge_exists(env): return _detect_msgmerge(env) -############################################################################# - -############################################################################# def _detect_msgfmt(env): """ Detects *msgmfmt(1)* program. """ if 'MSGFMT' in env: @@ -454,16 +419,11 @@ def _detect_msgfmt(env): return None -############################################################################# def _msgfmt_exists(env): return _detect_msgfmt(env) -############################################################################# - -############################################################################# def tool_list(platform, env): """ List tools that shall be generated by top-level `gettext` tool """ return ['xgettext', 'msginit', 'msgmerge', 'msgfmt'] -############################################################################# diff --git a/SCons/Tool/MSCommon/vs.py b/SCons/Tool/MSCommon/vs.py index 0d22e29..cc8946f 100644 --- a/SCons/Tool/MSCommon/vs.py +++ b/SCons/Tool/MSCommon/vs.py @@ -65,7 +65,6 @@ class VisualStudio: return batch_file def find_vs_dir_by_vc(self, env): - SCons.Tool.MSCommon.vc.get_installed_vcs(env) dir = SCons.Tool.MSCommon.vc.find_vc_pdir(env, self.vc_version) if not dir: debug('no installed VC %s' % self.vc_version) diff --git a/SCons/Tool/applelink.py b/SCons/Tool/applelink.py index 2cdbd50..b81d2b3 100644 --- a/SCons/Tool/applelink.py +++ b/SCons/Tool/applelink.py @@ -36,7 +36,7 @@ selection method. # Even though the Mac is based on the GNU toolchain, it doesn't understand # the -rpath option, so we use the "link" tool instead of "gnulink". from SCons.Util import CLVar - +from SCons.Errors import UserError from . import link # User programmatically describes how SHLIBVERSION maps to values for compat/current. @@ -141,6 +141,24 @@ def _applelib_compatVersionFromSoVersion(source, target, env, for_signature): return "-Wl,-compatibility_version,%s" % version_string +def _applelib_soname(target, source, env, for_signature): + """ + Override default _soname() function from SCons.Tools.linkCommon.SharedLibrary. + Apple's file naming for versioned shared libraries puts the version string before + the shared library suffix (.dylib), instead of after. + """ + if "SONAME" in env: + # Now verify that SOVERSION is not also set as that is not allowed + if "SOVERSION" in env: + raise UserError( + "Ambiguous library .so naming, both SONAME: %s and SOVERSION: %s are defined. " + "Only one can be defined for a target library." + % (env["SONAME"], env["SOVERSION"]) + ) + return "$SONAME" + else: + return "$SHLIBPREFIX$_get_shlib_stem$_SHLIBSOVERSION${SHLIBSUFFIX}" + def generate(env): """Add Builders and construction variables for applelink to an @@ -178,6 +196,8 @@ def generate(env): env['__LDMODULEVERSIONFLAGS'] = '${__lib_either_version_flag(__env__,' \ '"LDMODULEVERSION","_APPLELINK_CURRENT_VERSION", "_LDMODULEVERSIONFLAGS")}' + env["_SHLIBSONAME"] = _applelib_soname + def exists(env): return env['PLATFORM'] == 'darwin' diff --git a/SCons/Tool/clang.py b/SCons/Tool/clang.py index e033cfa..6c9227c 100644 --- a/SCons/Tool/clang.py +++ b/SCons/Tool/clang.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8; -*- -# # MIT License # # Copyright The SCons Foundation @@ -22,25 +20,20 @@ # 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. -# -"""SCons.Tool.clang -Tool-specific initialization for clang. +"""Tool-specific initialization for clang. There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() selection method. - """ - # Based on SCons/Tool/gcc.py by Paweł Tomulik 2014 as a separate tool. # Brought into the SCons mainline by Russel Winder 2017. import os import re import subprocess -import sys import SCons.Util import SCons.Tool.cc diff --git a/SCons/Tool/clangxx.py b/SCons/Tool/clangxx.py index 736d455..4443b39 100644 --- a/SCons/Tool/clangxx.py +++ b/SCons/Tool/clangxx.py @@ -1,17 +1,6 @@ -# -*- coding: utf-8; -*- - -"""SCons.Tool.clang++ - -Tool-specific initialization for clang++. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -31,9 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for clang++. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" # Based on SCons/Tool/g++.py by Paweł Tomulik 2014 as a separate tool. # Brought into the SCons mainline by Russel Winder 2017. @@ -41,7 +34,6 @@ selection method. import os.path import re import subprocess -import sys import SCons.Tool import SCons.Util diff --git a/SCons/Tool/f03.py b/SCons/Tool/f03.py index 41d9c43..142c127 100644 --- a/SCons/Tool/f03.py +++ b/SCons/Tool/f03.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f03 - -Tool-specific initialization for the generic Posix f03 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for the generic Posix f03 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" -import SCons.Defaults -import SCons.Tool -import SCons.Util -from . import fortran from SCons.Tool.FortranCommon import add_all_to_env, add_f03_to_env compilers = ['f03'] diff --git a/SCons/Tool/f08.py b/SCons/Tool/f08.py index 3d1bce2..eb367c5 100644 --- a/SCons/Tool/f08.py +++ b/SCons/Tool/f08.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f08 - -Tool-specific initialization for the generic Posix f08 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for the generic Posix f08 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" -import SCons.Defaults -import SCons.Tool -import SCons.Util -from . import fortran from SCons.Tool.FortranCommon import add_all_to_env, add_f08_to_env compilers = ['f08'] diff --git a/SCons/Tool/f77.py b/SCons/Tool/f77.py index b936acd..5ff15ae 100644 --- a/SCons/Tool/f77.py +++ b/SCons/Tool/f77.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f77 - -Tool-specific initialization for the generic Posix f77 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for the generic Posix f77 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" -import SCons.Defaults -import SCons.Scanner.Fortran -import SCons.Tool -import SCons.Util from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env compilers = ['f77'] diff --git a/SCons/Tool/f90.py b/SCons/Tool/f90.py index ef7d93d..cbf3947 100644 --- a/SCons/Tool/f90.py +++ b/SCons/Tool/f90.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f90 - -Tool-specific initialization for the generic Posix f90 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for the generic Posix f90 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" -import SCons.Defaults -import SCons.Scanner.Fortran -import SCons.Tool -import SCons.Util from SCons.Tool.FortranCommon import add_all_to_env, add_f90_to_env compilers = ['f90'] diff --git a/SCons/Tool/f95.py b/SCons/Tool/f95.py index 7b56d4e..4830ee0 100644 --- a/SCons/Tool/f95.py +++ b/SCons/Tool/f95.py @@ -1,15 +1,6 @@ -"""SCons.Tool.f95 - -Tool-specific initialization for the generic Posix f95 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,14 +20,14 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for the generic Posix f95 Fortran compiler. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" -import SCons.Defaults -import SCons.Tool -import SCons.Util -from . import fortran from SCons.Tool.FortranCommon import add_all_to_env, add_f95_to_env compilers = ['f95'] diff --git a/SCons/Tool/fortran.py b/SCons/Tool/fortran.py index 0a68df6..9a095ae 100644 --- a/SCons/Tool/fortran.py +++ b/SCons/Tool/fortran.py @@ -1,15 +1,6 @@ -"""SCons.Tool.fortran - -Tool-specific initialization for a generic Posix f77/f90 Fortran compiler. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,16 +20,14 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for a generic Posix f77/f90 Fortran compiler. +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" -import SCons.Action -import SCons.Defaults -import SCons.Scanner.Fortran -import SCons.Tool -import SCons.Util from SCons.Tool.FortranCommon import add_all_to_env, add_fortran_to_env compilers = ['f95', 'f90', 'f77'] diff --git a/SCons/Tool/gettext_tool.py b/SCons/Tool/gettext_tool.py index 43ca494..a1407b3 100644 --- a/SCons/Tool/gettext_tool.py +++ b/SCons/Tool/gettext_tool.py @@ -1,9 +1,7 @@ -"""gettext tool -""" - - -# __COPYRIGHT__ -# +# MIT License +# +# Copyright The SCons Foundation +# # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including @@ -11,10 +9,10 @@ # 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 @@ -23,38 +21,49 @@ # 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__" +"""gettext tool""" + +import sys +import os -############################################################################# -def generate(env,**kw): - import sys - import os - import SCons.Tool - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +import SCons.Tool +import SCons.Warnings +from SCons.Errors import StopError +from SCons.Platform.mingw import MINGW_DEFAULT_PATHS +from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +from SCons.Tool.GettextCommon import ( + _msgfmt_exists, + _msginit_exists, + _msgmerge_exists, + tool_list, + _translate, + _xgettext_exists, +) - from SCons.Tool.GettextCommon \ - import _translate, tool_list - for t in tool_list(env['PLATFORM'], env): - if sys.platform == 'win32': - tool = SCons.Tool.find_program_path(env, t, default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if tool: - tool_bin_dir = os.path.dirname(tool) - env.AppendENVPath('PATH', tool_bin_dir) - else: - SCons.Warnings.SConsWarning(t + ' tool requested, but binary not found in ENV PATH') - env.Tool(t) - env.AddMethod(_translate, 'Translate') -############################################################################# +def generate(env, **kw): + for t in tool_list(env['PLATFORM'], env): + if sys.platform == 'win32': + tool = SCons.Tool.find_program_path( + env, t, default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS + ) + if tool: + tool_bin_dir = os.path.dirname(tool) + env.AppendENVPath('PATH', tool_bin_dir) + else: + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + t + ' tool requested, but binary not found in ENV PATH', + ) + env.Tool(t) + env.AddMethod(_translate, 'Translate') -############################################################################# def exists(env): - from SCons.Tool.GettextCommon \ - import _xgettext_exists, _msginit_exists, \ - _msgmerge_exists, _msgfmt_exists - try: - return _xgettext_exists(env) and _msginit_exists(env) \ - and _msgmerge_exists(env) and _msgfmt_exists(env) - except: - return False -############################################################################# + try: + return ( + _xgettext_exists(env) + and _msginit_exists(env) + and _msgmerge_exists(env) + and _msgfmt_exists(env) + ) + except StopError: + return False diff --git a/SCons/Tool/install.py b/SCons/Tool/install.py index d73d678..59b4a52 100644 --- a/SCons/Tool/install.py +++ b/SCons/Tool/install.py @@ -1,14 +1,6 @@ -"""SCons.Tool.install - -Tool-specific initialization for the install tool. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -28,10 +20,17 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# + +""" Tool-specific initialization for the install tool. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import os -from shutil import copy2, copymode, copystat +import stat +from shutil import copy2, copystat import SCons.Action import SCons.Tool @@ -43,7 +42,6 @@ from SCons.Tool.linkCommon import ( EmitLibSymlinks, ) -# # We keep track of *all* installed files. _INSTALLED_FILES = [] _UNIQUE_INSTALLED_FILES = None @@ -152,11 +150,14 @@ def scons_copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, # # Functions doing the actual work of the Install Builder. # -def copyFunc(dest, source, env): - """Install a source file or directory into a destination by copying, +def copyFunc(dest, source, env) -> int: + """Install a source file or directory into a destination by copying. - Mode/permissions bits will be copied as well. + Mode/permissions bits will be copied as well, except that the target + will be made writable. + Returns: + POSIX-style error code - 0 for success, non-zero for fail """ if os.path.isdir(source): if os.path.exists(dest): @@ -169,19 +170,24 @@ def copyFunc(dest, source, env): scons_copytree(source, dest, dirs_exist_ok=True) else: copy2(source, dest) - copymode(source, dest) + st = os.stat(source) + os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) return 0 # # Functions doing the actual work of the InstallVersionedLib Builder. # -def copyFuncVersionedLib(dest, source, env): - """Install a versioned library into a destination by copying, +def copyFuncVersionedLib(dest, source, env) -> int: + """Install a versioned library into a destination by copying. - Mode/permissions bits will be copied as well. Any required symbolic links for other library names are created. + Mode/permissions bits will be copied as well, except that the target + will be made writable. + + Returns: + POSIX-style error code - 0 for success, non-zero for fail """ if os.path.isdir(source): raise SCons.Errors.UserError("cannot install directory `%s' as a version library" % str(source) ) @@ -192,7 +198,8 @@ def copyFuncVersionedLib(dest, source, env): except: pass copy2(source, dest) - copymode(source, dest) + st = os.stat(source) + os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) installShlibLinks(dest, source, env) return 0 @@ -223,38 +230,58 @@ def installShlibLinks(dest, source, env): CreateLibSymlinks(env, symlinks) return -def installFunc(target, source, env): - """Install a source file into a target using the function specified - as the INSTALL construction variable.""" +def installFunc(target, source, env) -> int: + """Install a source file into a target. + + Uses the function specified in the INSTALL construction variable. + + Returns: + POSIX-style error code - 0 for success, non-zero for fail + """ + try: install = env['INSTALL'] except KeyError: raise SCons.Errors.UserError('Missing INSTALL construction variable.') - assert len(target)==len(source), \ - "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(map(str, target))) - for t,s in zip(target,source): - if install(t.get_path(),s.get_path(),env): + assert len(target) == len(source), ( + "Installing source %s into target %s: " + "target and source lists must have same length." + % (list(map(str, source)), list(map(str, target))) + ) + for t, s in zip(target, source): + if install(t.get_path(), s.get_path(), env): return 1 return 0 -def installFuncVersionedLib(target, source, env): - """Install a versioned library into a target using the function specified - as the INSTALLVERSIONEDLIB construction variable.""" +def installFuncVersionedLib(target, source, env) -> int: + """Install a versioned library into a target. + + Uses the function specified in the INSTALL construction variable. + + Returns: + POSIX-style error code - 0 for success, non-zero for fail + """ + try: install = env['INSTALLVERSIONEDLIB'] except KeyError: - raise SCons.Errors.UserError('Missing INSTALLVERSIONEDLIB construction variable.') - - assert len(target)==len(source), \ - "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(map(str, target))) - for t,s in zip(target,source): + raise SCons.Errors.UserError( + 'Missing INSTALLVERSIONEDLIB construction variable.' + ) + + assert len(target) == len(source), ( + "Installing source %s into target %s: " + "target and source lists must have same length." + % (list(map(str, source)), list(map(str, target))) + ) + for t, s in zip(target, source): if hasattr(t.attributes, 'shlibname'): tpath = os.path.join(t.get_dir(), t.attributes.shlibname) else: tpath = t.get_path() - if install(tpath,s.get_path(),env): + if install(tpath, s.get_path(), env): return 1 return 0 @@ -461,12 +488,12 @@ def generate(env): try: env['INSTALL'] except KeyError: - env['INSTALL'] = copyFunc + env['INSTALL'] = copyFunc try: env['INSTALLVERSIONEDLIB'] except KeyError: - env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib + env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib def exists(env): return 1 diff --git a/SCons/Tool/intelc.py b/SCons/Tool/intelc.py index 5025719..0d07c72 100644 --- a/SCons/Tool/intelc.py +++ b/SCons/Tool/intelc.py @@ -1,16 +1,6 @@ -"""SCons.Tool.icl - -Tool-specific initialization for the Intel C/C++ compiler. -Supports Linux and Windows compilers, v7 and up. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,7 +20,15 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +"""Tool-specific initialization for the Intel C/C++ compiler. + +Supports Linux and Windows compilers, v7 and up. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import glob import math @@ -454,20 +452,26 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): # on $PATH and the user is importing their env. class ICLTopDirWarning(SCons.Warnings.SConsWarning): pass - if (is_mac or is_linux) and not env.Detect('icc') or \ - is_windows and not env.Detect('icl'): + if ( + ((is_mac or is_linux) and not env.Detect('icc')) + or (is_windows and not env.Detect('icl')) + ): SCons.Warnings.enableWarningClass(ICLTopDirWarning) - SCons.Warnings.warn(ICLTopDirWarning, - "Failed to find Intel compiler for version='%s', abi='%s'"% - (str(version), str(abi))) + SCons.Warnings.warn( + ICLTopDirWarning, + "Failed to find Intel compiler for version='%s', abi='%s'" + % (str(version), str(abi)), + ) else: # should be cleaned up to say what this other version is # since in this case we have some other Intel compiler installed SCons.Warnings.enableWarningClass(ICLTopDirWarning) - SCons.Warnings.warn(ICLTopDirWarning, - "Can't find Intel compiler top dir for version='%s', abi='%s'"% - (str(version), str(abi))) + SCons.Warnings.warn( + ICLTopDirWarning, + "Can't find Intel compiler top dir for version='%s', abi='%s'" + % (str(version), str(abi)), + ) if topdir: archdir={'x86_64': 'intel64', @@ -576,11 +580,14 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): class ICLLicenseDirWarning(SCons.Warnings.SConsWarning): pass SCons.Warnings.enableWarningClass(ICLLicenseDirWarning) - SCons.Warnings.warn(ICLLicenseDirWarning, - "Intel license dir was not found." - " Tried using the INTEL_LICENSE_FILE environment variable (%s), the registry (%s) and the default path (%s)." - " Using the default path as a last resort." - % (envlicdir, reglicdir, defaultlicdir)) + SCons.Warnings.warn( + ICLLicenseDirWarning, + "Intel license dir was not found. " + "Tried using the INTEL_LICENSE_FILE environment variable " + "(%s), the registry (%s) and the default path (%s). " + "Using the default path as a last resort." + % (envlicdir, reglicdir, defaultlicdir) + ) env['ENV']['INTEL_LICENSE_FILE'] = licdir def exists(env): diff --git a/SCons/Tool/jar.py b/SCons/Tool/jar.py index fa29987..a19c40a 100644 --- a/SCons/Tool/jar.py +++ b/SCons/Tool/jar.py @@ -1,15 +1,6 @@ -"""SCons.Tool.jar - -Tool-specific initialization for jar. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,13 +20,19 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for jar. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + import os import SCons.Subst import SCons.Util +import SCons.Warnings from SCons.Node.FS import _my_normcase from SCons.Tool.JavaCommon import get_java_install_dirs @@ -101,8 +98,10 @@ def Jar(env, target = None, source = [], *args, **kw): # no target and want implicit target to be made and the arg # was actaully the list of sources if SCons.Util.is_List(target) and source == []: - SCons.Warnings.SConsWarning("Making implicit target jar file, " + - "and treating the list as sources") + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + "Making implicit target jar file, and treating the list as sources" + ) source = target target = None @@ -123,7 +122,10 @@ def Jar(env, target = None, source = [], *args, **kw): target = os.path.splitext(str(source[0]))[0] + env.subst('$JARSUFFIX') except: # something strange is happening but attempt anyways - SCons.Warnings.SConsWarning("Could not make implicit target from sources, using directory") + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + "Could not make implicit target from sources, using directory" + ) target = os.path.basename(str(env.Dir('.'))) + env.subst('$JARSUFFIX') # make lists out of our target and sources @@ -192,7 +194,11 @@ def Jar(env, target = None, source = [], *args, **kw): except: pass - SCons.Warnings.SConsWarning("File: " + str(s) + " could not be identified as File or Directory, skipping.") + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + ("File: " + str(s) + + " could not be identified as File or Directory, skipping.") + ) # at this point all our sources have been converted to classes or directories of class # so pass it to the Jar builder diff --git a/SCons/Tool/lex.py b/SCons/Tool/lex.py index a9f7a8a..d8d8de4 100644 --- a/SCons/Tool/lex.py +++ b/SCons/Tool/lex.py @@ -1,15 +1,6 @@ -"""SCons.Tool.lex - -Tool-specific initialization for lex. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,9 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for lex. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import os.path import sys @@ -39,6 +34,7 @@ import sys import SCons.Action import SCons.Tool import SCons.Util +import SCons.Warnings from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS from SCons.Platform.win32 import CHOCO_DEFAULT_PATH @@ -93,7 +89,11 @@ def get_lex_path(env, append_paths=False): if append_paths: env.AppendENVPath('PATH', os.path.dirname(bin_path)) return bin_path - SCons.Warnings.SConsWarning('lex tool requested, but lex or flex binary not found in ENV PATH') + + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'lex tool requested, but lex or flex binary not found in ENV PATH' + ) def generate(env): diff --git a/SCons/Tool/link.py b/SCons/Tool/link.py index efc84f1..24d17a3 100644 --- a/SCons/Tool/link.py +++ b/SCons/Tool/link.py @@ -21,9 +21,9 @@ # 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. -# + """ -Tool-specific initialization for the generic Posix linker. +Tool-specific initialization for the generic POSIX linker. There normally shouldn't be any need to import this module directly. It will usually be imported through the generic SCons.Tool.Tool() diff --git a/SCons/Tool/linkCommon/SharedLibrary.py b/SCons/Tool/linkCommon/SharedLibrary.py index 2a079bf..6a12dd4 100644 --- a/SCons/Tool/linkCommon/SharedLibrary.py +++ b/SCons/Tool/linkCommon/SharedLibrary.py @@ -166,8 +166,12 @@ def _get_shlib_dir(target, source, env, for_signature: bool) -> str: Returns: the directory the library will be in (empty string if '.') """ + verbose = False + if target.dir and str(target.dir) != ".": - print("target.dir:%s" % target.dir) + if verbose: + print("_get_shlib_dir: target.dir:%s" % target.dir) + return "%s/" % str(target.dir) else: return "" diff --git a/SCons/Tool/msgfmt.py b/SCons/Tool/msgfmt.py index 3a77fc6..a15c1dc 100644 --- a/SCons/Tool/msgfmt.py +++ b/SCons/Tool/msgfmt.py @@ -1,7 +1,7 @@ -""" msgfmt tool """ - -# __COPYRIGHT__ -# +# MIT License +# +# Copyright The SCons Foundation +# # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including @@ -9,10 +9,10 @@ # 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 @@ -21,99 +21,109 @@ # 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__" +""" msgfmt tool """ +import sys +import os + +import SCons.Action +import SCons.Tool +import SCons.Util +import SCons.Warnings from SCons.Builder import BuilderBase -############################################################################# +from SCons.Errors import StopError +from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +from SCons.Platform.mingw import MINGW_DEFAULT_PATHS +from SCons.Tool.GettextCommon import ( + _detect_msgfmt, + _msgfmt_exists, + # MsgfmtToolWarning, + _read_linguas_from_files, +) + class _MOFileBuilder(BuilderBase): - """ The builder class for `MO` files. - - The reason for this builder to exists and its purpose is quite simillar - as for `_POFileBuilder`. This time, we extend list of sources, not targets, - and call `BuilderBase._execute()` only once (as we assume single-target - here). - """ - - def _execute(self, env, target, source, *args, **kw): - # Here we add support for 'LINGUAS_FILE' keyword. Emitter is not suitable - # in this case, as it is called too late (after multiple sources - # are handled single_source builder. - import SCons.Util - from SCons.Tool.GettextCommon import _read_linguas_from_files - linguas_files = None - if 'LINGUAS_FILE' in env and env['LINGUAS_FILE'] is not None: - linguas_files = env['LINGUAS_FILE'] - # This should prevent from endless recursion. - env['LINGUAS_FILE'] = None - # We read only languages. Suffixes shall be added automatically. - linguas = _read_linguas_from_files(env, linguas_files) - if SCons.Util.is_List(source): - source.extend(linguas) - elif source is not None: - source = [source] + linguas - else: - source = linguas - result = BuilderBase._execute(self,env,target,source,*args, **kw) - if linguas_files is not None: - env['LINGUAS_FILE'] = linguas_files - return result -############################################################################# - -############################################################################# + """The builder class for `MO` files. + + The reason for this builder to exists and its purpose is quite simillar + as for `_POFileBuilder`. This time, we extend list of sources, not targets, + and call `BuilderBase._execute()` only once (as we assume single-target + here). + """ + + def _execute(self, env, target, source, *args, **kw): + # Here we add support for 'LINGUAS_FILE' keyword. Emitter is not suitable + # in this case, as it is called too late (after multiple sources + # are handled single_source builder. + + linguas_files = None + if 'LINGUAS_FILE' in env and env['LINGUAS_FILE'] is not None: + linguas_files = env['LINGUAS_FILE'] + # This should prevent from endless recursion. + env['LINGUAS_FILE'] = None + # We read only languages. Suffixes shall be added automatically. + linguas = _read_linguas_from_files(env, linguas_files) + if SCons.Util.is_List(source): + source.extend(linguas) + elif source is not None: + source = [source] + linguas + else: + source = linguas + result = BuilderBase._execute(self, env, target, source, *args, **kw) + if linguas_files is not None: + env['LINGUAS_FILE'] = linguas_files + return result + + def _create_mo_file_builder(env, **kw): - """ Create builder object for `MOFiles` builder """ - import SCons.Action - # FIXME: What factory use for source? Ours or their? - kw['action'] = SCons.Action.Action('$MSGFMTCOM','$MSGFMTCOMSTR') - kw['suffix'] = '$MOSUFFIX' - kw['src_suffix'] = '$POSUFFIX' - kw['src_builder'] = '_POUpdateBuilder' - kw['single_source'] = True - return _MOFileBuilder(**kw) -############################################################################# - -############################################################################# -def generate(env,**kw): - """ Generate `msgfmt` tool """ - import sys - import os - import SCons.Util - import SCons.Tool - from SCons.Tool.GettextCommon import _detect_msgfmt - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - if sys.platform == 'win32': - msgfmt = SCons.Tool.find_program_path(env, 'msgfmt', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if msgfmt: - msgfmt_bin_dir = os.path.dirname(msgfmt) - env.AppendENVPath('PATH', msgfmt_bin_dir) - else: - SCons.Warnings.SConsWarning('msgfmt tool requested, but binary not found in ENV PATH') - - try: - env['MSGFMT'] = _detect_msgfmt(env) - except: - env['MSGFMT'] = 'msgfmt' - env.SetDefault( - MSGFMTFLAGS = [ SCons.Util.CLVar('-c') ], - MSGFMTCOM = '$MSGFMT $MSGFMTFLAGS -o $TARGET $SOURCE', - MSGFMTCOMSTR = '', - MOSUFFIX = ['.mo'], - POSUFFIX = ['.po'] - ) - env.Append( BUILDERS = { 'MOFiles' : _create_mo_file_builder(env) } ) -############################################################################# - -############################################################################# + """ Create builder object for `MOFiles` builder """ + + # FIXME: What factory use for source? Ours or their? + kw['action'] = SCons.Action.Action('$MSGFMTCOM', '$MSGFMTCOMSTR') + kw['suffix'] = '$MOSUFFIX' + kw['src_suffix'] = '$POSUFFIX' + kw['src_builder'] = '_POUpdateBuilder' + kw['single_source'] = True + return _MOFileBuilder(**kw) + + +def generate(env, **kw): + """ Generate `msgfmt` tool """ + + if sys.platform == 'win32': + msgfmt = SCons.Tool.find_program_path( + env, 'msgfmt', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS + ) + if msgfmt: + msgfmt_bin_dir = os.path.dirname(msgfmt) + env.AppendENVPath('PATH', msgfmt_bin_dir) + else: + SCons.Warnings.warn( + # MsgfmtToolWarning, # using this breaks test, so keep: + SCons.Warnings.SConsWarning, + 'msgfmt tool requested, but binary not found in ENV PATH', + ) + + try: + env['MSGFMT'] = _detect_msgfmt(env) + except StopError: + env['MSGFMT'] = 'msgfmt' + env.SetDefault( + MSGFMTFLAGS=[SCons.Util.CLVar('-c')], + MSGFMTCOM='$MSGFMT $MSGFMTFLAGS -o $TARGET $SOURCE', + MSGFMTCOMSTR='', + MOSUFFIX=['.mo'], + POSUFFIX=['.po'], + ) + env.Append(BUILDERS={'MOFiles': _create_mo_file_builder(env)}) + + def exists(env): - """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msgfmt_exists - try: - return _msgfmt_exists(env) - except: - return False -############################################################################# + """ Check if the tool exists """ + + try: + return _msgfmt_exists(env) + except StopError: + return False # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msginit.py b/SCons/Tool/msginit.py index 4b72c30..9635f57 100644 --- a/SCons/Tool/msginit.py +++ b/SCons/Tool/msginit.py @@ -1,10 +1,7 @@ -""" msginit tool - -Tool specific initialization of msginit tool. -""" - -# __COPYRIGHT__ -# +# MIT License +# +# Copyright The SCons Foundation +# # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including @@ -12,10 +9,10 @@ Tool specific initialization of msginit tool. # 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 @@ -24,107 +21,114 @@ Tool specific initialization of msginit tool. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool specific initialization of msginit tool.""" + +import sys +import os +import SCons.Action +import SCons.Tool +import SCons.Util import SCons.Warnings -import SCons.Builder +from SCons.Environment import _null +from SCons.Errors import StopError +from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +from SCons.Platform.mingw import MINGW_DEFAULT_PATHS +from SCons.Tool.GettextCommon import ( + _detect_msginit, + _init_po_files, + _msginit_exists, + # MsginitToolWarning, + _POFileBuilder, +) + -############################################################################# def _optional_no_translator_flag(env): - """ Return '--no-translator' flag if we run *msginit(1)* in non-interactive - mode.""" - import SCons.Util - if 'POAUTOINIT' in env: - autoinit = env['POAUTOINIT'] - else: - autoinit = False - if autoinit: - return [SCons.Util.CLVar('--no-translator')] - else: - return [SCons.Util.CLVar('')] -############################################################################# - -############################################################################# + """Return '--no-translator' flag if we run *msginit(1)* in non-interactive + mode.""" + if 'POAUTOINIT' in env: + autoinit = env['POAUTOINIT'] + else: + autoinit = False + if autoinit: + return [SCons.Util.CLVar('--no-translator')] + else: + return [SCons.Util.CLVar('')] + + def _POInitBuilder(env, **kw): - """ Create builder object for `POInit` builder. """ - import SCons.Action - from SCons.Tool.GettextCommon import _init_po_files, _POFileBuilder - action = SCons.Action.Action(_init_po_files, None) - return _POFileBuilder(env, action=action, target_alias='$POCREATE_ALIAS') -############################################################################# - -############################################################################# -from SCons.Environment import _null -############################################################################# + """ Create builder object for `POInit` builder. """ + + action = SCons.Action.Action(_init_po_files, None) + return _POFileBuilder(env, action=action, target_alias='$POCREATE_ALIAS') + + def _POInitBuilderWrapper(env, target=None, source=_null, **kw): - """ Wrapper for _POFileBuilder. We use it to make user's life easier. - - This wrapper checks for `$POTDOMAIN` construction variable (or override in - `**kw`) and treats it appropriatelly. - """ - if source is _null: - if 'POTDOMAIN' in kw: - domain = kw['POTDOMAIN'] - elif 'POTDOMAIN' in env: - domain = env['POTDOMAIN'] - else: - domain = 'messages' - source = [ domain ] # NOTE: Suffix shall be appended automatically - return env._POInitBuilder(target, source, **kw) -############################################################################# - -############################################################################# -def generate(env,**kw): - """ Generate the `msginit` tool """ - import sys - import os - import SCons.Util - import SCons.Tool - from SCons.Tool.GettextCommon import _detect_msginit - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - if sys.platform == 'win32': - msginit = SCons.Tool.find_program_path(env, 'msginit', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if msginit: - msginit_bin_dir = os.path.dirname(msginit) - env.AppendENVPath('PATH', msginit_bin_dir) - else: - SCons.Warnings.SConsWarning('msginit tool requested, but binary not found in ENV PATH') - - try: - env['MSGINIT'] = _detect_msginit(env) - except: - env['MSGINIT'] = 'msginit' - msginitcom = '$MSGINIT ${_MSGNoTranslator(__env__)} -l ${_MSGINITLOCALE}' \ - + ' $MSGINITFLAGS -i $SOURCE -o $TARGET' - # NOTE: We set POTSUFFIX here, in case the 'xgettext' is not loaded - # (sometimes we really don't need it) - env.SetDefault( - POSUFFIX = ['.po'], - POTSUFFIX = ['.pot'], - _MSGINITLOCALE = '${TARGET.filebase}', - _MSGNoTranslator = _optional_no_translator_flag, - MSGINITCOM = msginitcom, - MSGINITCOMSTR = '', - MSGINITFLAGS = [ ], - POAUTOINIT = False, - POCREATE_ALIAS = 'po-create' - ) - env.Append( BUILDERS = { '_POInitBuilder' : _POInitBuilder(env) } ) - env.AddMethod(_POInitBuilderWrapper, 'POInit') - env.AlwaysBuild(env.Alias('$POCREATE_ALIAS')) -############################################################################# - -############################################################################# + """Wrapper for _POFileBuilder. We use it to make user's life easier. + + This wrapper checks for `$POTDOMAIN` construction variable (or override in + `**kw`) and treats it appropriatelly. + """ + if source is _null: + if 'POTDOMAIN' in kw: + domain = kw['POTDOMAIN'] + elif 'POTDOMAIN' in env: + domain = env['POTDOMAIN'] + else: + domain = 'messages' + source = [domain] # NOTE: Suffix shall be appended automatically + return env._POInitBuilder(target, source, **kw) + +def generate(env, **kw): + """ Generate the `msginit` tool """ + + if sys.platform == 'win32': + msginit = SCons.Tool.find_program_path( + env, 'msginit', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS + ) + if msginit: + msginit_bin_dir = os.path.dirname(msginit) + env.AppendENVPath('PATH', msginit_bin_dir) + else: + SCons.Warnings.warn( + # MsginitToolWarning, # using this breaks test, so keep: + SCons.Warnings.SConsWarning, + 'msginit tool requested, but binary not found in ENV PATH', + ) + + try: + env['MSGINIT'] = _detect_msginit(env) + except StopError: + env['MSGINIT'] = 'msginit' + msginitcom = ( + '$MSGINIT ${_MSGNoTranslator(__env__)} -l ${_MSGINITLOCALE}' + + ' $MSGINITFLAGS -i $SOURCE -o $TARGET' + ) + # NOTE: We set POTSUFFIX here, in case the 'xgettext' is not loaded + # (sometimes we really don't need it) + env.SetDefault( + POSUFFIX=['.po'], + POTSUFFIX=['.pot'], + _MSGINITLOCALE='${TARGET.filebase}', + _MSGNoTranslator=_optional_no_translator_flag, + MSGINITCOM=msginitcom, + MSGINITCOMSTR='', + MSGINITFLAGS=[], + POAUTOINIT=False, + POCREATE_ALIAS='po-create', + ) + env.Append(BUILDERS={'_POInitBuilder': _POInitBuilder(env)}) + env.AddMethod(_POInitBuilderWrapper, 'POInit') + env.AlwaysBuild(env.Alias('$POCREATE_ALIAS')) + + def exists(env): - """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msginit_exists - try: - return _msginit_exists(env) - except: - return False -############################################################################# + """ Check if the tool exists """ + + try: + return _msginit_exists(env) + except StopError: + return False # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msgmerge.py b/SCons/Tool/msgmerge.py index 4551235..69508eb 100644 --- a/SCons/Tool/msgmerge.py +++ b/SCons/Tool/msgmerge.py @@ -1,10 +1,7 @@ -""" msgmerget tool - -Tool specific initialization for `msgmerge` tool. -""" - -# __COPYRIGHT__ -# +# MIT License +# +# Copyright The SCons Foundation +# # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including @@ -12,10 +9,10 @@ Tool specific initialization for `msgmerge` tool. # 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 @@ -24,91 +21,102 @@ Tool specific initialization for `msgmerge` tool. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool specific initialization for `msgmerge` tool.""" + +import sys +import os + +import SCons.Action +import SCons.Tool +import SCons.Warnings +from SCons.Errors import StopError +from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS +from SCons.Platform.mingw import MINGW_DEFAULT_PATHS +from SCons.Tool.GettextCommon import ( + _detect_msgmerge, + _init_po_files, + _msgmerge_exists, + # MsgmergeToolWarning, + _POFileBuilder, +) -############################################################################# def _update_or_init_po_files(target, source, env): - """ Action function for `POUpdate` builder """ - import SCons.Action - from SCons.Tool.GettextCommon import _init_po_files - for tgt in target: - if tgt.rexists(): - action = SCons.Action.Action('$MSGMERGECOM', '$MSGMERGECOMSTR') - else: - action = _init_po_files - status = action([tgt], source, env) - if status : return status - return 0 -############################################################################# - -############################################################################# + """ Action function for `POUpdate` builder """ + + for tgt in target: + if tgt.rexists(): + action = SCons.Action.Action('$MSGMERGECOM', '$MSGMERGECOMSTR') + else: + action = _init_po_files + status = action([tgt], source, env) + if status: + return status + return 0 + + def _POUpdateBuilder(env, **kw): - """ Create an object of `POUpdate` builder """ - import SCons.Action - from SCons.Tool.GettextCommon import _POFileBuilder - action = SCons.Action.Action(_update_or_init_po_files, None) - return _POFileBuilder(env, action=action, target_alias='$POUPDATE_ALIAS') -############################################################################# - -############################################################################# + """ Create an object of `POUpdate` builder """ + + action = SCons.Action.Action(_update_or_init_po_files, None) + return _POFileBuilder(env, action=action, target_alias='$POUPDATE_ALIAS') + + from SCons.Environment import _null -############################################################################# + + def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): - """ Wrapper for `POUpdate` builder - make user's life easier """ - if source is _null: - if 'POTDOMAIN' in kw: - domain = kw['POTDOMAIN'] - elif 'POTDOMAIN' in env and env['POTDOMAIN']: - domain = env['POTDOMAIN'] - else: - domain = 'messages' - source = [ domain ] # NOTE: Suffix shall be appended automatically - return env._POUpdateBuilder(target, source, **kw) -############################################################################# - -############################################################################# -def generate(env,**kw): - """ Generate the `msgmerge` tool """ - import sys - import os - import SCons.Tool - from SCons.Tool.GettextCommon import _detect_msgmerge - from SCons.Platform.mingw import MINGW_DEFAULT_PATHS - from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS - - if sys.platform == 'win32': - msgmerge = SCons.Tool.find_program_path(env, 'msgmerge', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) - if msgmerge: - msgmerge_bin_dir = os.path.dirname(msgmerge) - env.AppendENVPath('PATH', msgmerge_bin_dir) - else: - SCons.Warnings.SConsWarning('msgmerge tool requested, but binary not found in ENV PATH') - try: - env['MSGMERGE'] = _detect_msgmerge(env) - except: - env['MSGMERGE'] = 'msgmerge' - env.SetDefault( - POTSUFFIX = ['.pot'], - POSUFFIX = ['.po'], - MSGMERGECOM = '$MSGMERGE $MSGMERGEFLAGS --update $TARGET $SOURCE', - MSGMERGECOMSTR = '', - MSGMERGEFLAGS = [ ], - POUPDATE_ALIAS = 'po-update' - ) - env.Append(BUILDERS = { '_POUpdateBuilder':_POUpdateBuilder(env) }) - env.AddMethod(_POUpdateBuilderWrapper, 'POUpdate') - env.AlwaysBuild(env.Alias('$POUPDATE_ALIAS')) -############################################################################# - -############################################################################# + """ Wrapper for `POUpdate` builder - make user's life easier """ + if source is _null: + if 'POTDOMAIN' in kw: + domain = kw['POTDOMAIN'] + elif 'POTDOMAIN' in env and env['POTDOMAIN']: + domain = env['POTDOMAIN'] + else: + domain = 'messages' + source = [domain] # NOTE: Suffix shall be appended automatically + return env._POUpdateBuilder(target, source, **kw) + + +def generate(env, **kw): + """ Generate the `msgmerge` tool """ + + if sys.platform == 'win32': + msgmerge = SCons.Tool.find_program_path( + env, 'msgmerge', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS + ) + if msgmerge: + msgmerge_bin_dir = os.path.dirname(msgmerge) + env.AppendENVPath('PATH', msgmerge_bin_dir) + else: + SCons.Warnings.warn( + # MsgmergeToolWarning, # using this breaks test, so keep: + SCons.Warnings.SConsWarning, + 'msgmerge tool requested, but binary not found in ENV PATH', + ) + try: + env['MSGMERGE'] = _detect_msgmerge(env) + except StopError: + env['MSGMERGE'] = 'msgmerge' + env.SetDefault( + POTSUFFIX=['.pot'], + POSUFFIX=['.po'], + MSGMERGECOM='$MSGMERGE $MSGMERGEFLAGS --update $TARGET $SOURCE', + MSGMERGECOMSTR='', + MSGMERGEFLAGS=[], + POUPDATE_ALIAS='po-update', + ) + env.Append(BUILDERS={'_POUpdateBuilder': _POUpdateBuilder(env)}) + env.AddMethod(_POUpdateBuilderWrapper, 'POUpdate') + env.AlwaysBuild(env.Alias('$POUPDATE_ALIAS')) + + def exists(env): - """ Check if the tool exists """ - from SCons.Tool.GettextCommon import _msgmerge_exists - try: - return _msgmerge_exists(env) - except: - return False -############################################################################# + """ Check if the tool exists """ + + try: + return _msgmerge_exists(env) + except StopError: + return False # Local Variables: # tab-width:4 diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py index c398365..9fdee65 100644 --- a/SCons/Tool/msvs.py +++ b/SCons/Tool/msvs.py @@ -1,15 +1,6 @@ -"""SCons.Tool.msvs - -Tool-specific initialization for Microsoft Visual Studio project files. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,9 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import SCons.compat +""" Tool-specific initialization for Microsoft Visual Studio project files. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import base64 import uuid @@ -48,10 +43,9 @@ import SCons.Script.SConscript import SCons.PathList import SCons.Util import SCons.Warnings - -from .MSCommon import msvc_exists, msvc_setup_env_once from SCons.Defaults import processDefines from SCons.compat import PICKLE_PROTOCOL +from .MSCommon import msvc_exists, msvc_setup_env_once ############################################################################## # Below here are the classes and functions for generation of @@ -782,7 +776,7 @@ class _GenerateV6DSP(_DSPGenerator): data = pickle.loads(datas) except KeyboardInterrupt: raise - except: + except Exception: return # unable to unpickle any data for some reason self.configs.update(data) diff --git a/SCons/Tool/packaging/__init__.py b/SCons/Tool/packaging/__init__.py index c378909..68cedeb 100644 --- a/SCons/Tool/packaging/__init__.py +++ b/SCons/Tool/packaging/__init__.py @@ -1,5 +1,6 @@ +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,12 +21,7 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -"""SCons.Tool.Packaging - -SCons Packaging Tool. -""" - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""SCons Packaging Tool.""" import importlib from inspect import getfullargspec @@ -306,8 +302,11 @@ def stripinstallbuilder(target, source, env): and file.builder.name in ["InstallBuilder", "InstallAsBuilder"]) if len([src for src in source if has_no_install_location(src)]): - warn(SConsWarning, "there are files to package which have no\ - InstallBuilder attached, this might lead to irreproducible packages") + warn( + SConsWarning, + "there are files to package which have no InstallBuilder " + "attached, this might lead to irreproducible packages" + ) n_source = [] for s in source: diff --git a/SCons/Tool/qt.py b/SCons/Tool/qt.py index d8a51b2..2fd7294 100644 --- a/SCons/Tool/qt.py +++ b/SCons/Tool/qt.py @@ -1,16 +1,6 @@ - -"""SCons.Tool.qt - -Tool-specific initialization for Qt. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,8 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +"""Tool-specific initialization for Qt. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import os.path import re diff --git a/SCons/Tool/swig.py b/SCons/Tool/swig.py index 48d65d4..fa9d93b 100644 --- a/SCons/Tool/swig.py +++ b/SCons/Tool/swig.py @@ -1,14 +1,6 @@ -"""SCons.Tool.swig - -Tool-specific initialization for swig. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -28,9 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for swig. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import os.path import sys @@ -42,6 +38,7 @@ import SCons.Defaults import SCons.Tool import SCons.Util import SCons.Node +import SCons.Warnings verbose = False @@ -190,7 +187,10 @@ def generate(env): swig_bin_dir = os.path.dirname(swig) env.AppendENVPath('PATH', swig_bin_dir) else: - SCons.Warnings.SConsWarning('swig tool requested, but binary not found in ENV PATH') + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'swig tool requested, but binary not found in ENV PATH' + ) if 'SWIG' not in env: env['SWIG'] = env.Detect(swigs) or swigs[0] diff --git a/SCons/Tool/tex.py b/SCons/Tool/tex.py index 0ca7e2d..3a133b8 100644 --- a/SCons/Tool/tex.py +++ b/SCons/Tool/tex.py @@ -1,16 +1,6 @@ -"""SCons.Tool.tex - -Tool-specific initialization for TeX. -Generates .dvi files from .tex files - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -30,8 +20,15 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" Tool-specific initialization for TeX. + +Generates .dvi files from .tex files + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import os.path import re @@ -867,7 +864,7 @@ def generate_darwin(env): if platform.system() == 'Darwin': try: ospath = env['ENV']['PATHOSX'] - except: + except KeyError: ospath = None if ospath: env.AppendENVPath('PATH', ospath) diff --git a/SCons/Tool/xgettext.py b/SCons/Tool/xgettext.py index ae40555..ed76e25 100644 --- a/SCons/Tool/xgettext.py +++ b/SCons/Tool/xgettext.py @@ -1,9 +1,6 @@ -""" xgettext tool - -Tool specific initialization of `xgettext` tool. -""" - -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -24,7 +21,7 @@ Tool specific initialization of `xgettext` tool. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool specific initialization of `xgettext` tool.""" import os import re @@ -35,16 +32,20 @@ import SCons.Action import SCons.Node.FS import SCons.Tool import SCons.Util +import SCons.Warnings from SCons.Builder import BuilderBase from SCons.Environment import _null from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS from SCons.Platform.mingw import MINGW_DEFAULT_PATHS -from SCons.Tool.GettextCommon import _POTargetFactory -from SCons.Tool.GettextCommon import RPaths, _detect_xgettext -from SCons.Tool.GettextCommon import _xgettext_exists +from SCons.Tool.GettextCommon import ( + _detect_xgettext, + _POTargetFactory, + RPaths, + _xgettext_exists, + # XgettextToolWarning, +) -############################################################################# class _CmdRunner: """ Callable object, which runs shell command storing its stdout and stderr to variables. It also provides `strfunction()` method, which shall be used by @@ -81,9 +82,6 @@ class _CmdRunner: return s -############################################################################# - -############################################################################# def _update_pot_file(target, source, env): """ Action function for `POTUpdate` builder """ nop = lambda target, source, env: 0 @@ -160,9 +158,6 @@ def _update_pot_file(target, source, env): return 0 -############################################################################# - -############################################################################# class _POTBuilder(BuilderBase): def _execute(self, env, target, source, *args): if not target: @@ -174,9 +169,6 @@ class _POTBuilder(BuilderBase): return BuilderBase._execute(self, env, target, source, *args) -############################################################################# - -############################################################################# def _scan_xgettext_from_files(target, source, env, files=None, path=None): """ Parses `POTFILES.in`-like file and returns list of extracted file names. """ @@ -226,9 +218,6 @@ def _scan_xgettext_from_files(target, source, env, files=None, path=None): return 0 -############################################################################# - -############################################################################# def _pot_update_emitter(target, source, env): """ Emitter function for `POTUpdate` builder """ if 'XGETTEXTFROM' in env: @@ -255,16 +244,10 @@ def _pot_update_emitter(target, source, env): return target, source -############################################################################# - -############################################################################# def _POTUpdateBuilderWrapper(env, target=None, source=_null, **kw): return env._POTUpdateBuilder(target, source, **kw) -############################################################################# - -############################################################################# def _POTUpdateBuilder(env, **kw): """ Creates `POTUpdate` builder object """ kw['action'] = SCons.Action.Action(_update_pot_file, None) @@ -274,9 +257,6 @@ def _POTUpdateBuilder(env, **kw): return _POTBuilder(**kw) -############################################################################# - -############################################################################# def generate(env, **kw): """ Generate `xgettext` tool """ @@ -286,7 +266,11 @@ def generate(env, **kw): xgettext_bin_dir = os.path.dirname(xgettext) env.AppendENVPath('PATH', xgettext_bin_dir) else: - SCons.Warnings.SConsWarning('xgettext tool requested, but binary not found in ENV PATH') + SCons.Warnings.warn( + # XgettextToolWarning, # using this breaks test, so keep: + SCons.Warnings.SConsWarning, + 'xgettext tool requested, but binary not found in ENV PATH' + ) try: env['XGETTEXT'] = _detect_xgettext(env) except: @@ -338,9 +322,6 @@ def generate(env, **kw): env.AlwaysBuild(env.Alias('$POTUPDATE_ALIAS')) -############################################################################# - -############################################################################# def exists(env): """ Check, whether the tool exists """ try: @@ -348,7 +329,6 @@ def exists(env): except: return False -############################################################################# # Local Variables: # tab-width:4 diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index ab019b2..61ad61a 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -1,15 +1,6 @@ -"""SCons.Tool.yacc - -Tool-specific initialization for yacc. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -29,9 +20,13 @@ selection method. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Tool-specific initialization for yacc. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" import os.path import sys @@ -39,6 +34,7 @@ import sys import SCons.Defaults import SCons.Tool import SCons.Util +import SCons.Warnings from SCons.Platform.mingw import MINGW_DEFAULT_PATHS from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS from SCons.Platform.win32 import CHOCO_DEFAULT_PATH @@ -125,7 +121,10 @@ def get_yacc_path(env, append_paths=False): if append_paths: env.AppendENVPath('PATH', os.path.dirname(bin_path)) return bin_path - SCons.Warnings.SConsWarning('yacc tool requested, but yacc or bison binary not found in ENV PATH') + SCons.Warnings.warn( + SCons.Warnings.SConsWarning, + 'yacc tool requested, but yacc or bison binary not found in ENV PATH' + ) def generate(env): diff --git a/SCons/Util.py b/SCons/Util.py index 37107c9..4e575d5 100644 --- a/SCons/Util.py +++ b/SCons/Util.py @@ -745,7 +745,7 @@ else: if sys.platform == 'win32': - def WhereIs(file, path=None, pathext=None, reject=[]): + def WhereIs(file, path=None, pathext=None, reject=None): if path is None: try: path = os.environ['PATH'] @@ -764,6 +764,8 @@ if sys.platform == 'win32': if ext.lower() == file[-len(ext):].lower(): pathext = [''] break + if reject is None: + reject = [] if not is_List(reject) and not is_Tuple(reject): reject = [reject] for dir in path: @@ -780,7 +782,7 @@ if sys.platform == 'win32': elif os.name == 'os2': - def WhereIs(file, path=None, pathext=None, reject=[]): + def WhereIs(file, path=None, pathext=None, reject=None): if path is None: try: path = os.environ['PATH'] @@ -794,6 +796,8 @@ elif os.name == 'os2': if ext.lower() == file[-len(ext):].lower(): pathext = [''] break + if reject is None: + reject = [] if not is_List(reject) and not is_Tuple(reject): reject = [reject] for dir in path: @@ -810,7 +814,7 @@ elif os.name == 'os2': else: - def WhereIs(file, path=None, pathext=None, reject=[]): + def WhereIs(file, path=None, pathext=None, reject=None): import stat if path is None: try: @@ -819,6 +823,8 @@ else: return None if is_String(path): path = path.split(os.pathsep) + if reject is None: + reject = [] if not is_List(reject) and not is_Tuple(reject): reject = [reject] for d in path: @@ -1339,12 +1345,6 @@ class UniqueList(UserList): def __setitem__(self, i, item): UserList.__setitem__(self, i, item) self.unique = False - def __getslice__(self, i, j): - self.__make_unique() - return UserList.__getslice__(self, i, j) - def __setslice__(self, i, j, other): - UserList.__setslice__(self, i, j, other) - self.unique = False def __add__(self, other): result = UserList.__add__(self, other) result.unique = False diff --git a/SCons/__init__.py b/SCons/__init__.py index a87bb16..bc0f428 100644 --- a/SCons/__init__.py +++ b/SCons/__init__.py @@ -1,9 +1,9 @@ __version__="4.1.1a" __copyright__="Copyright (c) 2001 - 2021 The SCons Foundation" -__developer__="millsd" -__date__="2021-03-18 01:11:29" -__buildsys__="chn-cad-vnc31" -__revision__="fc3946a217f29407c65291c5358262a7b3cc78cd" -__build__="fc3946a217f29407c65291c5358262a7b3cc78cd" +__developer__="bdbaddog" +__date__="2021-04-18 22:22:37" +__buildsys__="ProDog2020" +__revision__="1850bdd13c7668aac493b9f5b896578813e60ca9" +__build__="1850bdd13c7668aac493b9f5b896578813e60ca9" # make sure compatibility is always in place import SCons.compat # noqa
\ No newline at end of file diff --git a/SCons/cpp.py b/SCons/cpp.py index 65358b3..4c6b437 100644 --- a/SCons/cpp.py +++ b/SCons/cpp.py @@ -23,18 +23,14 @@ """SCons C Pre-Processor module""" -import SCons.compat - import os import re -# # First "subsystem" of regular expressions that we set up: # # Stuff to turn the C preprocessor directives in a file's contents into # a list of tuples that we can process easily. # - # A table of regular expressions that fetch the arguments from the rest of # a C preprocessor line. Different directives have different arguments # that we want to fetch, using the regular expressions to which the lists diff --git a/doc/generated/builders.gen b/doc/generated/builders.gen index e2b98fe..d3490f0 100644 --- a/doc/generated/builders.gen +++ b/doc/generated/builders.gen @@ -172,8 +172,8 @@ env.DocbookHtml('manual') <term><function>DocbookHtmlChunked</function>()</term> <term><replaceable>env</replaceable>.<methodname>DocbookHtmlChunked</methodname>()</term> <listitem><para> -A pseudo-Builder, providing a Docbook toolchain for chunked HTML output. -It supports the <literal>base.dir</literal> parameter. The +A pseudo-Builder providing a Docbook toolchain for chunked HTML output. +It supports the <parameter>base.dir</parameter> parameter. The <filename>chunkfast.xsl</filename> file (requires "EXSLT") is used as the default stylesheet. Basic syntax: </para> @@ -184,22 +184,23 @@ env.DocbookHtmlChunked('manual') <para> where <filename>manual.xml</filename> is the input file. </para> -<para>If you use the <literal>root.filename</literal> +<para>If you use the <parameter>root.filename</parameter> parameter in your own stylesheets you have to specify the new target name. This ensures that the dependencies get correct, especially for the cleanup via <quote><literal>scons -c</literal></quote>: </para> <screen>env = Environment(tools=['docbook']) env.DocbookHtmlChunked('mymanual.html', 'manual', xsl='htmlchunk.xsl') </screen> -<para>Some basic support for the <literal>base.dir</literal> is provided. You -can add the <literal>base_dir</literal> keyword to your Builder -call, and the given prefix gets prepended to all the created filenames: +<para>Some basic support for the <parameter>base.dir</parameter> parameter +is provided. You can add the <parameter>base_dir</parameter> keyword to +your Builder call, and the given prefix gets prepended to all the +created filenames: </para> <screen>env = Environment(tools=['docbook']) env.DocbookHtmlChunked('manual', xsl='htmlchunk.xsl', base_dir='output/') </screen> <para>Make sure that you don't forget the trailing slash for the base folder, else -your files get renamed only! +your files get renamed only! </para> </listitem> </varlistentry> @@ -218,15 +219,15 @@ env.DocbookHtmlhelp('manual') where <filename>manual.xml</filename> is the input file. </para> -<para>If you use the <literal>root.filename</literal> +<para>If you use the <parameter>root.filename</parameter> parameter in your own stylesheets you have to specify the new target name. -This ensures that the dependencies get correct, especially for the cleanup via <quote><literal>scons -c</literal></quote>: +This ensures that the dependencies get correct, especially for the cleanup via <quote><userinput>scons -c</userinput></quote>: </para> <screen>env = Environment(tools=['docbook']) env.DocbookHtmlhelp('mymanual.html', 'manual', xsl='htmlhelp.xsl') </screen> -<para>Some basic support for the <literal>base.dir</literal> parameter -is provided. You can add the <literal>base_dir</literal> keyword to +<para>Some basic support for the <parameter>base.dir</parameter> parameter +is provided. You can add the <parameter>base_dir</parameter> keyword to your Builder call, and the given prefix gets prepended to all the created filenames: </para> @@ -234,7 +235,7 @@ created filenames: env.DocbookHtmlhelp('manual', xsl='htmlhelp.xsl', base_dir='output/') </screen> <para>Make sure that you don't forget the trailing slash for the base folder, else -your files get renamed only! +your files get renamed only! </para> </listitem> @@ -251,7 +252,7 @@ Its basic syntax is: env.DocbookMan('manual') </example_commands> <para> -where <filename>manual.xml</filename> is the input file. Note, that +where <filename>manual.xml</filename> is the input file. Note, that you can specify a target name, but the actual output names are automatically set from the <literal>refname</literal> entries in your XML source. </para> @@ -289,25 +290,25 @@ A pseudo-Builder, providing a Docbook toolchain for HTML slides output. env.DocbookSlidesHtml('manual') </example_commands> -<para>If you use the <literal>titlefoil.html</literal> parameter in +<para>If you use the <parameter>titlefoil.html</parameter> parameter in your own stylesheets you have to give the new target name. This ensures -that the dependencies get correct, especially for the cleanup via -<quote><literal>scons -c</literal></quote>: +that the dependencies get correct, especially for the cleanup via +<quote><userinput>scons -c</userinput></quote>: </para> <screen>env = Environment(tools=['docbook']) env.DocbookSlidesHtml('mymanual.html','manual', xsl='slideshtml.xsl') </screen> -<para>Some basic support for the <literal>base.dir</literal> parameter +<para>Some basic support for the <parameter>base.dir</parameter> parameter is provided. You -can add the <literal>base_dir</literal> keyword to your Builder +can add the <parameter>base_dir</parameter> keyword to your Builder call, and the given prefix gets prepended to all the created filenames: </para> <screen>env = Environment(tools=['docbook']) env.DocbookSlidesHtml('manual', xsl='slideshtml.xsl', base_dir='output/') </screen> <para>Make sure that you don't forget the trailing slash for the base folder, else -your files get renamed only! +your files get renamed only! </para> </listitem> @@ -355,7 +356,7 @@ A pseudo-Builder, applying a given XSL transformation to the input file. env.DocbookXslt('manual_transformed.xml', 'manual.xml', xsl='transform.xslt') </example_commands> -<para>Note, that this builder requires the <literal>xsl</literal> parameter +<para>Note, that this builder requires the <parameter>xsl</parameter> parameter to be set. </para> </listitem> @@ -418,15 +419,18 @@ env.DVI(target = 'ccc.dvi', source = 'ccc.latex') <term><function>Gs</function>()</term> <term><replaceable>env</replaceable>.<methodname>Gs</methodname>()</term> <listitem><para> -A Builder for explicitly calling the <literal>gs</literal> executable. -Depending on the underlying OS, the different names <literal>gs</literal>, -<literal>gsos2</literal> and <literal>gswin32c</literal> +A Builder for explicitly calling the <application>gs</application> executable. +Depending on the underlying OS, the different names <application>gs</application>, +<application>gsos2</application> and <application>gswin32c</application> are tried. </para> -<example_commands>env = Environment(tools=['gs']) -env.Gs('cover.jpg','scons-scons.pdf', - GSFLAGS='-dNOPAUSE -dBATCH -sDEVICE=jpeg -dFirstPage=1 -dLastPage=1 -q') - ) +<example_commands> +env = Environment(tools=['gs']) +env.Gs( + 'cover.jpg', + 'scons-scons.pdf', + GSFLAGS='-dNOPAUSE -dBATCH -sDEVICE=jpeg -dFirstPage=1 -dLastPage=1 -q', +) </example_commands> </listitem> </varlistentry> @@ -1285,7 +1289,7 @@ builder method. <term><replaceable>env</replaceable>.<methodname>Package</methodname>()</term> <listitem><para> Builds software distribution packages. -A <firstterm>Package</firstterm> is a container format which +A <firstterm>package</firstterm> is a container format which includes files to install along with metadata. Packaging is optional, and must be enabled by specifying the &t-link-packaging; tool. For example: diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 27c8771..a5593d3 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,8 +1,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 f4.o -c f4.c -cc -o f5.o -c f5.c -cc -o f3.o -c f3.c cc -o f2.o -c f2.c cc -o f1.o -c f1.c +cc -o f3.o -c f3.c +cc -o f4.o -c f4.c +cc -o f5.o -c f5.c cc -o prog f1.o f2.o f3.o f4.o f5.o </screen> diff --git a/doc/generated/examples/commandline_ListVariable_1.xml b/doc/generated/examples/commandline_ListVariable_1.xml index 1e68e02..8e023d1 100644 --- a/doc/generated/examples/commandline_ListVariable_1.xml +++ b/doc/generated/examples/commandline_ListVariable_1.xml @@ -1,5 +1,5 @@ <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 COLORS=red,blue foo.o</userinput> -cc -o foo.o -c -DCOLORS="red blue" foo.c +cc -o foo.o -c -DCOLORS="red -Dblue" foo.c % <userinput>scons -Q COLORS=blue,green,red foo.o</userinput> -cc -o foo.o -c -DCOLORS="blue green red" foo.c +cc -o foo.o -c -DCOLORS="blue -Dgreen -Dred" foo.c </screen> diff --git a/doc/generated/examples/commandline_ListVariable_2.xml b/doc/generated/examples/commandline_ListVariable_2.xml index c31d16b..87dd3c6 100644 --- a/doc/generated/examples/commandline_ListVariable_2.xml +++ b/doc/generated/examples/commandline_ListVariable_2.xml @@ -1,5 +1,5 @@ <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 COLORS=all foo.o</userinput> -cc -o foo.o -c -DCOLORS="red green blue" foo.c +cc -o foo.o -c -DCOLORS="red -Dgreen -Dblue" foo.c % <userinput>scons -Q COLORS=none foo.o</userinput> cc -o foo.o -c -DCOLORS="" foo.c </screen> diff --git a/doc/generated/examples/troubleshoot_Dump_1.xml b/doc/generated/examples/troubleshoot_Dump_1.xml index 0b7bd05..8f4e624 100644 --- a/doc/generated/examples/troubleshoot_Dump_1.xml +++ b/doc/generated/examples/troubleshoot_Dump_1.xml @@ -58,6 +58,7 @@ scons: Reading SConscript files ... 'TARGET_ARCH': None, 'TARGET_OS': None, 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, + 'TEMPFILEARGESCFUNC': <function quote_spaces at 0x700000>, 'TEMPFILEARGJOIN': ' ', 'TEMPFILEPREFIX': '@', 'TOOLS': ['install', 'install'], diff --git a/doc/generated/examples/troubleshoot_Dump_2.xml b/doc/generated/examples/troubleshoot_Dump_2.xml index 4272d0a..f2fc5e6 100644 --- a/doc/generated/examples/troubleshoot_Dump_2.xml +++ b/doc/generated/examples/troubleshoot_Dump_2.xml @@ -101,6 +101,7 @@ scons: Reading SConscript files ... 'TARGET_ARCH': None, 'TARGET_OS': None, 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, + 'TEMPFILEARGESCFUNC': <function quote_spaces at 0x700000>, 'TEMPFILEARGJOIN': '\n', 'TEMPFILEPREFIX': '@', 'TOOLS': ['msvc', 'install', 'install'], diff --git a/doc/generated/examples/troubleshoot_explain1_3.xml b/doc/generated/examples/troubleshoot_explain1_3.xml index 85556b1..6b90e1c 100644 --- a/doc/generated/examples/troubleshoot_explain1_3.xml +++ b/doc/generated/examples/troubleshoot_explain1_3.xml @@ -2,5 +2,5 @@ cp file.in file.oout scons: warning: Cannot find target file.out after building -File "/Users/bdbaddog/devel/scons/git/scons-bugfixes-3/scripts/scons.py", line 96, in <module> +File "/Users/bdbaddog/devel/scons/git/as_scons/scripts/scons.py", line 96, in <module> </screen> diff --git a/doc/generated/examples/troubleshoot_stacktrace_2.xml b/doc/generated/examples/troubleshoot_stacktrace_2.xml index 41e53c5..8e8809c 100644 --- a/doc/generated/examples/troubleshoot_stacktrace_2.xml +++ b/doc/generated/examples/troubleshoot_stacktrace_2.xml @@ -3,7 +3,7 @@ scons: *** [prog.o] Source `prog.c' not found, needed by target `prog.o'. scons: internal stack trace: File "SCons/Job.py", line 195, in start task.prepare() - File "SCons/Script/Main.py", line 177, in prepare + File "SCons/Script/Main.py", line 179, in prepare return SCons.Taskmaster.OutOfDateTask.prepare(self) File "SCons/Taskmaster.py", line 186, in prepare executor.prepare() diff --git a/doc/generated/functions.gen b/doc/generated/functions.gen index c9ffc86..d1e730a 100644 --- a/doc/generated/functions.gen +++ b/doc/generated/functions.gen @@ -507,58 +507,6 @@ Preprocessor macros can be valued, or un-valued, as in The macro can be be supplied as a complete string including the value, or as a tuple (or list) of macro, value, or as a dictionary. Example (again gcc syntax in the expanded defines): -</para> - -<example_commands> -env = Environment(CPPDEFINES="FOO") -print("CPPDEFINES={}".format(env['CPPDEFINES'])) -env.Append(CPPDEFINES="BAR=1") -print("CPPDEFINES={}".format(env['CPPDEFINES'])) -env.Append(CPPDEFINES=("OTHER", 2)) -print("CPPDEFINES={}".format(env['CPPDEFINES'])) -env.Append(CPPDEFINES={"EXTRA": "arg"}) -print("CPPDEFINES={}".format(env['CPPDEFINES'])) -print("CPPDEFINES will expand to {}".format(env.subst("$_CPPDEFFLAGS"))) -</example_commands> - -<screen> -$ scons -Q -CPPDEFINES=FOO -CPPDEFINES=['FOO', 'BAR=1'] -CPPDEFINES=['FOO', 'BAR=1', ('OTHER', 2)] -CPPDEFINES=['FOO', 'BAR=1', ('OTHER', 2), {'EXTRA': 'arg'}] -CPPDEFINES will expand to -DFOO -DBAR=1 -DOTHER=2 -DEXTRA=arg -scons: `.' is up to date. -</screen> - -<para> -Adding a string <parameter>val</parameter> -to a dictonary &consvar; will enter -<parameter>val</parameter> as the key in the dict, -and <literal>None</literal> as its value. -Using a tuple type to supply a key + value only works -for the special case of &cv-link-CPPDEFINES; -described above. -</para> - -<para> -Although most combinations of types work without -needing to know the details, some combinations -do not make sense and a Python exception will be raised. -</para> - -<para> -When using &f-env-Append; to modify &consvars; -which are path specifications (normally, -those names which end in <varname>PATH</varname>), -it is recommended to add the values as a list of strings, -even if there is only a single string to add. -The same goes for adding library names to &cv-LIBS;. -</para> - -<example_commands> -env.Append(CPPPATH=["#/include"]) -</example_commands> <para> See also &f-link-env-AppendUnique;, @@ -672,8 +620,8 @@ until after the Builder object is actually called. </listitem> </varlistentry> <varlistentry id="f-CacheDir"> - <term><function>CacheDir</function>(<parameter>cache_dir</parameter>)</term> - <term><replaceable>env</replaceable>.<methodname>CacheDir</methodname>(<parameter>cache_dir</parameter>)</term> + <term><function>CacheDir</function>(<parameter>cache_dir, custom_class=None</parameter>)</term> + <term><replaceable>env</replaceable>.<methodname>CacheDir</methodname>(<parameter>cache_dir, custom_class=None</parameter>)</term> <listitem><para> Direct &scons; @@ -690,6 +638,15 @@ disables derived file caching. </para> <para> +When specifying a +<parameter>custom_class</parameter> which should be a class type which is a subclass of +<classname>SCons.CacheDir.CacheDir</classname>, SCons will +internally invoke this class to use for performing caching operations. +This argument is optional and if left to default <constant>None</constant>, will use the +default <classname>SCons.CacheDir.CacheDir</classname> class. +</para> + +<para> Calling the environment method &f-link-env-CacheDir; limits the effect to targets built @@ -1247,32 +1204,46 @@ env.Decider(my_decider) </listitem> </varlistentry> <varlistentry id="f-Default"> - <term><function>Default</function>(<parameter>targets...</parameter>)</term> - <term><replaceable>env</replaceable>.<methodname>Default</methodname>(<parameter>targets...</parameter>)</term> + <term><function>Default</function>(<parameter>target[, ...]</parameter>)</term> + <term><replaceable>env</replaceable>.<methodname>Default</methodname>(<parameter>target[, ...]</parameter>)</term> <listitem><para> -This specifies a list of default targets, -which will be built by -&scons; -if no explicit targets are given on the command line. -Multiple calls to +Specify default targets to the &SCons; target selection mechanism. +Any call to &f-Default; will cause &SCons; to use the +defined default target list instead of +its built-in algorithm for determining default targets +(see the manpage section "Target Selection"). +</para> + +<para> +<parameter>target</parameter> may be one or more strings, +a list of strings, +a <classname>NodeList</classname> as returned by a Builder, +or <constant>None</constant>. +A string <parameter>target</parameter> may be the name of +a file or directory, or a target previously defined by a call to +&f-link-Alias; (defining the alias later will still create +the alias, but it will not be recognized as a default). +Calls to &f-Default; are additive. +A <parameter>target</parameter> of +<literal>None</literal> +will clear any existing default target list; +subsequent calls to &f-Default; -are legal, -and add to the list of default targets. -As noted above, both forms of this call affect the +will add to the (now empty) default target list +like normal. +</para> + +<para> +Both forms of this call affect the same global list of default targets; the construction environment method applies construction variable expansion to the targets. </para> <para> -Multiple targets should be specified as -separate arguments to the -&f-Default; -method, or as a list. -&f-Default; -will also accept the Node returned by any -of a construction environment's -builder methods. +The current list of targets added using +&f-Default; is available in the +&DEFAULT_TARGETS; list (see below). </para> <para> @@ -1286,26 +1257,6 @@ hello = env.Program('hello', 'hello.c') env.Default(hello) </example_commands> -<para> -An argument to -&f-Default; -of -<literal>None</literal> -will clear all default targets. -Later calls to -&f-Default; -will add to the (now empty) default-target list -like normal. -</para> - -<para> -The current list of targets added using the -&f-Default; -function or method is available in the -<literal>DEFAULT_TARGETS</literal> -list; -see below. -</para> </listitem> </varlistentry> <varlistentry id="f-DefaultEnvironment"> @@ -3907,11 +3858,24 @@ The settable variables with their associated command-line options are: </entry><entry> <option>--diskcheck</option> </entry></row> -<row><entry> + + <row><entry> <varname>duplicate</varname> </entry><entry> <option>--duplicate</option> </entry></row> + + + <row> + <entry> + <varname>experimental</varname> + </entry> + <entry> + <option>--experimental</option> + </entry> + </row> + + <row><entry> <varname>help</varname> </entry><entry> diff --git a/doc/generated/tools.gen b/doc/generated/tools.gen index 44118c2..bdb353c 100644 --- a/doc/generated/tools.gen +++ b/doc/generated/tools.gen @@ -144,67 +144,79 @@ 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; +examined by inspecting the &cv-link-TOOLS; &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. +On all platforms, the tools from the following list +are selected if their respective conditions are met: +<!--TODO: &t-link-filesystem; --> filesystem;, +<!--TODO &t-link-wix; --> wix, +&t-link-lex;, &t-link-yacc;, +&t-link-rpcgen;, &t-link-swig;, +&t-link-jar;, &t-link-javac;, &t-link-javah;, &t-link-rmic;, +&t-link-dvipdf;, &t-link-dvips;, &t-link-gs;, +&t-link-tex;, &t-link-latex;, &t-link-pdflatex;, &t-link-pdftex;, +&t-link-tar;, &t-link-zip;, &t-link-textfile;. </para> <para> On Linux systems, the default tools list selects (first-found): a C compiler from -gcc, intelc, icc, cc; +&t-link-gcc;, &t-link-intelc;, &t-link-icc;, &t-link-cc;; a C++ compiler from -g++, intelc, icc, cxx; +&t-link-gXX;, &t-link-intelc;, &t-link-icc;, &t-link-cXX;; an assembler from -gas, nasm, masm; +&t-link-gas;, &t-link-nasm;, &t-link-masm;; a linker from -gnulink, ilink; +&t-link-gnulink;, &t-link-ilink;; a Fortran compiler from -gfortran, g77, ifort, ifl, f95, f90, f77; -and a static archiver 'ar'. +&t-link-gfortran;, &t-link-g77;, &t-link-ifort;, &t-link-ifl;, +&t-link-f95;, &t-link-f90;, &t-link-f77;; +and a static archiver &t-link-ar;. It also selects all found from the list -m4, rpm. +&t-link-m4; +<!-- TODO &t-link-rpm; --> 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; +&t-link-msvc;, &t-link-mingw;, &t-link-gcc;, &t-link-intelc;, +&t-link-icl;, &t-link-icc;, &t-link-cc;, &t-link-bcc32;; a C++ compiler from -msvc, intelc, icc, g++, cxx, bcc32; +&t-link-msvc;, &t-link-intelc;, &t-link-icc;, &t-link-gXX;, +&t-link-cXX;, &t-link-bcc32;; an assembler from -masm, nasm, gas, 386asm; +&t-link-masm;, &t-link-nasm;, &t-link-gas;, &t-link-386asm;; a linker from -mslink, gnulink, ilink, linkloc, ilink32; +&t-link-mslink;, &t-link-gnulink;, &t-link-ilink;, +&t-link-linkloc;, &t-link-ilink32;; a Fortran compiler from -gfortran, g77, ifl, cvf, f95, f90, fortran; +&t-link-gfortran;, &t-link-g77;, &t-link-ifl;, &t-link-cvf;, +&t-link-f95;, &t-link-f90;, &t-link-fortran;; and a static archiver from -mslib, ar, tlib; +&t-link-mslib;, &t-link-ar;, &t-link-tlib;; It also selects all found from the list -msvs, midl. +&t-link-msvs;, &t-link-midl;. </para> <para> On MacOS systems, the default tools list selects (first-found): a C compiler from -gcc, cc; +&t-link-gcc;, &t-link-cc;; a C++ compiler from -g++, cxx; -an assembler 'as'; +&t-link-gXX;, &t-link-cXX;; +an assembler &t-link-as;; a linker from -applelink, gnulink; +&t-link-applelink;, &t-link-gnulink;; a Fortran compiler from -gfortran, f95, f90, g77; -and a static archiver ar. +&t-link-gfortran;, &t-link-f95;, &t-link-f90;, &t-link-g77;; +and a static archiver &t-link-ar;. It also selects all found from the list -m4, rpm. +&t-link-m4;, +<!-- TODO &t-link-rpm; --> rpm. </para> <para> @@ -240,29 +252,29 @@ stylesheet <filename>utils/xmldepend.xsl</filename> by Paul DuBois is used for t <para>Note, that there is no support for XML catalog resolving offered! This tool calls the XSLT processors and PDF renderers with the stylesheets you specified, that's it. The rest lies in your hands and you still have to know what you're doing when -resolving names via a catalog. +resolving names via a catalog. </para> <para>For activating the tool "docbook", you have to add its name to the Environment constructor, like this </para> <screen>env = Environment(tools=['docbook']) </screen> -<para>On its startup, the Docbook tool tries to find a required <literal>xsltproc</literal> processor, and -a PDF renderer, e.g. <literal>fop</literal>. So make sure that these are added to your system's environment -<literal>PATH</literal> and can be called directly, without specifying their full path. +<para>On its startup, the &t-docbook; tool tries to find a required <literal>xsltproc</literal> processor, and +a PDF renderer, e.g. <application>fop</application>. So make sure that these are added to your system's environment +<envar>PATH</envar> and can be called directly without specifying their full path. </para> <para>For the most basic processing of Docbook to HTML, you need to have installed </para> -<itemizedlist><listitem><para>the Python <literal>lxml</literal> binding to <literal>libxml2</literal>, or -</para> +<itemizedlist><listitem><para>the Python <systemitem>lxml</systemitem> +binding to <systemitem>libxml2</systemitem>, or</para> </listitem> -<listitem><para>a standalone XSLT processor, currently detected are <literal>xsltproc</literal>, <literal>saxon</literal>, <literal>saxon-xslt</literal> -and <literal>xalan</literal>. +<listitem><para>a standalone XSLT processor, currently detected are <application>xsltproc</application>, <application>saxon</application>, <application>saxon-xslt</application> +and <application>xalan</application>. </para> </listitem> </itemizedlist> <para>Rendering to PDF requires you to have one of the applications -<literal>fop</literal> or <literal>xep</literal> installed. +<application>fop</application> or <application>xep</application> installed. </para> <para>Creating a HTML or PDF document is very simple and straightforward. Say @@ -293,14 +305,14 @@ Tool uses the given names as file stems, and adds the suffixes for target and so accordingly. </para> </important> -<para>The rules given above are valid for the Builders &b-link-DocbookHtml;, -&b-link-DocbookPdf;, &b-link-DocbookEpub;, &b-link-DocbookSlidesPdf; and &b-link-DocbookXInclude;. For the +<para>The rules given above are valid for the Builders &b-link-DocbookHtml;, +&b-link-DocbookPdf;, &b-link-DocbookEpub;, &b-link-DocbookSlidesPdf; and &b-link-DocbookXInclude;. For the &b-link-DocbookMan; transformation you can specify a target name, but the actual output names are automatically set from the <literal>refname</literal> entries in your XML source. </para> -<para>The Builders &b-link-DocbookHtmlChunked;, &b-link-DocbookHtmlhelp; and +<para>The Builders &b-link-DocbookHtmlChunked;, &b-link-DocbookHtmlhelp; and &b-link-DocbookSlidesHtml; are special, in that: </para> <orderedlist><listitem><para>they create a large set of files, where the exact names and their number depend @@ -312,7 +324,7 @@ XSL transformation is not picked up by the stylesheets. </para> </listitem> </orderedlist> -<para>As a result, there is simply no use in specifying a target HTML name. +<para>As a result, there is simply no use in specifying a target HTML name. So the basic syntax for these builders is always: </para> <screen>env = Environment(tools=['docbook']) @@ -320,7 +332,7 @@ env.DocbookHtmlhelp('manual') </screen> <para>If you want to use a specific XSL file, you can set the -additional <literal>xsl</literal> parameter to your +additional <parameter>xsl</parameter> parameter to your Builder call as follows: </para> <screen>env.DocbookHtml('other.html', 'manual.xml', xsl='html.xsl') @@ -329,28 +341,31 @@ Builder call as follows: e.g. <filename>html.xsl</filename> for HTML and <filename>pdf.xsl</filename> for PDF output, a set of variables for setting the default XSL name is provided. These are: </para> -<screen>DOCBOOK_DEFAULT_XSL_HTML -DOCBOOK_DEFAULT_XSL_HTMLCHUNKED -DOCBOOK_DEFAULT_XSL_HTMLHELP -DOCBOOK_DEFAULT_XSL_PDF -DOCBOOK_DEFAULT_XSL_EPUB -DOCBOOK_DEFAULT_XSL_MAN -DOCBOOK_DEFAULT_XSL_SLIDESPDF -DOCBOOK_DEFAULT_XSL_SLIDESHTML +<screen>DOCBOOK_DEFAULT_XSL_HTML +DOCBOOK_DEFAULT_XSL_HTMLCHUNKED +DOCBOOK_DEFAULT_XSL_HTMLHELP +DOCBOOK_DEFAULT_XSL_PDF +DOCBOOK_DEFAULT_XSL_EPUB +DOCBOOK_DEFAULT_XSL_MAN +DOCBOOK_DEFAULT_XSL_SLIDESPDF +DOCBOOK_DEFAULT_XSL_SLIDESHTML </screen> <para>and you can set them when constructing your environment: </para> -<screen>env = Environment(tools=['docbook'], - DOCBOOK_DEFAULT_XSL_HTML='html.xsl', - DOCBOOK_DEFAULT_XSL_PDF='pdf.xsl') -env.DocbookHtml('manual') # now uses html.xsl +<screen> +env = Environment( + tools=['docbook'], + DOCBOOK_DEFAULT_XSL_HTML='html.xsl', + DOCBOOK_DEFAULT_XSL_PDF='pdf.xsl', +) +env.DocbookHtml('manual') # now uses html.xsl </screen> <para>Sets: &cv-link-DOCBOOK_DEFAULT_XSL_EPUB;, &cv-link-DOCBOOK_DEFAULT_XSL_HTML;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLCHUNKED;, &cv-link-DOCBOOK_DEFAULT_XSL_HTMLHELP;, &cv-link-DOCBOOK_DEFAULT_XSL_MAN;, &cv-link-DOCBOOK_DEFAULT_XSL_PDF;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESHTML;, &cv-link-DOCBOOK_DEFAULT_XSL_SLIDESPDF;, &cv-link-DOCBOOK_FOP;, &cv-link-DOCBOOK_FOPCOM;, &cv-link-DOCBOOK_FOPFLAGS;, &cv-link-DOCBOOK_XMLLINT;, &cv-link-DOCBOOK_XMLLINTCOM;, &cv-link-DOCBOOK_XMLLINTFLAGS;, &cv-link-DOCBOOK_XSLTPROC;, &cv-link-DOCBOOK_XSLTPROCCOM;, &cv-link-DOCBOOK_XSLTPROCFLAGS;, &cv-link-DOCBOOK_XSLTPROCPARAMS;.</para><para>Uses: &cv-link-DOCBOOK_FOPCOMSTR;, &cv-link-DOCBOOK_XMLLINTCOMSTR;, &cv-link-DOCBOOK_XSLTPROCCOMSTR;.</para></listitem> </varlistentry> <varlistentry id="t-dvi"> <term>dvi</term> <listitem><para> -Attaches the &b-DVI; builder to the +Attaches the &b-link-DVI; builder to the construction environment. </para> </listitem> @@ -431,7 +446,7 @@ to set variables. <term>gas</term> <listitem><para> Sets construction variables for the &gas; assembler. -Calls the &t-as; module. +Calls the &t-link-as; tool. </para> <para>Sets: &cv-link-AS;.</para></listitem> </varlistentry> @@ -485,8 +500,8 @@ so you're encouraged to see their individual documentation. <para> Each of the above tools provides its own builder(s) which may be used to perform particular activities related to software internationalization. You -may be however interested in <emphasis>top-level</emphasis> builder -&b-Translate; described few paragraphs later. +may be however interested in <emphasis>top-level</emphasis> +&b-link-Translate; builder. </para> <para> @@ -516,11 +531,11 @@ Set construction variables for GNU linker/loader. <term>gs</term> <listitem><para> This Tool sets the required construction variables for working with -the Ghostscript command. It also registers an appropriate Action -with the PDF Builder (&b-link-PDF;), such that the conversion from +the Ghostscript software. It also registers an appropriate Action +with the &b-link-PDF; Builder, such that the conversion from PS/EPS to PDF happens automatically for the TeX/LaTeX toolchain. -Finally, it adds an explicit Ghostscript Builder (&b-link-Gs;) to the -environment. +Finally, it adds an explicit &b-link-Gs; Builder for Ghostscript +to the environment. </para> <para>Sets: &cv-link-GS;, &cv-link-GSCOM;, &cv-link-GSFLAGS;.</para><para>Uses: &cv-link-GSCOMSTR;.</para></listitem> </varlistentry> @@ -534,9 +549,9 @@ Set construction variables for the compilers aCC on HP/UX systems. <varlistentry id="t-hpcc"> <term>hpcc</term> <listitem><para> -Set construction variables for the -<application>aCC</application> on HP/UX systems. -Calls the &t-cXX; tool for additional variables. +Set construction variables for +<application>aCC</application> compilers on HP/UX systems. +Calls the &t-link-cXX; tool for additional variables. </para> <para>Sets: &cv-link-CXX;, &cv-link-CXXVERSION;, &cv-link-SHCXXFLAGS;.</para></listitem> </varlistentry> @@ -607,9 +622,9 @@ and directory installation. <listitem><para> Sets construction variables for the Intel C/C++ compiler (Linux and Windows, version 7 and later). -Calls the &t-gcc; or &t-msvc; +Calls the &t-link-gcc; or &t-link-msvc; (on Linux and Windows, respectively) -to set underlying variables. +tool to set underlying variables. </para> <para>Sets: &cv-link-AR;, &cv-link-CC;, &cv-link-CXX;, &cv-link-INTEL_C_COMPILER_VERSION;, &cv-link-LINK;.</para></listitem> </varlistentry> diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index 5b1edbe..bdc7adc 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -379,6 +379,17 @@ env['BUILDERS']['NewBuilder'] = bld </example_commands> </listitem> </varlistentry> + <varlistentry id="cv-CACHEDIR_CLASS"> + <term> + <envar>CACHEDIR_CLASS</envar> + </term> + <listitem><para> +The class type that SCons should use when instantiating a +new &f-link-CacheDir; for the given environment. It must be +a subclass of the SCons.CacheDir.CacheDir class. + </para> + </listitem> + </varlistentry> <varlistentry id="cv-CC"> <term> <envar>CC</envar> @@ -585,7 +596,7 @@ section of the RPM <envar>COMPILATIONDB_COMSTR</envar> </term> <listitem><para> - The string displayed when the &b-CompilationDatabase; + The string displayed when the &b-link-CompilationDatabase; builder's action is run. </para> </listitem> @@ -626,7 +637,7 @@ section of the RPM <envar>_concat</envar> </term> <listitem><para> -A function used to produce variables like &cv-_CPPINCFLAGS;. It takes +A function used to produce variables like &cv-link-_CPPINCFLAGS;. It takes four or five arguments: a prefix to concatenate onto each element, a list of elements, a suffix to concatenate onto each element, an environment @@ -660,7 +671,7 @@ file. <envar>CONFIGURELOG</envar> </term> <listitem><para> -The name of the Configure context log file. +The name of the &Configure; context log file. The default is <filename>config.log</filename> in the top-level directory @@ -678,7 +689,7 @@ file. An automatically-generated &consvar; containing the C preprocessor command-line options to define values. -The value of &cv-_CPPDEFFLAGS; is created +The value of &cv-link-_CPPDEFFLAGS; is created by respectively prepending and appending &cv-link-CPPDEFPREFIX; and &cv-link-CPPDEFSUFFIX; to each definition in &cv-link-CPPDEFINES;. @@ -703,7 +714,7 @@ If &cv-CPPDEFINES; is a string, the values of the &cv-link-CPPDEFPREFIX; and &cv-link-CPPDEFSUFFIX; &consvars; will be respectively prepended and appended to -each definition in &cv-CPPDEFINES;. +each definition in &cv-link-CPPDEFINES;. </para> <example_commands> @@ -715,7 +726,7 @@ env = Environment(CPPDEFINES='xyz') <para> If &cv-CPPDEFINES; is a list, the values of the -&cv-link-CPPDEFPREFIX; and &cv-link-CPPDEFSUFFIX; &consvars; +&cv-CPPDEFPREFIX; and &cv-CPPDEFSUFFIX; &consvars; will be respectively prepended and appended to each element in the list. If any element is a list or tuple, @@ -732,7 +743,7 @@ env = Environment(CPPDEFINES=[('B', 2), 'A']) <para> If &cv-CPPDEFINES; is a dictionary, the values of the -&cv-link-CPPDEFPREFIX; and &cv-link-CPPDEFSUFFIX; &consvars; +&cv-CPPDEFPREFIX; and &cv-CPPDEFSUFFIX; &consvars; will be respectively prepended and appended to each item from the dictionary. The key of each dictionary item @@ -846,7 +857,7 @@ Python's <systemitem>os.sep</systemitem>. <para> Note: -directory names in &cv-link-CPPPATH; +directory names in &cv-CPPPATH; will be looked-up relative to the directory of the SConscript file when they are used in a command. To force &scons; @@ -1473,7 +1484,7 @@ no lxml Python binding can be imported in the current system. </term> <listitem><para> The full command-line for the external executable -<literal>xsltproc</literal> (or <literal>saxon</literal>, +<literal>xsltproc</literal> (or <literal>saxon</literal>, <literal>xalan</literal>). </para> </listitem> @@ -1494,7 +1505,7 @@ an XML file via a given XSLT stylesheet. </term> <listitem><para> Additonal command-line flags for the external executable -<literal>xsltproc</literal> (or <literal>saxon</literal>, +<literal>xsltproc</literal> (or <literal>saxon</literal>, <literal>xalan</literal>). </para> </listitem> @@ -3046,7 +3057,7 @@ env.AppendUnique(FRAMEWORKS=Split('System Cocoa SystemConfiguration')) <envar>GS</envar> </term> <listitem><para> -The Ghostscript program used, e.g. to convert PostScript to PDF files. +The Ghostscript program used to, for example, convert PostScript to PDF files. </para> </listitem> </varlistentry> @@ -3367,7 +3378,7 @@ Install file: "$SOURCE" as "$TARGET" <envar>INTEL_C_COMPILER_VERSION</envar> </term> <listitem><para> -Set by the "intelc" Tool +Set by the &t-link-intelc; Tool to the major version number of the Intel C compiler selected for use. </para> @@ -4271,6 +4282,16 @@ default file named The linker. See also &cv-link-SHLINK; for linking shared objects. </para> +<para> +On POSIX systems (those using the &t-link-link; tool), +you should normally not change this value as it defaults +to a "smart" linker tool which selects a compiler +driver matching the type of source files in use. +So for example, if you set &cv-link-CXX; to a specific +compiler name, and are compiling C++ sources, +the smartlink function will automatically select the same compiler +for linking. +</para> </listitem> </varlistentry> <varlistentry id="cv-LINKCOM"> @@ -7350,6 +7371,16 @@ set. The linker for programs that use shared libraries. See also &cv-link-LINK; for linking static objects. </para> +<para> +On POSIX systems (those using the &t-link-link; tool), +you should normally not change this value as it defaults +to a "smart" linker tool which selects a compiler +driver matching the type of source files in use. +So for example, if you set &cv-link-SHCXX; to a specific +compiler name, and are compiling C++ sources, +the smartlink function will automatically select the same compiler +for linking. +</para> </listitem> </varlistentry> <varlistentry id="cv-SHLINKCOM"> @@ -7944,6 +7975,35 @@ The suffix used for tar file names. </para> </listitem> </varlistentry> + <varlistentry id="cv-TEMPFILEARGESCFUNC"> + <term> + <envar>TEMPFILEARGESCFUNC</envar> + </term> + <listitem><para> +A default argument escape function is ``SCons.Subst.quote_spaces``. +If you need to apply extra operations on a command argument before +writing to a temporary file(fix Windows slashes, normalize paths, etc.), +please set `TEMPFILEARGESCFUNC` variable to a custom function. Example:: +</para> + +<example_commands> +import sys +import re +from SCons.Subst import quote_spaces + +WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)") + +def tempfile_arg_esc_func(arg): + arg = quote_spaces(arg) + if sys.platform != "win32": + return arg + # GCC requires double Windows slashes, let's use UNIX separator + return WINPATHSEP_RE.sub(r"/\1", arg) + +env["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func +</example_commands> +</listitem> + </varlistentry> <varlistentry id="cv-TEMPFILEARGJOIN"> <term> <envar>TEMPFILEARGJOIN</envar> diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index a5fe961..86fc604 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -34,6 +34,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. <!ENTITY cv-BIBTEXCOMSTR "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$BIBTEXCOMSTR</envar>"> <!ENTITY cv-BIBTEXFLAGS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$BIBTEXFLAGS</envar>"> <!ENTITY cv-BUILDERS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$BUILDERS</envar>"> +<!ENTITY cv-CACHEDIR_CLASS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$CACHEDIR_CLASS</envar>"> <!ENTITY cv-CC "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$CC</envar>"> <!ENTITY cv-CCCOM "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$CCCOM</envar>"> <!ENTITY cv-CCCOMSTR "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$CCCOMSTR</envar>"> @@ -561,6 +562,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. <!ENTITY cv-TARGET_OS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TARGET_OS</envar>"> <!ENTITY cv-TARGETS "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TARGETS</envar>"> <!ENTITY cv-TARSUFFIX "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TARSUFFIX</envar>"> +<!ENTITY cv-TEMPFILEARGESCFUNC "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TEMPFILEARGESCFUNC</envar>"> <!ENTITY cv-TEMPFILEARGJOIN "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TEMPFILEARGJOIN</envar>"> <!ENTITY cv-TEMPFILEDIR "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TEMPFILEDIR</envar>"> <!ENTITY cv-TEMPFILEPREFIX "<envar xmlns='http://www.scons.org/dbxsd/v1.0'>$TEMPFILEPREFIX</envar>"> @@ -685,6 +687,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. <!ENTITY cv-link-BIBTEXCOMSTR "<link linkend='cv-BIBTEXCOMSTR' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$BIBTEXCOMSTR</envar></link>"> <!ENTITY cv-link-BIBTEXFLAGS "<link linkend='cv-BIBTEXFLAGS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$BIBTEXFLAGS</envar></link>"> <!ENTITY cv-link-BUILDERS "<link linkend='cv-BUILDERS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$BUILDERS</envar></link>"> +<!ENTITY cv-link-CACHEDIR_CLASS "<link linkend='cv-CACHEDIR_CLASS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$CACHEDIR_CLASS</envar></link>"> <!ENTITY cv-link-CC "<link linkend='cv-CC' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$CC</envar></link>"> <!ENTITY cv-link-CCCOM "<link linkend='cv-CCCOM' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$CCCOM</envar></link>"> <!ENTITY cv-link-CCCOMSTR "<link linkend='cv-CCCOMSTR' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$CCCOMSTR</envar></link>"> @@ -1212,6 +1215,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. <!ENTITY cv-link-TARGET_OS "<link linkend='cv-TARGET_OS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TARGET_OS</envar></link>"> <!ENTITY cv-link-TARGETS "<link linkend='cv-TARGETS' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TARGETS</envar></link>"> <!ENTITY cv-link-TARSUFFIX "<link linkend='cv-TARSUFFIX' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TARSUFFIX</envar></link>"> +<!ENTITY cv-link-TEMPFILEARGESCFUNC "<link linkend='cv-TEMPFILEARGESCFUNC' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TEMPFILEARGESCFUNC</envar></link>"> <!ENTITY cv-link-TEMPFILEARGJOIN "<link linkend='cv-TEMPFILEARGJOIN' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TEMPFILEARGJOIN</envar></link>"> <!ENTITY cv-link-TEMPFILEDIR "<link linkend='cv-TEMPFILEDIR' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TEMPFILEDIR</envar></link>"> <!ENTITY cv-link-TEMPFILEPREFIX "<link linkend='cv-TEMPFILEPREFIX' xmlns='http://www.scons.org/dbxsd/v1.0'><envar>$TEMPFILEPREFIX</envar></link>"> diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 3f7eef9..165d906 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -105,6 +105,7 @@ component pieces must be built or rebuilt and invoking the necessary commands to build them. &SCons; offers many features to improve developer productivity such as parallel builds, caching of build artifacts, +automatic dependency scanning, and a database of information about previous builds so details do not have to be recalculated each run. </para> @@ -123,7 +124,7 @@ build system by writing a script that describes things to build (<firstterm>targets</firstterm>), and, if necessary, the rules to build those files (<firstterm>actions</firstterm>). &SCons; comes with a collection of <firstterm>Builder</firstterm> methods -which apply premade rules for building many common software components +which apply premade actions for building many common software components such as executable programs, object files and libraries, so that for many software projects, only the targets and input files (<firstterm>sources</firstterm>) @@ -131,7 +132,7 @@ need be specified in a call to a builder. &scons; thus can operate at a level of abstraction above that of pure files. For example if you specify a library target named "foo", &scons; keeps track of the actual operating system dependent filename -(for example <filename>libfoo.so</filename> on a GNU/Linux system), +(such as <filename>libfoo.so</filename> on a GNU/Linux system), and how to refer to that library in later construction steps that want to use it, so you don't have to specify that precise information yourself. @@ -146,7 +147,7 @@ looks for a file named &SConstruct; in the current directory and reads the build configuration from that file -(other names are possible, +(other names are allowed, see <xref linkend="sconscript_files"/> for more information). The &SConstruct; file may specify subsidiary @@ -158,7 +159,7 @@ these subsidiary files are named although any name may be used. As a result of this naming convention, the term <firstterm>SConscript files</firstterm> -is often used to refer +is used to refer generically to the complete set of configuration files for a project (including the &SConstruct; file), @@ -292,14 +293,14 @@ integration setups. </para> <para>&scons; -can scan known input files automatically for dependency +can scan known input file types automatically for dependency information (for example, <literal>#include</literal> preprocessor directives in C or C++ files) and will rebuild dependent files appropriately whenever any "included" input file changes. &scons; supports the -ability to define new scanners for unknown input file types.</para> +ability to define new scanners to support additional input file types.</para> <para>&scons; is normally executed in a top-level directory containing an @@ -309,9 +310,7 @@ the command line (including the contents of the <link linkend="v-SCONSFLAGS">&SCONSFLAGS;</link> environment variable, if set) is processed. Command-line options (see <xref linkend="options"/>) are consumed. -Any variable argument assignments -(see <xref linkend="commandline_construction_variables"/>) -are collected, and +Any variable argument assignments are collected, and remaining arguments are taken as targets to build.</para> <para>Values of variables to be passed to the SConscript files @@ -341,6 +340,11 @@ if necessary. Each &ARGLIST; entry is a tuple containing (<replaceable>argname</replaceable>, <replaceable>argvalue</replaceable>). </para> +<para> +See <xref linkend="commandline_construction_variables"/> +for more information. +</para> + <para>&scons; can maintain a cache of target (derived) files that can be shared between multiple builds. When derived-file caching is enabled in an @@ -429,7 +433,7 @@ and are made available in the </listitem> <listitem> <para> -If there are no targets from the previous steps, +If no targets are selected by the previous steps, &scons; selects the current directory for scanning, unless command-line options which affect the target scan are detected @@ -1120,7 +1124,7 @@ the mechanisms in the specified order.</para> </listitem> </varlistentry> - <varlistentry id="opt--experimental"> + <varlistentry id="opt-experimental"> <term> <option>--experimental=<replaceable>all</replaceable></option>, <option>--experimental=<replaceable>none</replaceable></option> @@ -1128,6 +1132,7 @@ the mechanisms in the specified order.</para> <listitem> <para>Enable experimental features and/or tools. <emphasis role="strong">No Support offered for any features or tools enabled by this flag</emphasis></para> <para>The default setting is none.</para> + <para><emphasis>Available since &scons; 4.2.</emphasis></para> </listitem> </varlistentry> @@ -2753,14 +2758,15 @@ Builder methods take two required arguments: and <parameter>source</parameter>. Either can be passed as a scalar or as a list. -The target and source arguments +The <parameter>target</parameter> and +<parameter>source</parameter> arguments can be specified either as positional arguments, in which case <parameter>target</parameter> comes first, or as keyword arguments, using <parameter>target=</parameter> and <parameter>source=</parameter>. -Although both arguments are required, -in one particular case the target argument can actually be omitted -because it can be inferred and &SCons; supplies it (see below). +Although both arguments are nominally required, +if there is a single source and the target can be inferred +the <parameter>target</parameter> argument can be omitted (see below). Builder methods also take a variety of keyword arguments, described below. </para> @@ -2830,7 +2836,8 @@ to a relative or absolute path first. </para> <para> -Target and source pathnames can be absolute, relative, or +<parameter>target</parameter> and <parameter>source</parameter> +can be absolute, relative, or top-relative. Relative pathnames are searched considering the directory of the SConscript file currently being processed as the "current directory". @@ -3098,9 +3105,10 @@ bar_obj_list = env.StaticObject('bar.c', CPPDEFINES='-DBAR') print("The path to bar_obj is:", str(bar_obj_list[0])) </programlisting> -<para>Note again that because the Builder call returns a list, -you have to access the first element in the list -(<literal>(bar_obj_list[0])</literal>) +<para>Note that because the Builder call returns a +<classname>NodeList</classname>, +you have to access the first element in the list, +(<literal>bar_obj_list[0]</literal> in the example) to get at the Node that actually represents the object file.</para> @@ -3162,6 +3170,19 @@ and to use just the filename portion of the targets and source.</para> +<para> +When trying to handle errors that may occur in a builder method, +consider that the corresponding Action is executed at a different +time than the SConscript file statement calling the builder. +It is not useful to wrap a builder call in a +<systemitem>try</systemitem> block, +since success in the builder call is not the same as +the builder itself succeeding. +If necessary, a Builder's Action should be coded to exit with +a useful exception message indicating the problem in the SConscript files - +programmatically recovering from build errors is rarely useful. +</para> + <para>&scons; predefines the following builder methods. Depending on the setup of a particular @@ -5173,21 +5194,27 @@ to a &consenv;. <emphasis>In general</emphasis>, you should only need to add a new Builder object when you want to build a new type of file or other external target. -If you just want to invoke a different compiler or other tool -to build &Program;, &Object;, &Library;, or any other -type of output file for which -&scons; -already has an existing Builder, -it is generally much easier to -use those existing Builders -in a &consenv; -that sets the appropriate &consvars; -(<envar>CC</envar>, <envar>LINK</envar>, etc.).</para> +For output file types &scons; already knows about, +you can usually modify the behavior of premade Builders +such as &b-link-Program;, &b-link-Object; or &b-link-Library; +by changing the &consvars; they use +(&cv-link-CC;, &cv-link-LINK;, etc.). +In this manner you can, for example, change the compiler to use, +which is simpler and less error-prone than writing a new builder. +The documentation for each Builder lists which +&consvars; it uses. +</para> <para>Builder objects are created using the &f-link-Builder; factory function. +Once created, a builder is added to an environment +by entering it in the &cv-link-BUILDERS; dictionary +in that environment (some of the examples +in this section illustrate that). </para> + +<para> The &f-Builder; function accepts the following keyword arguments:</para> @@ -5196,33 +5223,33 @@ function accepts the following keyword arguments:</para> <varlistentry> <term><parameter>action</parameter></term> <listitem> -<para>The command line string used to build the target from the source. +<para>The command used to build the target from the source. <parameter>action</parameter> -can also be: +may be a string representing a template command line to execute, a list of strings representing the command -to be executed and its arguments +to execute with its arguments (suitable for enclosing white space in an argument), a dictionary mapping source file name suffixes to any combination of command line strings (if the builder should accept multiple source file extensions), -a Python function; +a Python function, an Action object -(see the next section); +(see <xref linkend="action_objects"/>) or a list of any of the above.</para> -<para>An action function takes three arguments:</para> - - <simplelist type="vert"> - <member><parameter>source</parameter> - a list of source nodes;.</member> - <member><parameter>target</parameter> - a list of target nodes;.</member> - <member><parameter>env</parameter> - the &consenv;.</member> - </simplelist> +<para>An action function must accept three arguments: +<parameter>source</parameter>, +<parameter>target</parameter> and +<parameter>env</parameter>. +<parameter>source</parameter> is a list of source nodes; +<parameter>target</parameter> is a list of target nodes; +<parameter>env</parameter> is the &consenv; to use for context. +</para> -<para>The -<parameter>action</parameter> -and -<parameter>generator</parameter> +<para> +The <parameter>action</parameter> +and <parameter>generator</parameter> arguments must not both be used for the same Builder.</para> </listitem> </varlistentry> @@ -5231,36 +5258,30 @@ arguments must not both be used for the same Builder.</para> <term><parameter>prefix</parameter></term> <listitem> <para>The prefix to prepend to the target file name. -<parameter>prefix</parameter> may be:</para> - - <itemizedlist> - <listitem><para>a string</para></listitem> - <listitem><para>a callable object - -a function or other callable that takes +<parameter>prefix</parameter> may be +a string, a function (or other callable) that takes two arguments (a &consenv; and a list of sources) -and returns a prefix</para></listitem> - <listitem><para>a dictionary - -specifies a mapping from a specific source suffix (of the first -source specified) to a corresponding target prefix. Both the source -suffix and target prefix specifications may use environment variable -substitution, and the target prefix (the 'value' entries in the -dictionary) may also be a callable object. The default target prefix -may be indicated by a dictionary entry with a key value of <constant>None</constant>.</para> - </listitem> - </itemizedlist> +and returns a prefix string, +or a dictionary specifying a mapping from a specific source suffix +(of the first source specified) +to a corresponding target prefix string. For the dictionary form, both the source +suffix (key) and target prefix (value) specifications may use environment variable +substitution, and the target prefix +may also be a callable object. The default target prefix +may be indicated by a dictionary entry with a key of <constant>None</constant>.</para> <programlisting language="python"> b = Builder("build_it < $SOURCE > $TARGET", - prefix = "file-") + prefix="file-") def gen_prefix(env, sources): return "file-" + env['PLATFORM'] + '-' + b = Builder("build_it < $SOURCE > $TARGET", - prefix = gen_prefix) + prefix=gen_prefix) b = Builder("build_it < $SOURCE > $TARGET", - suffix = { None: "file-", - "$SRC_SFX_A": gen_prefix }) + suffix={None: "file-", "$SRC_SFX_A": gen_prefix}) </programlisting> </listitem> </varlistentry> @@ -5269,26 +5290,26 @@ b = Builder("build_it < $SOURCE > $TARGET", <term><parameter>suffix</parameter></term> <listitem> <para>The suffix to append to the target file name. -This may be specified in the same manner as the prefix above. +Specified in the same manner as for <parameter>prefix</parameter> above. If the suffix is a string, then &scons; -prepends a '.' to the suffix if it's not already there. -The string returned by the callable object (or obtained from the -dictionary) is untouched and you need to manually prepend a '.' -if one is desired.</para> +prepends a <literal>'.'</literal> to the suffix if it's not already there. +The string returned by the callable object or obtained from the +dictionary is untouched and you need to manually prepend a <literal>'.'</literal> +if one is required.</para> <programlisting language="python"> b = Builder("build_it < $SOURCE > $TARGET" - suffix = "-file") + suffix="-file") def gen_suffix(env, sources): return "." + env['PLATFORM'] + "-file" + b = Builder("build_it < $SOURCE > $TARGET", - suffix = gen_suffix) + suffix=gen_suffix) b = Builder("build_it < $SOURCE > $TARGET", - suffix = { None: ".sfx1", - "$SRC_SFX_A": gen_suffix }) + suffix={None: ".sfx1", "$SRC_SFX_A": gen_suffix}) </programlisting> </listitem> </varlistentry> @@ -5296,21 +5317,21 @@ b = Builder("build_it < $SOURCE > $TARGET", <varlistentry> <term><parameter>ensure_suffix</parameter></term> <listitem> -<para>When set to any true value, causes -&scons; -to add the target suffix specified by the -<parameter>suffix</parameter> -keyword to any target strings -that have a different suffix. -(The default behavior is to leave untouched -any target file name that looks like it already has any suffix.)</para> +<para>If set to a true value, +ensures that targets will end in +<parameter>suffix</parameter>. +Thus, the suffix will also be added to any target strings +that have a suffix that is not already <parameter>suffix</parameter>. +The default behavior (also indicated by a false value) +is to leave unchanged +any target string that looks like it already has a suffix.</para> <programlisting language="python"> b1 = Builder("build_it < $SOURCE > $TARGET" suffix = ".out") b2 = Builder("build_it < $SOURCE > $TARGET" suffix = ".out", - ensure_suffix) + ensure_suffix=True) env = Environment() env['BUILDERS']['B1'] = b1 env['BUILDERS']['B2'] = b2 @@ -5328,8 +5349,9 @@ env.B2('bar.txt', 'bar.in') <varlistentry> <term><parameter>src_suffix</parameter></term> <listitem> -<para>The expected source file name suffix. This may be a string or a list -of strings.</para> +<para>The expected source file name suffix. +<parameter>src_suffix</parameter> +may be a string or a list of strings.</para> </listitem> </varlistentry> @@ -5456,13 +5478,15 @@ to emitter functions. is used to select the actual emitter function from an emitter dictionary.)</para> -<para>An emitter function takes three arguments:</para> - - <simplelist type="vert"> - <member><parameter>source</parameter> - a list of source nodes.</member> - <member><parameter>target</parameter> - a list of target nodes.</member> - <member><parameter>env</parameter> - the &consenv;.</member> - </simplelist> +<para>A function passed as <parameter>emitter</parameter> +must accept three arguments: +<parameter>source</parameter>, +<parameter>target</parameter> and +<parameter>env</parameter>. +<parameter>source</parameter> is a list of source nodes, +<parameter>target</parameter> is a list of target nodes, +<parameter>env</parameter> is the &consenv; to use for context. +</para> <para>An emitter must return a tuple containing two lists, the list of targets to be built by this builder, @@ -5512,7 +5536,7 @@ b = Builder("my_build < $TARGET > $SOURCE", <term><parameter>multi</parameter></term> <listitem> <para>Specifies whether this builder is allowed to be called multiple times for -the same target file(s). The default is <constant>0</constant>, +the same target file(s). The default is <constant>False</constant>, which means the builder can not be called multiple times for the same target file(s). Calling a builder multiple times for the same target simply adds additional source @@ -5546,18 +5570,21 @@ an Action object, or anything that can be converted into an Action object (see the next section).</para> -<para>The generator function takes four arguments:</para> - - <simplelist type="vert"> - <member><parameter>source</parameter> - A list of source nodes;.</member> - <member><parameter>target</parameter> - A list of target nodes;.</member> - <member><parameter>env</parameter> - the &consenv;.</member> - <member><parameter>for_signature</parameter> - - A Boolean value that specifies - whether the generator is being called - for generating a build signature - (as opposed to actually executing the command).</member> - </simplelist> +<para>A function passed as <parameter>generator</parameter> +must accept four arguments: +<parameter>source</parameter>, +<parameter>target</parameter>, +<parameter>env</parameter> and +<parameter>for_signature</parameter>. +<parameter>source</parameter> is a list of source nodes, +<parameter>target</parameter> is a list of target nodes, +<parameter>env</parameter> is the &consenv; to use for context, +<parameter>for_signature</parameter> is +a Boolean value that specifies +whether the generator is being called +for generating a build signature +(as opposed to actually executing the command). +</para> <para>Example:</para> @@ -5611,12 +5638,9 @@ called with a list of source files with different extensions, this check can be suppressed by setting <parameter>source_ext_match</parameter> to -<parameter>None</parameter> +<constant>False</constant> or some other non-true value. -When -<parameter>source_ext_match</parameter> -is disable, -&scons; +In this case, &scons; will use the suffix of the first specified source file to select the appropriate action from the <parameter>action</parameter> @@ -5635,7 +5659,7 @@ and <programlisting language="python"> b = Builder(action={'.in' : 'build $SOURCES > $TARGET'}, - source_ext_match = None) + source_ext_match=False) env = Environment(BUILDERS={'MyBuild':b}) env.MyBuild('foo.out', ['foo.in', 'foo.extra']) @@ -5763,7 +5787,7 @@ and emitter functions.</para> <para>The &f-link-Builder; -function will turn its +factory function will turn its <parameter>action</parameter> keyword argument into an appropriate internal Action object, as will @@ -5785,25 +5809,25 @@ you need to create the action object using &f-Action;. <para>The &Action; factory function returns an appropriate object for the action -represented by the type of the action argument +represented by the type of the +<parameter>action</parameter> argument (the first positional parmeter):</para> <itemizedlist> <listitem> -<para>If the action argument is already an Action object, +<para>If <parameter>action</parameter> is already an Action object, the object is simply returned.</para> </listitem> <listitem> -<para>If the action argument is a string, +<para>If <parameter>action</parameter> is a string, a command-line Action is returned. -If such a string begins with -<emphasis role="bold">@</emphasis>, -it indicates printing of the command line is to be suppressed. -If the string begins with -<emphasis role="bold">-</emphasis> (hyphen), -it indicates the exit status from the specified command -is to be ignored, allowing execution to continue +If such a string begins with <literal>@</literal>, +the command line is not printed. +If the string begins with hyphen +(<literal>-</literal>), +the exit status from the specified command +is ignored, allowing execution to continue even if the command reports failure:</para> <programlisting language="python"> @@ -5818,14 +5842,13 @@ Action('-build $TARGET $SOURCES') </listitem> <listitem> -<para>If the action argument is a list, +<para>If <parameter>action</parameter> is a list, then a list of Action objects is returned. An Action object is created as necessary for each element in the list. -If an element -<emphasis>within</emphasis> +If an element within the list is itself a list, -the internal list is taken as the +the embedded list is taken as the command and arguments to be executed via the command line. This allows white space to be enclosed @@ -5838,18 +5861,19 @@ Action([['cc', '-c', '-DWHITE SPACE', '-o', '$TARGET', '$SOURCES']]) </listitem> <listitem> -<para>If the action argument is a Python function, -a function Action is returned. -The Python function must accept three keyword arguments:</para> - - <simplelist type="vert"> - <member><parameter>target</parameter> - - a Node object representing the target file.</member> - <member><parameter>source</parameter> - - a Node object representing the source file.</member> - <member><parameter>env</parameter> - - the &consenv; used for building the target file.</member> - </simplelist> +<para>If <parameter>action</parameter> is a callable object, +a Function Action is returned. +The callable must accept three keyword arguments: +<parameter>target</parameter>, +<parameter>source</parameter> and +<parameter>env</parameter>. +<parameter>target</parameter> +is a Node object representing the target file, +<parameter>source</parameter> +is a Node object representing the source file and +<parameter>env</parameter> +is the &consenv; used for building the target file. +</para> <para> The @@ -5886,17 +5910,22 @@ a = Action(build_it) </listitem> <listitem> -<para>If the action argument is not one of the above types, -<constant>None</constant> is returned.</para> +<para>If +<parameter>action</parameter> +is not one of the above types, +no action object is generated and &f-Action; +returns <constant>None</constant>.</para> </listitem> </itemizedlist> -<para>As usual the environment method form &f-link-env-Action; +<para>The environment method form &f-link-env-Action; will expand &consvars; in any argument strings, -including the action argument, at the time it is called, +including +<parameter>action</parameter>, +at the time it is called, using the construction variables in the &consenv; through which it was called. The global function form &f-link-Action; -<emphasis>delays</emphasis> variable expansion until +delays variable expansion until the Action object is actually used. </para> @@ -5912,30 +5941,7 @@ The following argument types are accepted: <itemizedlist> <listitem> -<para>If the output argument is a function, -the function will be called to obtain a string -describing the action being executed. -The function -must accept these three keyword arguments:</para> - - <simplelist type="vert"> - <member><parameter>source</parameter> - - a Node object representing the source file.</member> - <member><parameter>target</parameter> - - a Node object representing the target file.</member> - <member><parameter>env</parameter> - the &consenv;.</member> - </simplelist> - -<para>The -<parameter>target</parameter> -and -<parameter>source</parameter> -arguments may be lists of Node objects if there is -more than one target file or source file.</para> - </listitem> - - <listitem> -<para>If the output argument is a string, +<para>If <parameter>output</parameter> is a string, substitution is performed on the string before it is printed. The string typically contains variables, notably <literal>$TARGET(S)</literal> and <literal>$SOURCE(S)</literal>, @@ -5945,7 +5951,21 @@ variable, which is optionally defined somewhere else. </listitem> <listitem> -<para>If the argument is <constant>None</constant>, +<para>If <parameter>output</parameter> is a function, +the function will be called to obtain a string +describing the action being executed. +The function +must accept three keyword arguments: +<parameter>target</parameter>, +<parameter>source</parameter> and +<parameter>env</parameter>, +with the same interpretation as for a callable +<parameter>action</parameter> argument above. +</para> + </listitem> + + <listitem> +<para>If <parameter>output</parameter>is <constant>None</constant>, output is suppressed entirely.</para> </listitem> </itemizedlist> @@ -5955,8 +5975,8 @@ Instead of using a positional argument, the <parameter>cmdstr</parameter> keyword argument may be used to specify the output string, or the <parameter>strfunction</parameter> keyword argument -may be used to specify a function to return the output string, -Use <literal>cmdstr=None</literal> to suppress output. +may be used to specify a function to return the output string. +<literal>cmdstr=None</literal> suppresses output entirely. </para> <para>Examples:</para> @@ -6022,30 +6042,25 @@ to modify the Action object's behavior:</para> <term><parameter>chdir</parameter></term> <listitem> <para> -Specifies that -scons will execute the action -after changing to the specified directory. -If the -<parameter>chdir</parameter> -argument is -a string or a directory Node, -scons will change to the specified directory. -If the -<parameter>chdir</parameter> -argument -is not a string or Node -and is non-zero, -then scons will change to the +If <parameter>chdir</parameter> is true +(the default is <constant>False</constant>), +&SCons; will change directories before +executing the action. +If the value of <parameter>chdir</parameter> +is a string or a directory Node, +&SCons; will change to the specified directory. +Otherwise, if <parameter>chdir</parameter> evaluates true, +&SCons; will change to the target file's directory.</para> -<para>Note that scons will +<para>Note that &SCons; will <emphasis>not</emphasis> automatically modify its expansion of &consvars; like &cv-TARGET; and &cv-SOURCE; when using the <parameter>chdir</parameter> -keyword argument--that is, +parameter - that is, the expanded file names will still be relative to the top-level directory containing the &SConstruct; file, @@ -6061,8 +6076,7 @@ to use just the filename portion of the targets and source. Example:</para> <programlisting language="python"> -a = Action("build < ${SOURCE.file} > ${TARGET.file}", - chdir=1) +a = Action("build < ${SOURCE.file} > ${TARGET.file}", chdir=True) </programlisting> </listitem> </varlistentry> @@ -6070,11 +6084,10 @@ a = Action("build < ${SOURCE.file} > ${TARGET.file}", <term><parameter>exitstatfunc</parameter></term> <listitem> <para> -A function -that is passed the exit status -(or return value) -from the specified action -and can return an arbitrary +If provided, must be a callable which accepts a single parameter, +the exit status (or return value) +from the specified action, +and which returns an arbitrary or modified value. This can be used, for example, to specify that an Action object's @@ -6097,7 +6110,7 @@ a = Action("build < ${SOURCE.file} > ${TARGET.file}", <term><parameter>batch_key</parameter></term> <listitem> <para> -Specifies that the Action can create multiple target files +If provided, indicates 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 @@ -6134,33 +6147,33 @@ will be used to identify different for batch building. A <parameter>batch_key</parameter> -function must accept the following arguments:</para> - - <simplelist> - <member><parameter>action</parameter> - The action object.</member> - <member><parameter>env</parameter> - - The &consenv; configured for the target.</member> - <member><parameter>target</parameter> - - The list of targets for a particular configured action.</member> - <member><parameter>source</parameter> - - The list of source for a particular configured action.</member> - </simplelist> +function must accept four parameters: +<parameter>action</parameter>, +<parameter>env</parameter>, +<parameter>target</parameter> and +<parameter>source</parameter>. +The first parameter, <parameter>action</parameter>, +is the active action object. +The second parameter, <parameter>env</parameter>, +is the &consenv; configured for the target. +The <parameter>target</parameter> and <parameter>source</parameter> +parameters are the lists of targets and sources +for the configured action. +</para> <para>The returned key should typically be a tuple of values derived from the arguments, using any appropriate logic to decide how multiple invocations should be batched. For example, a -<function>batch_key</function> +<parameter>batch_key</parameter> function may decide to return -the value of a specific construction -variable from the -<parameter>env</parameter> -argument +the value of a specific &consvar; +from <parameter>env</parameter> which will cause &scons; to batch-build targets -with matching values of that variable, +with matching values of that &consvar;, or perhaps return the Python <function>id</function>() of the entire &consenv;, @@ -6197,8 +6210,8 @@ a = Action('build $CHANGED_SOURCES', batch_key=batch_key) <refsect2 id='miscellaneous_action_functions'> <title>Miscellaneous Action Functions</title> -<para>&scons; -supplies a number of functions +<para>&SCons; +supplies Action functions that arrange for various common file and directory manipulations to be performed. @@ -6213,8 +6226,8 @@ return an Action object that can be executed at the appropriate time.</para> -<para>In practice, -there are two natural ways +<para> +There are two natural ways that these Action Functions are intended to be used.</para> @@ -6226,7 +6239,7 @@ at the time the SConscript file is being read, you can use the &f-link-Execute; -global function to do so:</para> +global function:</para> <programlisting language="python"> Execute(Touch('file')) @@ -6284,6 +6297,12 @@ env.Command('foo.out', 'foo.in', Chmod('$TARGET', "ugo+w")]) </programlisting> +<para> +The behavior of <function>Chmod</function> is limited on Windows, +see the notes in the Python documentation for +<systemitem>os.chmod</systemitem>, which is the underlying function. +</para> + </listitem> </varlistentry> @@ -6346,12 +6365,14 @@ Execute(Delete('file_that_must_exist', must_exist=True)) </varlistentry> <varlistentry> - <term><function>Mkdir</function>(<parameter>dir</parameter>)</term> + <term><function>Mkdir</function>(<parameter>name</parameter>)</term> <listitem> <para>Returns an Action -that creates the specified -directory -<parameter>dir</parameter>. +that creates the directory +<parameter>name</parameter> +and all needed intermediate directories. +<parameter>name</parameter> may also be a list +of directories to create. Examples:</para> <programlisting language="python"> diff --git a/lgtm.yml b/lgtm.yml new file mode 100644 index 0000000..952122d --- /dev/null +++ b/lgtm.yml @@ -0,0 +1,135 @@ +########################################################################################## +# Customize file classifications. # +# Results from files under any classifier will be excluded from LGTM # +# statistics. # +########################################################################################## + +########################################################################################## +# Use the `path_classifiers` block to define changes to the default classification of # +# files. # +########################################################################################## + +path_classifiers: + docs: + - doc + - bin + test: + # Override LGTM's default classification of test files by excluding all files. + - exclude: / + # Classify all files in the top-level directories test/ and testing/ as test code. + - test + - testing + # Classify all files with suffix `.Test.py` as test code. + - "**/*.Test.py" + # and the test runner + - runtest.py + # The default behavior is to tag all files created during the + # build as `generated`. Results are hidden for generated code. You can tag + # further files as being generated by adding them to the `generated` section. + generated: + - build + # By default, all files not checked into the repository are considered to be + # 'generated'. + # The default behavior is to tag library code as `library`. Results are hidden + # for library code. You can tag further files as being library code by adding them + # to the `library` section. + library: + - exclude: path/to/libary/code/**/*.c + # The default behavior is to tag template files as `template`. Results are hidden + # for template files. You can tag further files as being template files by adding + # them to the `template` section. + template: + - template + # Define your own category, for example: 'some_custom_category'. + bench: + - bench + - timings + +######################################################################################### +# Define changes to the default code extraction process. # +# Each block configures the extraction of a single language, and modifies actions in a # +# named step. Every named step includes automatic default actions, # +# except for the 'prepare' step. The steps are performed in the following sequence: # +# prepare # +# after_prepare # +# configure (C/C++ only) # +# python_setup (Python only) # +# before_index # +# index # +########################################################################################## + +######################################################################################### +# Environment variables available to the steps: # +######################################################################################### + +# LGTM_SRC +# The root of the source tree. +# LGTM_WORKSPACE +# An existing (initially empty) folder outside the source tree. +# Used for temporary download and setup commands. + +######################################################################################### +# Use the extraction block to define changes to the default code extraction process # +# for one or more languages. The settings for each language are defined in a child # +# block, with one or more steps. # +######################################################################################### + +extraction: + javascript: + # The `prepare` step exists for customization on LGTM.com only. + # prepare: + # packages: + # - example_package + # Add an `after-prepare` step if you need to run commands after the prepare step. + # Each command should be listed on a separate line. + after_prepare: + - export PATH=$LGTM_WORKSPACE/tools:$PATH + # The `index` step extracts information from the files in the codebase. + index: + # Specify a list of files and folders to extract. + # Default: The project root directory. + include: + - src/js + # Specify a list of files and folders to exclude from extraction. + exclude: + - SCons/Tool/docbook/docbook-xsl-1.76.1 + + # Define settings for Python analysis + ###################################### + python: + # The `prepare` step exists for customization on LGTM.com only. + # prepare: + # # The `packages` section is valid for LGTM.com only. It names packages to + # # be installed. + # packages: libpng-dev + # This step is useful for Python analysis where you want to prepare the + # environment for the `python_setup` step without changing the default behavior + # for that step. + after_prepare: + - export PATH=$LGTM_WORKSPACE/tools:$PATH + # This sets up the Python interpreter and virtual environment, ready for the + # `index` step to extract the codebase. + python_setup: + # Specify packages that should NOT be installed despite being mentioned in the + # requirements.txt file. + # Default: no package marked for exclusion. + exclude_requirements: + - pywin32 + - readme-renderer + - sphinx<3.5.0 + - sphinx_rtd_theme + - lxml==4.6.3 + - rst2pdf + # Specify a list of pip packages to install. + # If any of these packages cannot be installed, the extraction will fail. + requirements: + #- Pillow + # Specify a list of requirements text files to use to set up the environment, + # or false for none. Default: any requirements.txt, test-requirements.txt, + # and similarly named files identified in the codebase are used. + requirements_files: + - required-packages.txt + # Specify a setup.py file to use to set up the environment, or false for none. + # Default: any setup.py files identified in the codebase are used in preference + # to any requirements text files. + #setup_py: new-setup.py @@ -199,11 +199,8 @@ if args.short_progress: suppress_output = catch_output = True if args.debug: - for d in sys.path: - pdb = os.path.join(d, 'pdb.py') - if os.path.exists(pdb): - debug = pdb - break + # TODO: add a way to pass a specific debugger + debug = "pdb" if args.exec: scons = args.exec @@ -710,7 +707,7 @@ def run_test(t, io_lock=None, run_async=True): t.headline = "" command_args = [] if debug: - command_args.append(debug) + command_args.extend(['-m', debug]) if args.devmode and sys.version_info >= (3, 7, 0): command_args.append('-X dev') command_args.append(t.path) diff --git a/site_scons/site_init.py b/site_scons/site_init.py index 336cad6..7d51fda 100644 --- a/site_scons/site_init.py +++ b/site_scons/site_init.py @@ -15,4 +15,4 @@ git = os.path.exists('.git') and whereis('git') unzip = whereis('unzip') zip_path = whereis('zip') -BuildCommandLine.git = git
\ No newline at end of file +BuildCommandLine.git = git diff --git a/test/CPPDEFINES/basic.py b/test/CPPDEFINES/basic.py index d0019a1..176f543 100644..100755 --- a/test/CPPDEFINES/basic.py +++ b/test/CPPDEFINES/basic.py @@ -39,13 +39,24 @@ test_list = [ ['x', ['y', 123], 'z', ('int', '$INTEGER')], { 'c' : 3, 'b': None, 'a' : 1 }, "${TESTDEFS}", + "${GEN}", ] + +def generator(target, source, env, for_signature): + if target and source: + return '_'.join([str(target[0]), 'GENERATED', str(source[0])]) + return 'TARGET_AND_SOURCE_ARE_MISSING' + for i in test_list: - env = Environment(CPPDEFPREFIX='-D', CPPDEFSUFFIX='', INTEGER=0, TESTDEFS=["FOO", "BAR=1"]) - print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS')) + env = Environment(CPPDEFPREFIX='-D', CPPDEFSUFFIX='', INTEGER=0, TESTDEFS=["FOO", "BAR=1"], GEN=generator) + ttt = env.Entry('#ttt') + sss = env.Entry('#sss') + print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS', target=[ttt], source=[sss])) for i in test_list: - env = Environment(CPPDEFPREFIX='|', CPPDEFSUFFIX='|', INTEGER=1, TESTDEFS=["FOO", "BAR=1"]) - print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS')) + env = Environment(CPPDEFPREFIX='|', CPPDEFSUFFIX='|', INTEGER=1, TESTDEFS=["FOO", "BAR=1"], GEN=generator) + ttt = env.Entry('#ttt') + sss = env.Entry('#sss') + print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS', target=[ttt], source=[sss])) """) expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n", @@ -55,11 +66,13 @@ expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n", -Dx -Dy=123 -Dz -Dint=0 -Da=1 -Db -Dc=3 -DFOO -DBAR=1 +-Dttt_GENERATED_sss |xyz| |x| |y| |z| |x| |y=123| |z| |int=1| |a=1| |b| |c=3| |FOO| |BAR=1| +|ttt_GENERATED_sss| """) test.run(arguments = '.', stdout=expect) diff --git a/test/Decider/MD5-winonly-fixture/test_parse.y b/test/Decider/MD5-winonly-fixture/test_parse.y index 3ead9d2..2172298 100644 --- a/test/Decider/MD5-winonly-fixture/test_parse.y +++ b/test/Decider/MD5-winonly-fixture/test_parse.y @@ -1,6 +1,9 @@ %{ #include<stdio.h> +int yyerror(char *s); +int yylex(); + int regs[26]; int base; @@ -25,11 +28,13 @@ digit: DIGIT; %% +int main() { return(yyparse()); } +int yyerror(s) char *s; { @@ -37,7 +42,8 @@ char *s; return(0); } +int yywrap() { return(1); -}
\ No newline at end of file +} diff --git a/test/GetOption/BadSetOption.py b/test/GetOption/BadSetOption.py new file mode 100644 index 0000000..7b0a33d --- /dev/null +++ b/test/GetOption/BadSetOption.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +Test that invalid SetOption calls generate expected errors. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +badopts = ( + ("no_such_var", True, "This option is not settable from a SConscript file: no_such_var"), + ("num_jobs", -22, "A positive integer is required: -22"), + ("max_drift", "'Foo'", "An integer is required: 'Foo'"), + ("duplicate", "'cookie'", "Not a valid duplication style: cookie"), + ("diskcheck", "'off'", "Not a valid diskcheck value: off"), + ("md5_chunksize", "'big'", "An integer is required: 'big'"), + ("hash_chunksize", "'small'", "An integer is required: 'small'"), +) + +for opt, value, expect in badopts: + SConstruct = "SC-" + opt + test.write( + SConstruct, + """\ +DefaultEnvironment(tools=[]) +SetOption("%(opt)s", %(value)s) +""" + % locals(), + ) + expect = r"scons: *** %s" % expect + test.run(arguments='-Q -f %s .' % SConstruct, stderr=None, status=2) + test.must_contain_all(test.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/GetSetOption.py b/test/GetOption/GetSetOption.py index 929f8d0..3ab3e7b 100644 --- a/test/GetSetOption.py +++ b/test/GetOption/GetSetOption.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test getting and setting options through global functions @@ -33,7 +32,8 @@ import TestSCons test = TestSCons.TestSCons() test.write('SConstruct', """ -env = Environment() +DefaultEnvironment(tools=[]) +env = Environment(tools=[]) option_list = ['clean', 'implicit_cache', 'max_drift', 'num_jobs'] val = 1 for option in option_list: diff --git a/test/GetOption/help.py b/test/GetOption/help.py index f83dc54..4db4bc8 100644 --- a/test/GetOption/help.py +++ b/test/GetOption/help.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test use of GetOption('help') to short-circuit work. @@ -40,14 +39,14 @@ else: print("no help for you") """) -test.run(arguments = '-q -Q', stdout = "no help for you\n") +test.run(arguments='-q -Q', stdout="no help for you\n") expect = "GetOption('help') set" -test.run(arguments = '-q -Q -h') +test.run(arguments='-q -Q -h') test.fail_test(test.stdout().split('\n')[0] != expect) -test.run(arguments = '-q -Q --help') +test.run(arguments='-q -Q --help') test.fail_test(test.stdout().split('\n')[0] != expect) test.pass_test() diff --git a/test/Install/Clone.py b/test/Install/Clone.py index 14e0688..c88a078 100644 --- a/test/Install/Clone.py +++ b/test/Install/Clone.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that we can Install() and InstallAs() from a construction diff --git a/test/Install/INSTALLSTR.py b/test/Install/INSTALLSTR.py index ace04f4..3ce71be 100644 --- a/test/Install/INSTALLSTR.py +++ b/test/Install/INSTALLSTR.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test that the $INSTALLSTR variable is displayed when we install a file. diff --git a/test/Install/Install-ro.py b/test/Install/Install-ro.py new file mode 100644 index 0000000..aa7e6f3 --- /dev/null +++ b/test/Install/Install-ro.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# +# MIT Licenxe +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +Test that SCons allows Install on top of an existing read-only file. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.file_fixture('fixture/SConstruct-multi', 'SConstruct') +test.run(arguments=["-Q"]) +test.run(arguments=["-Q"]) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: diff --git a/test/Install/Install.py b/test/Install/Install.py index 0647002..2857c72 100644 --- a/test/Install/Install.py +++ b/test/Install/Install.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that the Install() Builder works diff --git a/test/Install/InstallAs.py b/test/Install/InstallAs.py index 47ee9f6..24a9ddc 100644 --- a/test/Install/InstallAs.py +++ b/test/Install/InstallAs.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test the InstallAs() Environment method. @@ -83,7 +82,6 @@ test.must_match(install_file1a_out, "file1.in\n", mode='r') test.up_to_date(arguments = '.') -# test.pass_test() # Local Variables: diff --git a/test/Install/dir-exists.py b/test/Install/dir-exists.py index 9882d22..9e9a9b0 100644 --- a/test/Install/dir-exists.py +++ b/test/Install/dir-exists.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test using Install() on directories that exist. @@ -49,7 +48,7 @@ Mkdir("b") echo hi > a%sf Install directory: "a" as "b%sa" """%(os.sep, os.sep) -test.run(arguments = ["-Q"], stdout = expect) +test.run(arguments=["-Q"], stdout=expect) test.must_exist(test.workpath('a', 'f')) test.must_exist(test.workpath('b', 'a', 'f')) diff --git a/test/Install/directories.py b/test/Install/directories.py index e980936..66182b7 100644 --- a/test/Install/directories.py +++ b/test/Install/directories.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test using Install() on directories. @@ -33,16 +32,18 @@ import TestSCons test = TestSCons.TestSCons() -test.subdir('outside', - 'work', - ['work', 'dir1'], - ['work', 'dir1', 'sub'], - ['work', 'dir2'], - ['work', 'dir2', 'sub'], - ['work', 'dir3'], - ['work', 'dir3', 'sub'], - ['work', 'dir4'], - ['work', 'dir4', 'sub']) +test.subdir( + 'outside', + 'work', + ['work', 'dir1'], + ['work', 'dir1', 'sub'], + ['work', 'dir2'], + ['work', 'dir2', 'sub'], + ['work', 'dir3'], + ['work', 'dir3', 'sub'], + ['work', 'dir4'], + ['work', 'dir4', 'sub'], +) test.write(['work', 'SConstruct'], """\ DefaultEnvironment(tools=[]) @@ -80,7 +81,7 @@ Install directory: "dir3" as "%s" Install directory: "dir4" as "%s" """ % tuple(arguments)) -test.run(chdir = 'work', arguments = arguments, stdout = expect) +test.run(chdir='work', arguments=arguments, stdout=expect) test.must_match(test.workpath('outside', 'dir1', 'f2'), "work/dir1/f2\n") test.must_match(test.workpath('outside', 'dir1', 'sub', 'f3'), "work/dir1/sub/f3\n") diff --git a/test/Install/fixture/SConstruct-multi b/test/Install/fixture/SConstruct-multi new file mode 100644 index 0000000..94de1df --- /dev/null +++ b/test/Install/fixture/SConstruct-multi @@ -0,0 +1,24 @@ +# first run creates a src file, makes it read-only, and installs. +# second run updates src, Install should successfully replace +# the previous install (read-only attr on Windows might fail it) + +import os +import pathlib +import stat + +destdir = pathlib.Path("bin") +destdir.mkdir(exist_ok=True) + +srcfile = pathlib.Path("hello") +try: + srcfile.chmod(stat.S_IREAD | stat.S_IWRITE) +except OSError: + pass + +with srcfile.open(mode="w") as f: + print("Hello from ", os.getpid(), file=f) +srcfile.chmod(stat.S_IREAD) + +DefaultEnvironment(tools=[]) +env = Environment(tools=[]) +env.Install('bin', 'hello') diff --git a/test/Install/multi-dir.py b/test/Install/multi-dir.py index ddb6d0a..648f46f 100644 --- a/test/Install/multi-dir.py +++ b/test/Install/multi-dir.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that using Install to create multiple dir hierarchies outside diff --git a/test/Install/multi-dir/src/SConstruct b/test/Install/multi-dir/src/SConstruct index 05b46a9..44e3589 100644 --- a/test/Install/multi-dir/src/SConstruct +++ b/test/Install/multi-dir/src/SConstruct @@ -1,7 +1,8 @@ # This tests for a bug where installing a sequence dirs and subdirs # outside the source tree can cause SCons to fail to create the dest # dir. -import os, os.path, shutil +import os + DefaultEnvironment(tools=[]) env=Environment(tools=[]) dst='../build' diff --git a/test/Install/multi.py b/test/Install/multi.py index 1716d17..2d83981 100644 --- a/test/Install/multi.py +++ b/test/Install/multi.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that multiple calls to test.Install() with the same file @@ -42,8 +41,7 @@ env.Install('install', 'file1') test.write('file1', "file1\n") -test.run(arguments = '.') - +test.run(arguments='.') test.must_match(['install', 'file1'], "file1\n") test.pass_test() diff --git a/test/Install/no-top-relative.py b/test/Install/no-top-relative.py index 31c7130..efba365 100644 --- a/test/Install/no-top-relative.py +++ b/test/Install/no-top-relative.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that we can install a file if its file name portion begins diff --git a/test/Install/non-ascii-name.py b/test/Install/non-ascii-name.py index 7e25743..59a7406 100644 --- a/test/Install/non-ascii-name.py +++ b/test/Install/non-ascii-name.py @@ -1,7 +1,8 @@ -# -*- coding: utf-8 -*- #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -21,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that the Install() Builder works diff --git a/test/Install/option--install-sandbox.py b/test/Install/option--install-sandbox.py index 45366c1..bb64c34 100644 --- a/test/Install/option--install-sandbox.py +++ b/test/Install/option--install-sandbox.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test the --install-sandbox commandline option for Install() and InstallAs(). @@ -43,11 +42,8 @@ _SUBDIR_file3_in = os.path.join('$SUBDIR', 'file3.in') target_file2_out = os.path.join(target, 'file2.out') subdir_file3_in = os.path.join('subdir', 'file3.in') target_subdir_file3_out = os.path.join(target, 'subdir', 'file3.out') -file1_out = target+os.path.join( target, - os.path.splitdrive(destdir)[1], - 'file1.out' ) +file1_out = target + os.path.join(target, os.path.splitdrive(destdir)[1], 'file1.out') -# test.write('SConstruct', r""" DefaultEnvironment(tools=[]) env = Environment(tools=[], SUBDIR='subdir') diff --git a/test/Install/tool.py b/test/Install/tool.py index ba92d0a..0730e37 100644 --- a/test/Install/tool.py +++ b/test/Install/tool.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that we can still call Install() and InstallAs() even when @@ -37,14 +36,14 @@ test.subdir('iii') test.write('SConstruct', """ DefaultEnvironment(tools=[]) -env = Environment(tools = []) +env = Environment(tools=[]) env.Install('iii', 'foo.in') env.InstallAs('foo.out', 'foo.in') """) test.write('foo.in', "foo.in\n") -test.run(arguments = '.') +test.run(arguments='.') test.must_match(['iii', 'foo.in'], "foo.in\n") test.must_match('foo.out', "foo.in\n") diff --git a/test/Install/wrap-by-attribute.py b/test/Install/wrap-by-attribute.py index 014b7a5..c18ea77 100644 --- a/test/Install/wrap-by-attribute.py +++ b/test/Install/wrap-by-attribute.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT Licenxe +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ @@ -45,6 +44,7 @@ test.write('SConstruct', """\ DefaultEnvironment(tools=[]) import os.path + def cat(env, source, target): target = str(target[0]) with open(target, 'wb') as ofp: @@ -52,18 +52,23 @@ def cat(env, source, target): with open(str(src), 'rb') as ifp: ofp.write(ifp.read()) + env = Environment(tools=[], DESTDIR='dest') -env.Append(BUILDERS={'Cat':Builder(action=cat)}) +env.Append(BUILDERS={'Cat': Builder(action=cat)}) env.SconsInternalInstallFunc = env.Install env.SconsInternalInstallAsFunc = env.InstallAs + def InstallWithDestDir(dir, source): abspath = os.path.splitdrive(env.Dir(dir).get_abspath())[1] - return env.SconsInternalInstallFunc('$DESTDIR'+abspath, source) + return env.SconsInternalInstallFunc('$DESTDIR' + abspath, source) + + def InstallAsWithDestDir(target, source): abspath = os.path.splitdrive(env.File(target).get_abspath())[1] - return env.SconsInternalInstallAsFunc('$DESTDIR'+abspath, source) + return env.SconsInternalInstallAsFunc('$DESTDIR' + abspath, source) + # Add the wrappers directly as attributes. env.Install = InstallWithDestDir @@ -82,7 +87,6 @@ t = e2.Cat(target='f3.out', source='f3.in') e2.Install('export', source=t) t = e2.Cat(target='f4.out', source='f4.in') e2.InstallAs('export/f4-new.out', source=t) - """) test.write('f1.in', "f1.in\n") @@ -90,7 +94,7 @@ test.write('f2.in', "f2.in\n") test.write('f3.in', "f3.in\n") test.write('f4.in', "f4.in\n") -test.run(arguments = '.') +test.run(arguments='.') export = os.path.splitdrive(test.workpath('export'))[1] @@ -104,7 +108,7 @@ test.must_match(f2_new_out, "f2.in\n") test.must_match(f3_out, "f3.in\n") test.must_match(f4_new_out, "f4.in\n") -test.up_to_date(arguments = '.') +test.up_to_date(arguments='.') test.pass_test() diff --git a/test/LEX/LEXFLAGS.py b/test/LEX/LEXFLAGS.py index 2cebca7..efcf9c4 100644 --- a/test/LEX/LEXFLAGS.py +++ b/test/LEX/LEXFLAGS.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,11 +22,9 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import sys +import sysconfig import TestSCons @@ -59,10 +59,12 @@ sys.exit(0) """) test.write('SConstruct', """ -env = Environment(LEX = r'%(_python_)s mylex.py', - LEXFLAGS = '-x -I${TARGET.dir} -I${SOURCE.dir}', - tools=['default', 'lex']) -env.CFile(target = 'out/aaa', source = 'in/aaa.l') +env = Environment( + LEX=r'%(_python_)s mylex.py', + LEXFLAGS='-x -I${TARGET.dir} -I${SOURCE.dir}', + tools=['default', 'lex'], +) +env.CFile(target='out/aaa', source='in/aaa.l') """ % locals()) test.write(['in', 'aaa.l'], "aaa.l\nLEXFLAGS\nI_ARGS\n") @@ -70,7 +72,7 @@ test.write(['in', 'aaa.l'], "aaa.l\nLEXFLAGS\nI_ARGS\n") test.run('.', stderr = None) lexflags = ' -x -t' -if sys.platform == 'win32': +if sys.platform == 'win32' and not sysconfig.get_platform() in ("mingw",): lexflags = ' --nounistd' + lexflags # Read in with mode='r' because mylex.py implicitley wrote to stdout # with mode='w'. diff --git a/test/LEX/live_mingw.py b/test/LEX/live_mingw.py index d535065..5c64eb8 100644 --- a/test/LEX/live_mingw.py +++ b/test/LEX/live_mingw.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test LEX and LEXFLAGS and unistd.h with a live lex in mingw environment. @@ -41,7 +40,7 @@ if sys.platform != 'win32': test.skip_test('Not windows environment; skipping test.\n') if not test.where_is('gcc'): - test.skip_test('No mingw or cygwin build environment found; skipping test.\n') + test.skip_test('No mingw or cygwin build environment found; skipping test.\n') lex = test.where_is('lex') or test.where_is('flex') @@ -53,12 +52,14 @@ test.file_fixture('wrapper.py') test.write('SConstruct', """ foo = Environment(tools=['default', 'mingw', 'lex'], LEXUNISTD="") lex = foo.Dictionary('LEX') -bar = Environment(LEX = r'%(_python_)s wrapper.py ' + lex, - LEXFLAGS = '-b', - LEXUNISTD="", - tools=['default', 'mingw', 'lex']) -foo.Program(target = 'foo', source = 'foo.l') -bar.Program(target = 'bar', source = 'bar.l') +bar = Environment( + LEX=r'%(_python_)s wrapper.py ' + lex, + LEXFLAGS='-b', + LEXUNISTD="", + tools=['default', 'mingw', 'lex'], +) +foo.Program(target='foo', source='foo.l') +bar.Program(target='bar', source='bar.l') """ % locals()) lex = r""" diff --git a/test/LINK/SHLIBVERSIONFLAGS.py b/test/LINK/SHLIBVERSIONFLAGS.py index 7832862..158e82a 100644 --- a/test/LINK/SHLIBVERSIONFLAGS.py +++ b/test/LINK/SHLIBVERSIONFLAGS.py @@ -47,9 +47,9 @@ elif 'sunlink' in tool_list: soname = 'libfoo.so.4' sonameVersionFlags = r".+ -h %s( .+)+" % soname elif 'applelink' in tool_list: - versionflags = r" 'libfoo.1.dylib'->'libfoo.1.2.3.dylib'" + versionflags = r".+ -Wl,-current_version,1.2.3( .+)+" soname = 'libfoo.4.dylib' - sonameVersionFlags = r" '%s'->'libfoo.1.2.3.dylib'(.+)+" % soname + sonameVersionFlags = r".+ -Wl,-compatibility_version,1.2.0(.+)+" else: test.skip_test('No testable linkers found, skipping the test\n') diff --git a/test/Libs/SharedLibrary-update-deps.py b/test/Libs/SharedLibrary-update-deps.py index 922d580..f8ab44d 100644 --- a/test/Libs/SharedLibrary-update-deps.py +++ b/test/Libs/SharedLibrary-update-deps.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,16 +22,16 @@ # 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 SharedLibrary() updates when a different lib is linked, even if it has the same md5. +Test that SharedLibrary() updates when a different lib is linked, +even if it has the same md5. This is https://github.com/SCons/scons/issues/2903 """ import sys +import sysconfig + import TestSCons test = TestSCons.TestSCons() @@ -50,7 +52,7 @@ test.run(arguments='libname=foo') test.must_not_contain_any_line(test.stdout(), ["is up to date"]) # Now try changing the link command line (in an innocuous way); should rebuild. -if sys.platform == 'win32': +if sys.platform == 'win32' and not sysconfig.get_platform() in ("mingw",): extraflags='shlinkflags=/DEBUG' else: extraflags='shlinkflags=-g' diff --git a/test/Libs/SharedLibrary.py b/test/Libs/SharedLibrary.py index 3d2c734..f67d707 100644 --- a/test/Libs/SharedLibrary.py +++ b/test/Libs/SharedLibrary.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os import sys @@ -33,38 +32,36 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ import sys -env=Environment(WINDOWS_INSERT_DEF=1) -env2 = Environment(LIBS = [ 'foo1', 'foo2', 'foo3' ], - LIBPATH = [ '.' ]) -env.SharedLibrary(target = 'foo1', source = 'f1.c') + +env = Environment(WINDOWS_INSERT_DEF=1) +env2 = Environment(LIBS=['foo1', 'foo2', 'foo3'], LIBPATH=['.']) +env.SharedLibrary(target='foo1', source='f1.c') if sys.platform == 'win32': - env.StaticLibrary(target = 'foo1-static', source = 'f1.c') + env.StaticLibrary(target='foo1-static', source='f1.c') else: - env.StaticLibrary(target = 'foo1', source = 'f1.c') -SharedLibrary(target = 'foo2', - source = Split('f2a.c f2b.c f2c.c'), - WINDOWS_INSERT_DEF = 1) -env.SharedLibrary(target = 'foo3', source = ['f3a.c', 'f3b.c', 'f3c.c'], no_import_lib = 1) -env2.Program(target = 'prog', source = 'prog.c') + env.StaticLibrary(target='foo1', source='f1.c') +SharedLibrary(target='foo2', source=Split('f2a.c f2b.c f2c.c'), WINDOWS_INSERT_DEF=1) +env.SharedLibrary(target='foo3', source=['f3a.c', 'f3b.c', 'f3c.c'], no_import_lib=1) +env2.Program(target='prog', source='prog.c') """) test.write('SConstructFoo', """ -env=Environment() +env = Environment() obj = env.Object('foo', 'foo.c') -Default(env.SharedLibrary(target = 'foo', source = obj)) +Default(env.SharedLibrary(target='foo', source=obj)) """) test.write('SConstructFoo2', """ -env=Environment() +env = Environment() obj = env.SharedObject('bar', 'foo.c') -Default(env.Library(target = 'foo', source = obj)) +Default(env.Library(target='foo', source=obj)) """) test.write('SConstructBaz', """ -env=Environment() +env = Environment() env['SHLIBVERSION'] = '1.0.0' obj = env.SharedObject('baz', 'foo.c') -Default(env.SharedLibrary(target = 'baz', source = obj)) +Default(env.SharedLibrary(target='baz', source=obj)) """) test.write('foo.c', r""" @@ -252,7 +249,7 @@ env2.Program(target = 'progbar', source = 'progbar.c') test.write('f4.c', r""" #include <stdio.h> -f4(void) +void f4(void) { printf("f4.c\n"); fflush(stdout); diff --git a/test/MinGW/MinGWSharedLibrary.py b/test/MinGW/MinGWSharedLibrary.py index 9ce4eb3..9fac820 100644 --- a/test/MinGW/MinGWSharedLibrary.py +++ b/test/MinGW/MinGWSharedLibrary.py @@ -41,30 +41,28 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() -if sys.platform not in ('cygwin','win32',): - test.skip_test("Skipping mingw test on non-Windows %s platform."%sys.platform) +if sys.platform not in ('cygwin', 'win32',): + test.skip_test("Skipping mingw test on non-Windows platform %s." % sys.platform) -gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) +dp = MINGW_DEFAULT_PATHS +gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=dp) if not gcc: test.skip_test("Skipping mingw test, no MinGW found.\n") test.write('foobar.cc', """ int abc(int a) { return (a+1); - } - """) +} +""") test.write('SConstruct', """ DefaultEnvironment(tools=[]) -env = Environment(tools=['mingw','link','g++']) -#env.Tool('mingw') +env = Environment(tools=['mingw', 'link', 'g++']) foobar_obj = env.SharedObject('foobar.cc') env.SharedLibrary('foobar', foobar_obj) # Now verify versioned shared library doesn't fail env.SharedLibrary('foobar_ver', foobar_obj, SHLIBVERSION='2.4') - - """ % locals()) test.run(arguments = ".") diff --git a/test/MinGW/RCCOM.py b/test/MinGW/RCCOM.py index a4d9147..ffd58c8 100644 --- a/test/MinGW/RCCOM.py +++ b/test/MinGW/RCCOM.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,13 +22,10 @@ # 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 the ability to configure the $RCCOM construction variable -when using MinGW. +when using MinGW. This test does not use a compiler. """ import sys @@ -37,14 +36,17 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() if sys.platform in ('irix6',): - test.skip_test("Skipping mingw test on non-Windows %s platform."%sys.platform) + test.skip_test("Skipping mingw test on non-Windows platform %s." % sys.platform) test.file_fixture('mycompile.py') test.write('SConstruct', """ -env = Environment(tools=['default', 'mingw'], - RCCOM = r'%(_python_)s mycompile.py rc $TARGET $SOURCES') -env.RES(target = 'aaa', source = 'aaa.rc') +DefaultEnvironment(tools=[]) +env = Environment( + tools=['default', 'mingw'], + RCCOM=r'%(_python_)s mycompile.py rc $TARGET $SOURCES', +) +env.RES(target='aaa', source='aaa.rc') """ % locals()) test.write('aaa.rc', "aaa.rc\n/*rc*/\n") diff --git a/test/MinGW/RCCOMSTR.py b/test/MinGW/RCCOMSTR.py index 0ed84c2..e661577 100644 --- a/test/MinGW/RCCOMSTR.py +++ b/test/MinGW/RCCOMSTR.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,13 +22,11 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test that the $RCCOMSTR construction variable allows you to customize -the displayed string when rc is called. +the displayed string when rc is called when using MinGW. +This test does not use a compiler. """ import sys @@ -42,10 +42,13 @@ if sys.platform in ('irix6',): test.file_fixture('mycompile.py') test.write('SConstruct', """ -env = Environment(tools=['default', 'mingw'], - RCCOM = r'%(_python_)s mycompile.py rc $TARGET $SOURCES', - RCCOMSTR = 'RCing $TARGET from $SOURCE') -env.RES(target = 'aaa', source = 'aaa.rc') +DefaultEnvironment(tools=[]) +env = Environment( + tools=['default', 'mingw'], + RCCOM=r'%(_python_)s mycompile.py rc $TARGET $SOURCES', + RCCOMSTR='RCing $TARGET from $SOURCE', +) +env.RES(target='aaa', source='aaa.rc') """ % locals()) test.write('aaa.rc', "aaa.rc\n/*rc*/\n") diff --git a/test/MinGW/WINDOWS_INSERT_DEF.py b/test/MinGW/WINDOWS_INSERT_DEF.py index f82ebd8..5119c97 100644 --- a/test/MinGW/WINDOWS_INSERT_DEF.py +++ b/test/MinGW/WINDOWS_INSERT_DEF.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Make sure that WINDOWS_INSERT_DEF isn't ignored when using MinGW. @@ -39,11 +38,11 @@ from SCons.Platform.cygwin import CYGWIN_DEFAULT_PATHS test = TestSCons.TestSCons() -if sys.platform not in ('cygwin', 'win32'): - test.skip_test( - "Skipping mingw test on non-Windows platform: %s" % sys.platform) +if sys.platform not in ('cygwin', 'win32',): + test.skip_test("Skipping mingw test on non-Windows platform %s\n" % sys.platform) -gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS ) +dp = MINGW_DEFAULT_PATHS +gcc = SCons.Tool.find_program_path(test.Environment(), 'gcc', default_paths=dp) if not gcc: test.skip_test("Skipping mingw test, no MinGW found.\n") @@ -53,9 +52,9 @@ int hello_world(void) { return printf("Orbis, te saluto!\n"); } """) test.write('SConstruct', """ -env = Environment(TOOLS = ['mingw']) -hello_dll = env.SharedLibrary(WINDOWS_INSERT_DEF = 0, - target = 'hello', source = 'hello.c') +DefaultEnvironment(tools=[]) +env = Environment(TOOLS=['mingw']) +hello_dll = env.SharedLibrary(WINDOWS_INSERT_DEF=0, target='hello', source='hello.c') """ % locals()) test.run(arguments = ".") diff --git a/test/MinGW/bug_2799/SConstruct b/test/MinGW/bug_2799/SConstruct index a1832f1..f22cacc 100644 --- a/test/MinGW/bug_2799/SConstruct +++ b/test/MinGW/bug_2799/SConstruct @@ -1,12 +1,12 @@ env = Environment( - tools = ['mingw'], - SHCCCOMSTR = 'SHCC $TARGET', - SHLINKCOMSTR = 'SHLINK $TARGET', - LDMODULECOMSTR = 'LDMODULE $TARGET', - SHOBSUFFIX='.o', - SHLIBSUFFIX='.so', - SHLIBPREFIX='lib', - LDMODULESUFFIX='.so', + tools=['mingw'], + SHCCCOMSTR='SHCC $TARGET', + SHLINKCOMSTR='SHLINK $TARGET', + LDMODULECOMSTR='LDMODULE $TARGET', + SHOBSUFFIX='.o', + SHLIBSUFFIX='.so', + SHLIBPREFIX='lib', + LDMODULESUFFIX='.so', ) env.SharedLibrary('testlib', 'shlib.c') diff --git a/test/MinGW/mingw_uses_comstr_issue_2799.py b/test/MinGW/mingw_uses_comstr_issue_2799.py index fc96ad4..ae34f40 100644 --- a/test/MinGW/mingw_uses_comstr_issue_2799.py +++ b/test/MinGW/mingw_uses_comstr_issue_2799.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -37,13 +39,16 @@ test = TestSCons.TestSCons() test.dir_fixture('bug_2799') test.run('-n -Q') -test.must_contain_all_lines(test.stdout(), - [ - 'SHCC shlib.o', - 'SHLINK libtestlib.so', - 'SHCC module.o', - 'LDMODULE libtestmodule.so',''], - ) +test.must_contain_all_lines( + test.stdout(), + [ + 'SHCC shlib.o', + 'SHLINK libtestlib.so', + 'SHCC module.o', + 'LDMODULE libtestmodule.so', + '', + ], +) test.pass_test() diff --git a/test/Scanner/Python.py b/test/Scanner/Python.py new file mode 100644 index 0000000..b5b3ae5 --- /dev/null +++ b/test/Scanner/Python.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +Functional test for the Python scanner. Validates that the scanner is able to +find dynamically generated dependencies. The SConstruct copies in the +dependencies and runs a script. The expected behavior is that the scanner +picks up these dependencies, so SCons understands that the script shouldn't +be run until the files are copied. +""" + +import TestSCons + +test = TestSCons.TestSCons() +test.dir_fixture('Python') +test.run(arguments = '.') +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Scanner/Python/SConstruct b/test/Scanner/Python/SConstruct new file mode 100644 index 0000000..988cf60 --- /dev/null +++ b/test/Scanner/Python/SConstruct @@ -0,0 +1,16 @@ +import sys + +env = Environment(tools=['python']) + +# Copy each file individually instead of copying the dir. This has the benefit +# of establishing nodes in-memory for each of the resulting files, which helps +# the scanner work correctly. +srcDir = env.Dir('to_be_copied') +for srcNode in srcDir.glob('*'): + for destDir in [env.Dir('package1'), env.Dir('package2')]: + env.Command(destDir.File(srcNode.name), srcNode, + Copy('$TARGET', '$SOURCE')) + +# Don't set a dependency on the copy actions on purpose. Scanner should find +# the dependencies automatically. +env.Command('a.out', 'script.py', '$PYTHON $SOURCE $TARGET', PYTHON=sys.executable)
\ No newline at end of file diff --git a/test/Scanner/Python/sconstest.skip b/test/Scanner/Python/sconstest.skip new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Scanner/Python/sconstest.skip diff --git a/test/Scanner/Python/script.py b/test/Scanner/Python/script.py new file mode 100644 index 0000000..105a575 --- /dev/null +++ b/test/Scanner/Python/script.py @@ -0,0 +1,6 @@ +import package1 # noqa: F401 +import package2 # noqa: F401 +import sys + +with open(sys.argv[1], 'w') as f: + f.write('test') diff --git a/test/Scanner/Python/to_be_copied/__init__.py b/test/Scanner/Python/to_be_copied/__init__.py new file mode 100644 index 0000000..3c1c05b --- /dev/null +++ b/test/Scanner/Python/to_be_copied/__init__.py @@ -0,0 +1 @@ +from . import helper # noqa: F401
\ No newline at end of file diff --git a/test/Scanner/Python/to_be_copied/helper.py b/test/Scanner/Python/to_be_copied/helper.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Scanner/Python/to_be_copied/helper.py diff --git a/test/Scanner/Python/to_be_copied/sconstest.skip b/test/Scanner/Python/to_be_copied/sconstest.skip new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/Scanner/Python/to_be_copied/sconstest.skip diff --git a/test/Win32/mingw.py b/test/Win32/mingw.py index c45b7c6..aca8795 100644 --- a/test/Win32/mingw.py +++ b/test/Win32/mingw.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# # MIT License # # Copyright The SCons Foundation @@ -21,11 +22,12 @@ # 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. + """ This tests the MinGW C/C++ compiler support. +This test requires MinGW to be installed. """ - import os import sys @@ -39,13 +41,11 @@ if sys.platform != 'win32': msg = "Skipping mingw test on non-Windows platform '%s'\n" % sys.platform test.skip_test(msg) -# This test requires MinGW to be installed: test.write('SConstruct',""" -from SCons.Tool.mingw import exists import sys +from SCons.Tool.mingw import exists DefaultEnvironment(tools=[]) - env = Environment() if exists(env): print('mingw exists') @@ -61,12 +61,17 @@ test.subdir('header') # Do the actual testing: test.write('SConstruct',""" DefaultEnvironment(tools=[]) -env=Environment(tools=['mingw']) +env = Environment(tools=['mingw']) assert env['CC'] == 'gcc' env.StaticLibrary('static', 'static.cpp') env.SharedLibrary('shared', 'shared.cpp') env.SharedLibrary('cshared', ['cshared.c', 'cshared.def'], WINDOWS_INSERT_DEF=1) -env.Program('test', ['test.cpp', env.RES('resource.rc', CPPPATH=['header'])], LIBS=['static', 'shared', 'cshared'], LIBPATH=['.']) +env.Program( + 'test', + ['test.cpp', env.RES('resource.rc', CPPPATH=['header'])], + LIBS=['static', 'shared', 'cshared'], + LIBPATH=['.'], +) """) test.write('test.cpp', ''' diff --git a/test/Win32/msvc_mingw_env.py b/test/Win32/msvc_mingw_env.py index 107cd1e..f278cfa 100644 --- a/test/Win32/msvc_mingw_env.py +++ b/test/Win32/msvc_mingw_env.py @@ -1,10 +1,8 @@ -""" -This tests the MinGW with MSVC tool. -""" - #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -24,9 +22,10 @@ This tests the MinGW with MSVC tool. # 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__" +""" +This tests the MinGW with MSVC tool. +""" import sys @@ -43,21 +42,22 @@ test.skip_if_not_msvc() # control test: check for nologo and cl in env test.write('SConstruct',""" -env=Environment(tools=['default']) +DefaultEnvironment(tools=[]) +env = Environment(tools=['default']) print('CCFLAGS=' + str(env['CCFLAGS']).strip()) print('CC=' + str(env['CC']).strip()) """) test.run(arguments='-Q -s') -if('CCFLAGS=/nologo' not in test.stdout() - or 'CC=cl' not in test.stdout()): +if 'CCFLAGS=/nologo' not in test.stdout() or 'CC=cl' not in test.stdout(): test.fail_test() # make sure windows msvc doesnt add bad mingw flags # and that gcc is selected test.write('SConstruct',""" -env=Environment(tools=['default', 'mingw']) -print('CCFLAGS="' + str(env['CCFLAGS']).strip() + '"') -print('CC=' + str(env['CC']).strip()) +DefaultEnvironment(tools=[]) +env = Environment(tools=['default', 'mingw']) +print('CCFLAGS="' + str(env['CCFLAGS']).strip() + '"') +print('CC=' + str(env['CC']).strip()) """) test.run(arguments='-Q -s') if('CCFLAGS=""' not in test.stdout() @@ -66,18 +66,19 @@ if('CCFLAGS=""' not in test.stdout() # msvc should overwrite the flags and use cl test.write('SConstruct',""" -env=Environment(tools=['mingw', 'default']) +DefaultEnvironment(tools=[]) +env = Environment(tools=['mingw', 'default']) print('CCFLAGS=' + str(env['CCFLAGS']).strip()) print('CC=' + str(env['CC']).strip()) """) test.run(arguments='-Q -s') -if('CCFLAGS=/nologo' not in test.stdout() - or 'CC=cl' not in test.stdout()): +if 'CCFLAGS=/nologo' not in test.stdout() or 'CC=cl' not in test.stdout(): test.fail_test() # test that CCFLAGS are preserved test.write('SConstruct',""" -env=Environment(tools=['mingw'], CCFLAGS='-myflag') +DefaultEnvironment(tools=[]) +env = Environment(tools=['mingw'], CCFLAGS='-myflag') print(env['CCFLAGS']) """) test.run(arguments='-Q -s') @@ -86,7 +87,8 @@ if '-myflag' not in test.stdout(): # test that it handles a list test.write('SConstruct',""" -env=Environment(tools=['mingw'], CCFLAGS=['-myflag', '-myflag2']) +DefaultEnvironment(tools=[]) +env = Environment(tools=['mingw'], CCFLAGS=['-myflag', '-myflag2']) print(str(env['CCFLAGS'])) """) test.run(arguments='-Q -s') diff --git a/test/fixture/python_scanner/from_import_simple_package_module1_func.py b/test/fixture/python_scanner/from_import_simple_package_module1_func.py new file mode 100644 index 0000000..e9877fb --- /dev/null +++ b/test/fixture/python_scanner/from_import_simple_package_module1_func.py @@ -0,0 +1 @@ +from simple_package.module1 import somefunc # noqa: F401
\ No newline at end of file diff --git a/test/fixture/python_scanner/from_nested1_import_multiple.py b/test/fixture/python_scanner/from_nested1_import_multiple.py new file mode 100644 index 0000000..2cdd47f --- /dev/null +++ b/test/fixture/python_scanner/from_nested1_import_multiple.py @@ -0,0 +1 @@ +from nested1 import module, nested2 # noqa: F401
\ No newline at end of file diff --git a/test/fixture/python_scanner/imports_unknown_files.py b/test/fixture/python_scanner/imports_unknown_files.py new file mode 100644 index 0000000..5582e7b --- /dev/null +++ b/test/fixture/python_scanner/imports_unknown_files.py @@ -0,0 +1,3 @@ +import doesntexist # noqa: F401 +import notthere.something # noqa: F401 +from notthere import a, few, things # noqa: F401
\ No newline at end of file diff --git a/test/fixture/python_scanner/simple_package/module1.py b/test/fixture/python_scanner/simple_package/module1.py index e69de29..6880c47 100644 --- a/test/fixture/python_scanner/simple_package/module1.py +++ b/test/fixture/python_scanner/simple_package/module1.py @@ -0,0 +1,2 @@ +def somefunc(): + return
\ No newline at end of file diff --git a/test/fixture/python_scanner/simple_package/somefunc.py b/test/fixture/python_scanner/simple_package/somefunc.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/fixture/python_scanner/simple_package/somefunc.py diff --git a/test/long-lines/signature.py b/test/long-lines/signature.py index 7f9ba43..ef1b956 100644 --- a/test/long-lines/signature.py +++ b/test/long-lines/signature.py @@ -1,5 +1,7 @@ #!/usr/bin/env python # +# MIT License +# # Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining @@ -20,7 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# """ Verify that use of long command lines correctly excludes arguments @@ -36,18 +37,22 @@ test = TestSCons.TestSCons() build_py = test.workpath('build.py') +# create a dummy command which understands a tempfile syntax +# so it doesn't have to be that platform/compiler's specific syntax. test.write(build_py, """\ #!%(_python_)s import sys -if sys.argv[1][0] == '@': - with open(sys.argv[1][1:], 'r') as f: - args = f.read().split() +if sys.argv[1].startswith('@'): + tempfile = sys.argv[1][1:] + with open(tempfile, 'r') as tmp: + args = tmp.read().split() else: args = sys.argv[1:] -with open(args[0], 'w') as fp, open(args[1], 'r') as ifp: - fp.write(ifp.read()) - fp.write('FILEFLAG=%%s\\n' %% args[2]) - fp.write('TIMESTAMP=%%s\\n' %% args[3]) + +with open(args[0], 'w') as ofp, open(args[1], 'r') as ifp: + ofp.write(ifp.read()) + ofp.write('FILEFLAG=%%s\\n' %% args[2]) + ofp.write('TIMESTAMP=%%s\\n' %% args[3]) """ % locals()) os.chmod(build_py, 0o755) @@ -56,21 +61,29 @@ test.write('SConstruct', """\ DefaultEnvironment(tools=[]) arg = 'a_long_ignored_argument' extra_arguments = arg -while len(extra_arguments) <= 1024: +MAXLINE=1024 +while len(extra_arguments) <= MAXLINE: extra_arguments = extra_arguments + ' ' + arg -env = Environment(tools=[], - FILECOM=[r'%(build_py)s', - '$TARGET', '$SOURCE', - '$FILEFLAG', - '$(', '$TIMESTAMP', '$)', - '$EXTRA_ARGUMENTS'], - FILEFLAG=ARGUMENTS.get('FILEFLAG'), - TIMESTAMP=ARGUMENTS.get('TIMESTAMP'), - EXTRA_ARGUMENTS=extra_arguments, - MAXLINELENGTH=1024) +env = Environment( + tools=[], + FILECOM=[ + r'%(build_py)s', + '$TARGET', + '$SOURCE', + '$FILEFLAG', + '$(', + '$TIMESTAMP', + '$)', + '$EXTRA_ARGUMENTS', + ], + FILEFLAG=ARGUMENTS.get('FILEFLAG'), + TIMESTAMP=ARGUMENTS.get('TIMESTAMP'), + EXTRA_ARGUMENTS=extra_arguments, + MAXLINELENGTH=MAXLINE, + TEMPFILEPREFIX='@', +) env.PrependENVPath('PATHEXT', '.PY') -env.Command('file.out', 'file.in', - '${TEMPFILE(FILECOM)}') +env.Command('file.out', 'file.in', r'%(_python_)s ${TEMPFILE(FILECOM)}') """ % locals()) test.write('file.in', "file.in\n", mode='w') diff --git a/test/rebuild-generated.py b/test/rebuild-generated.py index 6beba74..0b3659e 100644 --- a/test/rebuild-generated.py +++ b/test/rebuild-generated.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Test case for the bug report: @@ -52,13 +51,16 @@ This may be a duplicate to bug 1019683. import os import sys +import sysconfig + import TestSCons test = TestSCons.TestSCons() _obj = TestSCons._obj -if sys.platform == 'win32': +if sys.platform == 'win32' and not sysconfig.get_platform() in ("mingw",): + generator_name = 'generator.bat' test.write(generator_name, '@echo #include "header.hh"') kernel_action = "$SOURCES > $TARGET" @@ -67,28 +69,23 @@ else: test.write(generator_name, 'echo \'#include "header.hh"\'') kernel_action = "sh $SOURCES > $TARGET" -test.write('SConstruct', """\ - -env = Environment() - -kernelDefines = env.Command("header.hh", - "header.hh.in", - Copy('$TARGET', '$SOURCE')) +if sysconfig.get_platform() in ("mingw",): + # mingw Python uses a sep of '/', when Command fires, that will not work. + # use its altsep instead, that is the standard Windows separator. + sep = os.altsep +else: + sep = os.sep -kernelImporterSource = env.Command( - "generated.cc", ["%s"], - "%s") -kernelImporter = env.Program( - kernelImporterSource + ["main.cc"]) +test.write('SConstruct', """\ +env = Environment() -kernelImports = env.Command( - "KernelImport.hh", kernelImporter, - ".%s$SOURCE > $TARGET") - -osLinuxModule = env.StaticObject( - ["target.cc"]) -""" % (generator_name, kernel_action, os.sep)) +kernelDefines = env.Command("header.hh", "header.hh.in", Copy('$TARGET', '$SOURCE')) +kernelImporterSource = env.Command("generated.cc", ["%s"], "%s") +kernelImporter = env.Program(kernelImporterSource + ["main.cc"]) +kernelImports = env.Command("KernelImport.hh", kernelImporter, ".%s$SOURCE > $TARGET") +osLinuxModule = env.StaticObject(["target.cc"]) +""" % (generator_name, kernel_action, sep)) test.write('main.cc', """\ int diff --git a/test/scons-time/func/chdir.py b/test/scons-time/func/chdir.py index 1aea7ad..412a1c8 100644 --- a/test/scons-time/func/chdir.py +++ b/test/scons-time/func/chdir.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that the func -C and --chdir options change directory before @@ -52,7 +51,7 @@ for i in range(9): i = str(i) test.subdir(i) test.profile_data('profs/foo-%s.prof' % i, '%s/prof.py' % i, '_main', input) - s = r'\d.\d\d\d %s/prof\.py:1\(_main\)' % re.escape(test.workpath(i)) + s = r'\d.\d\d\d %s.prof\.py:1\(_main\)' % re.escape(test.workpath(i)) expect.append(s + '\n') expect = ''.join(expect) diff --git a/test/scons-time/func/funcglob.py b/test/scons-time/func/funcglob.py index 6240404..3fff746 100644 --- a/test/scons-time/func/funcglob.py +++ b/test/scons-time/func/funcglob.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that the func subcommands globs for files. @@ -46,7 +45,7 @@ expect = [] for i in range(9): test.subdir(str(i)) test.profile_data('foo-%s.prof' % i, '%s/prof.py' % i, '_main', input) - expect.append((r'\d.\d\d\d %s/prof\.py:1\(_main\)' + '\n') % i) + expect.append((r'\d.\d\d\d %s.prof\.py:1\(_main\)' + '\n') % i) expect = ''.join(expect) diff --git a/test/scons-time/func/tail.py b/test/scons-time/func/tail.py index afd3f83..64d041a 100644 --- a/test/scons-time/func/tail.py +++ b/test/scons-time/func/tail.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that the func subcommand only prints results for the last number @@ -47,7 +46,7 @@ expect = [] for i in range(9): test.subdir(str(i)) test.profile_data('foo-%s.prof' % i, '%s/prof.py' % i, '_main', input) - expect.append((r'\d.\d\d\d %s/prof\.py:1\(_main\)' + '\n') % i) + expect.append((r'\d.\d\d\d %s.prof\.py:1\(_main\)' + '\n') % i) test.run(arguments = 'func -t 3 foo-*.prof', stdout = ''.join(expect[-3:])) diff --git a/test/sconsign/script/SConsignFile.py b/test/sconsign/script/SConsignFile.py index 47fe94f..c54e17b 100644 --- a/test/sconsign/script/SConsignFile.py +++ b/test/sconsign/script/SConsignFile.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that the sconsign script works with files generated when @@ -99,15 +98,22 @@ sub2_inc2_h = 'sub2/inc2.h' test.write(['SConstruct'], """\ SConsignFile() -env1 = Environment(PROGSUFFIX = '.exe', - OBJSUFFIX = '.obj', - CCCOM = [[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], - LINKCOM = [[r'%(fake_link_py)s', '$TARGET', '$SOURCE']]) +env1 = Environment( + PROGSUFFIX='.exe', + OBJSUFFIX='.obj', + CCCOM=[[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], + LINKCOM=[[r'%(fake_link_py)s', '$TARGET', '$SOURCE']], +) env1.PrependENVPath('PATHEXT', '.PY') env1.Program('sub1/hello.c') -env2 = env1.Clone(CPPPATH = ['sub2']) +env2 = env1.Clone(CPPPATH=['sub2']) env2.Program('sub2/hello.c') """ % locals()) +# TODO in the above, we would normally want to run a python program +# using "our python" as in: +# CCCOM=[[r'%(_python_)s', r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], +# LINKCOM=[[r'%(_python_)s', r'%(fake_link_py)s', '$TARGET', '$SOURCE']], +# however we're looking at dependencies with sconsign, so that breaks things test.write(['sub1', 'hello.c'], r""" sub1/hello.c diff --git a/test/sconsign/script/Signatures.py b/test/sconsign/script/Signatures.py index 9583cc6..0f21496 100644 --- a/test/sconsign/script/Signatures.py +++ b/test/sconsign/script/Signatures.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -20,9 +22,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ Verify that the sconsign script works when using a .sconsign file in @@ -108,18 +107,25 @@ test.chmod(fake_link_py, 0o755) test.write('SConstruct', """ SConsignFile(None) Decider('timestamp-newer') -env1 = Environment(PROGSUFFIX = '.exe', - OBJSUFFIX = '.obj', - # Specify the command lines with lists-of-lists so - # finding the implicit dependencies works even with - # spaces in the fake_*_py path names. - CCCOM = [[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], - LINKCOM = [[r'%(fake_link_py)s', '$TARGET', '$SOURCE']]) +env1 = Environment( + PROGSUFFIX='.exe', + OBJSUFFIX='.obj', + # Specify the command lines with lists-of-lists so + # finding the implicit dependencies works even with + # spaces in the fake_*_py path names. + CCCOM=[[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], + LINKCOM=[[r'%(fake_link_py)s', '$TARGET', '$SOURCE']], +) env1.PrependENVPath('PATHEXT', '.PY') env1.Program('sub1/hello.c') -env2 = env1.Clone(CPPPATH = ['sub2']) +env2 = env1.Clone(CPPPATH=['sub2']) env2.Program('sub2/hello.c') """ % locals()) +# TODO in the above, we would normally want to run a python program +# using "our python" as in: +# CCCOM=[[r'%(_python_)s', r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], +# LINKCOM=[[r'%(_python_)s', r'%(fake_link_py)s', '$TARGET', '$SOURCE']], +# however we're looking at dependencies with sconsign, so that breaks things test.write(['sub1', 'hello.c'], r"""\ sub1/hello.c diff --git a/test/sconsign/script/no-SConsignFile.py b/test/sconsign/script/no-SConsignFile.py index 3702c6c..c345829 100644 --- a/test/sconsign/script/no-SConsignFile.py +++ b/test/sconsign/script/no-SConsignFile.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -# __COPYRIGHT__ +# MIT License +# +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -110,18 +112,25 @@ sub2_inc2_h = 'sub2/inc2.h' test.write(['SConstruct'], """ SConsignFile(None) -env1 = Environment(PROGSUFFIX = '.exe', - OBJSUFFIX = '.obj', - # Specify the command lines with lists-of-lists so - # finding the implicit dependencies works even with - # spaces in the fake_*_py path names. - CCCOM = [[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], - LINKCOM = [[r'%(fake_link_py)s', '$TARGET', '$SOURCE']]) +env1 = Environment( + PROGSUFFIX='.exe', + OBJSUFFIX='.obj', + # Specify the command lines with lists-of-lists so + # finding the implicit dependencies works even with + # spaces in the fake_*_py path names. + CCCOM=[[r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], + LINKCOM=[[r'%(fake_link_py)s', '$TARGET', '$SOURCE']], +) env1.PrependENVPath('PATHEXT', '.PY') env1.Program('sub1/hello.c') -env2 = env1.Clone(CPPPATH = ['sub2']) +env2 = env1.Clone(CPPPATH=['sub2']) env2.Program('sub2/hello.c') """ % locals()) +# TODO in the above, we would normally want to run a python program +# using "our python" as in: +# CCCOM=[[r'%(_python_)s', r'%(fake_cc_py)s', 'sub2', '$TARGET', '$SOURCE']], +# LINKCOM=[[r'%(_python_)s', r'%(fake_link_py)s', '$TARGET', '$SOURCE']], +# however we're looking at dependencies with sconsign, so that breaks things test.write(['sub1', 'hello.c'], r"""\ sub1/hello.c diff --git a/testing/framework/TestCommon.py b/testing/framework/TestCommon.py index b1630e5..2eeaad0 100644 --- a/testing/framework/TestCommon.py +++ b/testing/framework/TestCommon.py @@ -785,10 +785,6 @@ class TestCommon(TestCmd): sys.stdout.flush() pass_skips = os.environ.get('TESTCOMMON_PASS_SKIPS') if pass_skips in [None, 0, '0']: - # skip=1 means skip this function when showing where this - # result came from. They only care about the line where the - # script called test.skip_test(), not the line number where - # we call test.no_result(). if from_fw: self.no_result(skip=2) else: |