summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/SCons/scons-3.0.1/engine/SCons/Script')
-rw-r--r--3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Interactive.py376
-rw-r--r--3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Main.py1427
-rw-r--r--3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Main.xml818
-rw-r--r--3rdParty/SCons/scons-3.0.1/engine/SCons/Script/MainTests.py55
-rw-r--r--3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConsOptions.py988
-rw-r--r--3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscript.py640
-rw-r--r--3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscript.xml602
-rw-r--r--3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscriptTests.py34
-rw-r--r--3rdParty/SCons/scons-3.0.1/engine/SCons/Script/__init__.py429
9 files changed, 5369 insertions, 0 deletions
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Interactive.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Interactive.py
new file mode 100644
index 0000000..cc4f23c
--- /dev/null
+++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Interactive.py
@@ -0,0 +1,376 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+from __future__ import print_function
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+__doc__ = """
+SCons interactive mode
+"""
+
+# TODO:
+#
+# This has the potential to grow into something with a really big life
+# of its own, which might or might not be a good thing. Nevertheless,
+# here are some enhancements that will probably be requested some day
+# and are worth keeping in mind (assuming this takes off):
+#
+# - A command to re-read / re-load the SConscript files. This may
+# involve allowing people to specify command-line options (e.g. -f,
+# -I, --no-site-dir) that affect how the SConscript files are read.
+#
+# - Additional command-line options on the "build" command.
+#
+# Of the supported options that seemed to make sense (after a quick
+# pass through the list), the ones that seemed likely enough to be
+# used are listed in the man page and have explicit test scripts.
+#
+# These had code changed in Script/Main.py to support them, but didn't
+# seem likely to be used regularly, so had no test scripts added:
+#
+# build --diskcheck=*
+# build --implicit-cache=*
+# build --implicit-deps-changed=*
+# build --implicit-deps-unchanged=*
+#
+# These look like they should "just work" with no changes to the
+# existing code, but like those above, look unlikely to be used and
+# therefore had no test scripts added:
+#
+# build --random
+#
+# These I'm not sure about. They might be useful for individual
+# "build" commands, and may even work, but they seem unlikely enough
+# that we'll wait until they're requested before spending any time on
+# writing test scripts for them, or investigating whether they work.
+#
+# build -q [??? is there a useful analog to the exit status?]
+# build --duplicate=
+# build --profile=
+# build --max-drift=
+# build --warn=*
+# build --Y
+#
+# - Most of the SCons command-line options that the "build" command
+# supports should be settable as default options that apply to all
+# subsequent "build" commands. Maybe a "set {option}" command that
+# maps to "SetOption('{option}')".
+#
+# - Need something in the 'help' command that prints the -h output.
+#
+# - A command to run the configure subsystem separately (must see how
+# this interacts with the new automake model).
+#
+# - Command-line completion of target names; maybe even of SCons options?
+# Completion is something that's supported by the Python cmd module,
+# so this should be doable without too much trouble.
+#
+
+import cmd
+import copy
+import os
+import re
+import shlex
+import sys
+
+try:
+ import readline
+except ImportError:
+ pass
+
+class SConsInteractiveCmd(cmd.Cmd):
+ """\
+
+build [TARGETS] Build the specified TARGETS and their dependencies. 'b' is a synonym.
+clean [TARGETS] Clean (remove) the specified TARGETS and their dependencies. 'c' is a synonym.
+exit Exit SCons interactive mode.
+help [COMMAND] Prints help for the specified COMMAND. 'h' and '?' are synonyms.
+shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and '!' are synonyms.
+version Prints SCons version information.
+"""
+
+ synonyms = {
+ 'b' : 'build',
+ 'c' : 'clean',
+ 'h' : 'help',
+ 'scons' : 'build',
+ 'sh' : 'shell',
+ }
+
+ def __init__(self, **kw):
+ cmd.Cmd.__init__(self)
+ for key, val in kw.items():
+ setattr(self, key, val)
+
+ if sys.platform == 'win32':
+ self.shell_variable = 'COMSPEC'
+ else:
+ self.shell_variable = 'SHELL'
+
+ def default(self, argv):
+ print("*** Unknown command: %s" % argv[0])
+
+ def onecmd(self, line):
+ line = line.strip()
+ if not line:
+ print(self.lastcmd)
+ return self.emptyline()
+ self.lastcmd = line
+ if line[0] == '!':
+ line = 'shell ' + line[1:]
+ elif line[0] == '?':
+ line = 'help ' + line[1:]
+ if os.sep == '\\':
+ line = line.replace('\\', '\\\\')
+ argv = shlex.split(line)
+ argv[0] = self.synonyms.get(argv[0], argv[0])
+ if not argv[0]:
+ return self.default(line)
+ else:
+ try:
+ func = getattr(self, 'do_' + argv[0])
+ except AttributeError:
+ return self.default(argv)
+ return func(argv)
+
+ def do_build(self, argv):
+ """\
+ build [TARGETS] Build the specified TARGETS and their
+ dependencies. 'b' is a synonym.
+ """
+ import SCons.Node
+ import SCons.SConsign
+ import SCons.Script.Main
+
+ options = copy.deepcopy(self.options)
+
+ options, targets = self.parser.parse_args(argv[1:], values=options)
+
+ SCons.Script.COMMAND_LINE_TARGETS = targets
+
+ if targets:
+ SCons.Script.BUILD_TARGETS = targets
+ else:
+ # If the user didn't specify any targets on the command line,
+ # use the list of default targets.
+ SCons.Script.BUILD_TARGETS = SCons.Script._build_plus_default
+
+ nodes = SCons.Script.Main._build_targets(self.fs,
+ options,
+ targets,
+ self.target_top)
+
+ if not nodes:
+ return
+
+ # Call each of the Node's alter_targets() methods, which may
+ # provide additional targets that ended up as part of the build
+ # (the canonical example being a VariantDir() when we're building
+ # from a source directory) and which we therefore need their
+ # state cleared, too.
+ x = []
+ for n in nodes:
+ x.extend(n.alter_targets()[0])
+ nodes.extend(x)
+
+ # Clean up so that we can perform the next build correctly.
+ #
+ # We do this by walking over all the children of the targets,
+ # and clearing their state.
+ #
+ # We currently have to re-scan each node to find their
+ # children, because built nodes have already been partially
+ # cleared and don't remember their children. (In scons
+ # 0.96.1 and earlier, this wasn't the case, and we didn't
+ # have to re-scan the nodes.)
+ #
+ # Because we have to re-scan each node, we can't clear the
+ # nodes as we walk over them, because we may end up rescanning
+ # a cleared node as we scan a later node. Therefore, only
+ # store the list of nodes that need to be cleared as we walk
+ # the tree, and clear them in a separate pass.
+ #
+ # XXX: Someone more familiar with the inner workings of scons
+ # may be able to point out a more efficient way to do this.
+
+ SCons.Script.Main.progress_display("scons: Clearing cached node information ...")
+
+ seen_nodes = {}
+
+ def get_unseen_children(node, parent, seen_nodes=seen_nodes):
+ def is_unseen(node, seen_nodes=seen_nodes):
+ return node not in seen_nodes
+ return [child for child in node.children(scan=1) if is_unseen(child)]
+
+ def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes):
+ seen_nodes[node] = 1
+
+ # If this file is in a VariantDir and has a
+ # corresponding source file in the source tree, remember the
+ # node in the source tree, too. This is needed in
+ # particular to clear cached implicit dependencies on the
+ # source file, since the scanner will scan it if the
+ # VariantDir was created with duplicate=0.
+ try:
+ rfile_method = node.rfile
+ except AttributeError:
+ return
+ else:
+ rfile = rfile_method()
+ if rfile != node:
+ seen_nodes[rfile] = 1
+
+ for node in nodes:
+ walker = SCons.Node.Walker(node,
+ kids_func=get_unseen_children,
+ eval_func=add_to_seen_nodes)
+ n = walker.get_next()
+ while n:
+ n = walker.get_next()
+
+ for node in list(seen_nodes.keys()):
+ # Call node.clear() to clear most of the state
+ node.clear()
+ # node.clear() doesn't reset node.state, so call
+ # node.set_state() to reset it manually
+ node.set_state(SCons.Node.no_state)
+ node.implicit = None
+
+ # Debug: Uncomment to verify that all Taskmaster reference
+ # counts have been reset to zero.
+ #if node.ref_count != 0:
+ # from SCons.Debug import Trace
+ # Trace('node %s, ref_count %s !!!\n' % (node, node.ref_count))
+
+ SCons.SConsign.Reset()
+ SCons.Script.Main.progress_display("scons: done clearing node information.")
+
+ def do_clean(self, argv):
+ """\
+ clean [TARGETS] Clean (remove) the specified TARGETS
+ and their dependencies. 'c' is a synonym.
+ """
+ return self.do_build(['build', '--clean'] + argv[1:])
+
+ def do_EOF(self, argv):
+ print()
+ self.do_exit(argv)
+
+ def _do_one_help(self, arg):
+ try:
+ # If help_<arg>() exists, then call it.
+ func = getattr(self, 'help_' + arg)
+ except AttributeError:
+ try:
+ func = getattr(self, 'do_' + arg)
+ except AttributeError:
+ doc = None
+ else:
+ doc = self._doc_to_help(func)
+ if doc:
+ sys.stdout.write(doc + '\n')
+ sys.stdout.flush()
+ else:
+ doc = self.strip_initial_spaces(func())
+ if doc:
+ sys.stdout.write(doc + '\n')
+ sys.stdout.flush()
+
+ def _doc_to_help(self, obj):
+ doc = obj.__doc__
+ if doc is None:
+ return ''
+ return self._strip_initial_spaces(doc)
+
+ def _strip_initial_spaces(self, s):
+ lines = s.split('\n')
+ spaces = re.match(' *', lines[0]).group(0)
+ def strip_spaces(l, spaces=spaces):
+ if l[:len(spaces)] == spaces:
+ l = l[len(spaces):]
+ return l
+ lines = list(map(strip_spaces, lines))
+ return '\n'.join(lines)
+
+ def do_exit(self, argv):
+ """\
+ exit Exit SCons interactive mode.
+ """
+ sys.exit(0)
+
+ def do_help(self, argv):
+ """\
+ help [COMMAND] Prints help for the specified COMMAND. 'h'
+ and '?' are synonyms.
+ """
+ if argv[1:]:
+ for arg in argv[1:]:
+ if self._do_one_help(arg):
+ break
+ else:
+ # If bare 'help' is called, print this class's doc
+ # string (if it has one).
+ doc = self._doc_to_help(self.__class__)
+ if doc:
+ sys.stdout.write(doc + '\n')
+ sys.stdout.flush()
+
+ def do_shell(self, argv):
+ """\
+ shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and
+ '!' are synonyms.
+ """
+ import subprocess
+ argv = argv[1:]
+ if not argv:
+ argv = os.environ[self.shell_variable]
+ try:
+ # Per "[Python-Dev] subprocess insufficiently platform-independent?"
+ # http://mail.python.org/pipermail/python-dev/2008-August/081979.html "+
+ # Doing the right thing with an argument list currently
+ # requires different shell= values on Windows and Linux.
+ p = subprocess.Popen(argv, shell=(sys.platform=='win32'))
+ except EnvironmentError as e:
+ sys.stderr.write('scons: %s: %s\n' % (argv[0], e.strerror))
+ else:
+ p.wait()
+
+ def do_version(self, argv):
+ """\
+ version Prints SCons version information.
+ """
+ sys.stdout.write(self.parser.version + '\n')
+
+def interact(fs, parser, options, targets, target_top):
+ c = SConsInteractiveCmd(prompt = 'scons>>> ',
+ fs = fs,
+ parser = parser,
+ options = options,
+ targets = targets,
+ target_top = target_top)
+ c.cmdloop()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Main.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Main.py
new file mode 100644
index 0000000..c810634
--- /dev/null
+++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Main.py
@@ -0,0 +1,1427 @@
+"""SCons.Script
+
+This file implements the main() function used by the scons script.
+
+Architecturally, this *is* the scons script, and will likely only be
+called from the external "scons" wrapper. Consequently, anything here
+should not be, or be considered, part of the build engine. If it's
+something that we expect other software to want to use, it should go in
+some other module. If it's specific to the "scons" script invocation,
+it goes here.
+"""
+
+from __future__ import print_function
+
+
+unsupported_python_version = (2, 6, 0)
+deprecated_python_version = (2, 7, 0)
+
+
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+
+import SCons.compat
+
+import os
+import sys
+import time
+import traceback
+import sysconfig
+
+import SCons.CacheDir
+import SCons.Debug
+import SCons.Defaults
+import SCons.Environment
+import SCons.Errors
+import SCons.Job
+import SCons.Node
+import SCons.Node.FS
+import SCons.Platform
+import SCons.SConf
+import SCons.Script
+import SCons.Taskmaster
+import SCons.Util
+import SCons.Warnings
+
+import SCons.Script.Interactive
+
+
+def fetch_win32_parallel_msg():
+ # A subsidiary function that exists solely to isolate this import
+ # so we don't have to pull it in on all platforms, and so that an
+ # in-line "import" statement in the _main() function below doesn't
+ # cause warnings about local names shadowing use of the 'SCons'
+ # global in nest scopes and UnboundLocalErrors and the like in some
+ # versions (2.1) of Python.
+ import SCons.Platform.win32
+ return SCons.Platform.win32.parallel_msg
+
+
+def revert_io():
+ # This call is added to revert stderr and stdout to the original
+ # ones just in case some build rule or something else in the system
+ # has redirected them elsewhere.
+ sys.stderr = sys.__stderr__
+ sys.stdout = sys.__stdout__
+
+class SConsPrintHelpException(Exception):
+ pass
+
+display = SCons.Util.display
+progress_display = SCons.Util.DisplayEngine()
+
+first_command_start = None
+last_command_end = None
+
+
+class Progressor(object):
+ prev = ''
+ count = 0
+ target_string = '$TARGET'
+
+ def __init__(self, obj, interval=1, file=None, overwrite=False):
+ if file is None:
+ file = sys.stdout
+
+ self.obj = obj
+ self.file = file
+ self.interval = interval
+ self.overwrite = overwrite
+
+ if callable(obj):
+ self.func = obj
+ elif SCons.Util.is_List(obj):
+ self.func = self.spinner
+ elif obj.find(self.target_string) != -1:
+ self.func = self.replace_string
+ else:
+ self.func = self.string
+
+ def write(self, s):
+ self.file.write(s)
+ self.file.flush()
+ self.prev = s
+
+ def erase_previous(self):
+ if self.prev:
+ length = len(self.prev)
+ if self.prev[-1] in ('\n', '\r'):
+ length = length - 1
+ self.write(' ' * length + '\r')
+ self.prev = ''
+
+ def spinner(self, node):
+ self.write(self.obj[self.count % len(self.obj)])
+
+ def string(self, node):
+ self.write(self.obj)
+
+ def replace_string(self, node):
+ self.write(self.obj.replace(self.target_string, str(node)))
+
+ def __call__(self, node):
+ self.count = self.count + 1
+ if (self.count % self.interval) == 0:
+ if self.overwrite:
+ self.erase_previous()
+ self.func(node)
+
+ProgressObject = SCons.Util.Null()
+
+def Progress(*args, **kw):
+ global ProgressObject
+ ProgressObject = Progressor(*args, **kw)
+
+# Task control.
+#
+
+_BuildFailures = []
+
+
+def GetBuildFailures():
+ return _BuildFailures
+
+
+class BuildTask(SCons.Taskmaster.OutOfDateTask):
+ """An SCons build task."""
+ progress = ProgressObject
+
+ def display(self, message):
+ display('scons: ' + message)
+
+ def prepare(self):
+ self.progress(self.targets[0])
+ return SCons.Taskmaster.OutOfDateTask.prepare(self)
+
+ def needs_execute(self):
+ if SCons.Taskmaster.OutOfDateTask.needs_execute(self):
+ return True
+ if self.top and self.targets[0].has_builder():
+ display("scons: `%s' is up to date." % str(self.node))
+ return False
+
+ def execute(self):
+ if print_time:
+ start_time = time.time()
+ global first_command_start
+ if first_command_start is None:
+ first_command_start = start_time
+ SCons.Taskmaster.OutOfDateTask.execute(self)
+ if print_time:
+ global cumulative_command_time
+ global last_command_end
+ finish_time = time.time()
+ last_command_end = finish_time
+ cumulative_command_time = cumulative_command_time+finish_time-start_time
+ sys.stdout.write("Command execution time: %s: %f seconds\n"%(str(self.node), finish_time-start_time))
+
+ def do_failed(self, status=2):
+ _BuildFailures.append(self.exception[1])
+ global exit_status
+ global this_build_status
+ if self.options.ignore_errors:
+ SCons.Taskmaster.OutOfDateTask.executed(self)
+ elif self.options.keep_going:
+ SCons.Taskmaster.OutOfDateTask.fail_continue(self)
+ exit_status = status
+ this_build_status = status
+ else:
+ SCons.Taskmaster.OutOfDateTask.fail_stop(self)
+ exit_status = status
+ this_build_status = status
+
+ def executed(self):
+ t = self.targets[0]
+ if self.top and not t.has_builder() and not t.side_effect:
+ if not t.exists():
+ if t.__class__.__name__ in ('File', 'Dir', 'Entry'):
+ errstr="Do not know how to make %s target `%s' (%s)." % (t.__class__.__name__, t, t.get_abspath())
+ else: # Alias or Python or ...
+ errstr="Do not know how to make %s target `%s'." % (t.__class__.__name__, t)
+ sys.stderr.write("scons: *** " + errstr)
+ if not self.options.keep_going:
+ sys.stderr.write(" Stop.")
+ sys.stderr.write("\n")
+ try:
+ raise SCons.Errors.BuildError(t, errstr)
+ except KeyboardInterrupt:
+ raise
+ except:
+ self.exception_set()
+ self.do_failed()
+ else:
+ print("scons: Nothing to be done for `%s'." % t)
+ SCons.Taskmaster.OutOfDateTask.executed(self)
+ else:
+ SCons.Taskmaster.OutOfDateTask.executed(self)
+
+ def failed(self):
+ # Handle the failure of a build task. The primary purpose here
+ # is to display the various types of Errors and Exceptions
+ # appropriately.
+ exc_info = self.exc_info()
+ try:
+ t, e, tb = exc_info
+ except ValueError:
+ t, e = exc_info
+ tb = None
+
+ if t is None:
+ # The Taskmaster didn't record an exception for this Task;
+ # see if the sys module has one.
+ try:
+ t, e, tb = sys.exc_info()[:]
+ except ValueError:
+ t, e = exc_info
+ tb = None
+
+ # Deprecated string exceptions will have their string stored
+ # in the first entry of the tuple.
+ if e is None:
+ e = t
+
+ buildError = SCons.Errors.convert_to_BuildError(e)
+ if not buildError.node:
+ buildError.node = self.node
+
+ node = buildError.node
+ if not SCons.Util.is_List(node):
+ node = [ node ]
+ nodename = ', '.join(map(str, node))
+
+ errfmt = "scons: *** [%s] %s\n"
+ sys.stderr.write(errfmt % (nodename, buildError))
+
+ if (buildError.exc_info[2] and buildError.exc_info[1] and
+ not isinstance(
+ buildError.exc_info[1],
+ (EnvironmentError, SCons.Errors.StopError,
+ SCons.Errors.UserError))):
+ type, value, trace = buildError.exc_info
+ if tb and print_stacktrace:
+ sys.stderr.write("scons: internal stack trace:\n")
+ traceback.print_tb(tb, file=sys.stderr)
+ traceback.print_exception(type, value, trace)
+ elif tb and print_stacktrace:
+ sys.stderr.write("scons: internal stack trace:\n")
+ traceback.print_tb(tb, file=sys.stderr)
+
+ self.exception = (e, buildError, tb) # type, value, traceback
+ self.do_failed(buildError.exitstatus)
+
+ self.exc_clear()
+
+ def postprocess(self):
+ if self.top:
+ t = self.targets[0]
+ for tp in self.options.tree_printers:
+ tp.display(t)
+ if self.options.debug_includes:
+ tree = t.render_include_tree()
+ if tree:
+ print()
+ print(tree)
+ SCons.Taskmaster.OutOfDateTask.postprocess(self)
+
+ def make_ready(self):
+ """Make a task ready for execution"""
+ SCons.Taskmaster.OutOfDateTask.make_ready(self)
+ if self.out_of_date and self.options.debug_explain:
+ explanation = self.out_of_date[0].explain()
+ if explanation:
+ sys.stdout.write("scons: " + explanation)
+
+
+class CleanTask(SCons.Taskmaster.AlwaysTask):
+ """An SCons clean task."""
+ def fs_delete(self, path, pathstr, remove=True):
+ try:
+ if os.path.lexists(path):
+ if os.path.isfile(path) or os.path.islink(path):
+ if remove: os.unlink(path)
+ display("Removed " + pathstr)
+ elif os.path.isdir(path) and not os.path.islink(path):
+ # delete everything in the dir
+ for e in sorted(os.listdir(path)):
+ p = os.path.join(path, e)
+ s = os.path.join(pathstr, e)
+ if os.path.isfile(p):
+ if remove: os.unlink(p)
+ display("Removed " + s)
+ else:
+ self.fs_delete(p, s, remove)
+ # then delete dir itself
+ if remove: os.rmdir(path)
+ display("Removed directory " + pathstr)
+ else:
+ errstr = "Path '%s' exists but isn't a file or directory."
+ raise SCons.Errors.UserError(errstr % (pathstr))
+ except SCons.Errors.UserError as e:
+ print(e)
+ except (IOError, OSError) as e:
+ print("scons: Could not remove '%s':" % pathstr, e.strerror)
+
+ def _get_files_to_clean(self):
+ result = []
+ target = self.targets[0]
+ if target.has_builder() or target.side_effect:
+ result = [t for t in self.targets if not t.noclean]
+ return result
+
+ def _clean_targets(self, remove=True):
+ target = self.targets[0]
+ if target in SCons.Environment.CleanTargets:
+ files = SCons.Environment.CleanTargets[target]
+ for f in files:
+ self.fs_delete(f.get_abspath(), str(f), remove)
+
+ def show(self):
+ for t in self._get_files_to_clean():
+ if not t.isdir():
+ display("Removed " + str(t))
+ self._clean_targets(remove=False)
+
+ def remove(self):
+ for t in self._get_files_to_clean():
+ try:
+ removed = t.remove()
+ except OSError as e:
+ # An OSError may indicate something like a permissions
+ # issue, an IOError would indicate something like
+ # the file not existing. In either case, print a
+ # message and keep going to try to remove as many
+ # targets as possible.
+ print("scons: Could not remove '{0}'".format(str(t)), e.strerror)
+ else:
+ if removed:
+ display("Removed " + str(t))
+ self._clean_targets(remove=True)
+
+ execute = remove
+
+ # We want the Taskmaster to update the Node states (and therefore
+ # handle reference counts, etc.), but we don't want to call
+ # back to the Node's post-build methods, which would do things
+ # we don't want, like store .sconsign information.
+ executed = SCons.Taskmaster.Task.executed_without_callbacks
+
+ # Have the Taskmaster arrange to "execute" all of the targets, because
+ # we'll figure out ourselves (in remove() or show() above) whether
+ # anything really needs to be done.
+ make_ready = SCons.Taskmaster.Task.make_ready_all
+
+ def prepare(self):
+ pass
+
+class QuestionTask(SCons.Taskmaster.AlwaysTask):
+ """An SCons task for the -q (question) option."""
+ def prepare(self):
+ pass
+
+ def execute(self):
+ if self.targets[0].get_state() != SCons.Node.up_to_date or \
+ (self.top and not self.targets[0].exists()):
+ global exit_status
+ global this_build_status
+ exit_status = 1
+ this_build_status = 1
+ self.tm.stop()
+
+ def executed(self):
+ pass
+
+
+class TreePrinter(object):
+ def __init__(self, derived=False, prune=False, status=False):
+ self.derived = derived
+ self.prune = prune
+ self.status = status
+ def get_all_children(self, node):
+ return node.all_children()
+ def get_derived_children(self, node):
+ children = node.all_children(None)
+ return [x for x in children if x.has_builder()]
+ def display(self, t):
+ if self.derived:
+ func = self.get_derived_children
+ else:
+ func = self.get_all_children
+ s = self.status and 2 or 0
+ SCons.Util.print_tree(t, func, prune=self.prune, showtags=s)
+
+
+def python_version_string():
+ return sys.version.split()[0]
+
+def python_version_unsupported(version=sys.version_info):
+ return version < unsupported_python_version
+
+def python_version_deprecated(version=sys.version_info):
+ return version < deprecated_python_version
+
+
+# Global variables
+
+print_objects = 0
+print_memoizer = 0
+print_stacktrace = 0
+print_time = 0
+sconscript_time = 0
+cumulative_command_time = 0
+exit_status = 0 # final exit status, assume success by default
+this_build_status = 0 # "exit status" of an individual build
+num_jobs = None
+delayed_warnings = []
+
+class FakeOptionParser(object):
+ """
+ A do-nothing option parser, used for the initial OptionsParser variable.
+
+ During normal SCons operation, the OptionsParser is created right
+ away by the main() function. Certain tests scripts however, can
+ introspect on different Tool modules, the initialization of which
+ can try to add a new, local option to an otherwise uninitialized
+ OptionsParser object. This allows that introspection to happen
+ without blowing up.
+
+ """
+ class FakeOptionValues(object):
+ def __getattr__(self, attr):
+ return None
+ values = FakeOptionValues()
+ def add_local_option(self, *args, **kw):
+ pass
+
+OptionsParser = FakeOptionParser()
+
+def AddOption(*args, **kw):
+ if 'default' not in kw:
+ kw['default'] = None
+ result = OptionsParser.add_local_option(*args, **kw)
+ return result
+
+def GetOption(name):
+ return getattr(OptionsParser.values, name)
+
+def SetOption(name, value):
+ return OptionsParser.values.set_option(name, value)
+
+def PrintHelp(file=None):
+ OptionsParser.print_help(file=file)
+
+class Stats(object):
+ def __init__(self):
+ self.stats = []
+ self.labels = []
+ self.append = self.do_nothing
+ self.print_stats = self.do_nothing
+ def enable(self, outfp):
+ self.outfp = outfp
+ self.append = self.do_append
+ self.print_stats = self.do_print
+ def do_nothing(self, *args, **kw):
+ pass
+
+class CountStats(Stats):
+ def do_append(self, label):
+ self.labels.append(label)
+ self.stats.append(SCons.Debug.fetchLoggedInstances())
+ def do_print(self):
+ stats_table = {}
+ for s in self.stats:
+ for n in [t[0] for t in s]:
+ stats_table[n] = [0, 0, 0, 0]
+ i = 0
+ for s in self.stats:
+ for n, c in s:
+ stats_table[n][i] = c
+ i = i + 1
+ self.outfp.write("Object counts:\n")
+ pre = [" "]
+ post = [" %s\n"]
+ l = len(self.stats)
+ fmt1 = ''.join(pre + [' %7s']*l + post)
+ fmt2 = ''.join(pre + [' %7d']*l + post)
+ labels = self.labels[:l]
+ labels.append(("", "Class"))
+ self.outfp.write(fmt1 % tuple([x[0] for x in labels]))
+ self.outfp.write(fmt1 % tuple([x[1] for x in labels]))
+ for k in sorted(stats_table.keys()):
+ r = stats_table[k][:l] + [k]
+ self.outfp.write(fmt2 % tuple(r))
+
+count_stats = CountStats()
+
+class MemStats(Stats):
+ def do_append(self, label):
+ self.labels.append(label)
+ self.stats.append(SCons.Debug.memory())
+ def do_print(self):
+ fmt = 'Memory %-32s %12d\n'
+ for label, stats in zip(self.labels, self.stats):
+ self.outfp.write(fmt % (label, stats))
+
+memory_stats = MemStats()
+
+# utility functions
+
+def _scons_syntax_error(e):
+ """Handle syntax errors. Print out a message and show where the error
+ occurred.
+ """
+ etype, value, tb = sys.exc_info()
+ lines = traceback.format_exception_only(etype, value)
+ for line in lines:
+ sys.stderr.write(line+'\n')
+ sys.exit(2)
+
+def find_deepest_user_frame(tb):
+ """
+ Find the deepest stack frame that is not part of SCons.
+
+ Input is a "pre-processed" stack trace in the form
+ returned by traceback.extract_tb() or traceback.extract_stack()
+ """
+
+ tb.reverse()
+
+ # find the deepest traceback frame that is not part
+ # of SCons:
+ for frame in tb:
+ filename = frame[0]
+ if filename.find(os.sep+'SCons'+os.sep) == -1:
+ return frame
+ return tb[0]
+
+def _scons_user_error(e):
+ """Handle user errors. Print out a message and a description of the
+ error, along with the line number and routine where it occured.
+ The file and line number will be the deepest stack frame that is
+ not part of SCons itself.
+ """
+ global print_stacktrace
+ etype, value, tb = sys.exc_info()
+ if print_stacktrace:
+ traceback.print_exception(etype, value, tb)
+ filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_tb(tb))
+ sys.stderr.write("\nscons: *** %s\n" % value)
+ sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine))
+ sys.exit(2)
+
+def _scons_user_warning(e):
+ """Handle user warnings. Print out a message and a description of
+ the warning, along with the line number and routine where it occured.
+ The file and line number will be the deepest stack frame that is
+ not part of SCons itself.
+ """
+ etype, value, tb = sys.exc_info()
+ filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_tb(tb))
+ sys.stderr.write("\nscons: warning: %s\n" % e)
+ sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine))
+
+def _scons_internal_warning(e):
+ """Slightly different from _scons_user_warning in that we use the
+ *current call stack* rather than sys.exc_info() to get our stack trace.
+ This is used by the warnings framework to print warnings."""
+ filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_stack())
+ sys.stderr.write("\nscons: warning: %s\n" % e.args[0])
+ sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine))
+
+def _scons_internal_error():
+ """Handle all errors but user errors. Print out a message telling
+ the user what to do in this case and print a normal trace.
+ """
+ print('internal error')
+ traceback.print_exc()
+ sys.exit(2)
+
+def _SConstruct_exists(dirname='', repositories=[], filelist=None):
+ """This function checks that an SConstruct file exists in a directory.
+ If so, it returns the path of the file. By default, it checks the
+ current directory.
+ """
+ if not filelist:
+ filelist = ['SConstruct', 'Sconstruct', 'sconstruct']
+ for file in filelist:
+ sfile = os.path.join(dirname, file)
+ if os.path.isfile(sfile):
+ return sfile
+ if not os.path.isabs(sfile):
+ for rep in repositories:
+ if os.path.isfile(os.path.join(rep, sfile)):
+ return sfile
+ return None
+
+def _set_debug_values(options):
+ global print_memoizer, print_objects, print_stacktrace, print_time
+
+ debug_values = options.debug
+
+ if "count" in debug_values:
+ # All of the object counts are within "if track_instances:" blocks,
+ # which get stripped when running optimized (with python -O or
+ # from compiled *.pyo files). Provide a warning if __debug__ is
+ # stripped, so it doesn't just look like --debug=count is broken.
+ enable_count = False
+ if __debug__: enable_count = True
+ if enable_count:
+ count_stats.enable(sys.stdout)
+ SCons.Debug.track_instances = True
+ else:
+ msg = "--debug=count is not supported when running SCons\n" + \
+ "\twith the python -O option or optimized (.pyo) modules."
+ SCons.Warnings.warn(SCons.Warnings.NoObjectCountWarning, msg)
+ if "dtree" in debug_values:
+ options.tree_printers.append(TreePrinter(derived=True))
+ options.debug_explain = ("explain" in debug_values)
+ if "findlibs" in debug_values:
+ SCons.Scanner.Prog.print_find_libs = "findlibs"
+ options.debug_includes = ("includes" in debug_values)
+ print_memoizer = ("memoizer" in debug_values)
+ if "memory" in debug_values:
+ memory_stats.enable(sys.stdout)
+ print_objects = ("objects" in debug_values)
+ if print_objects:
+ SCons.Debug.track_instances = True
+ if "presub" in debug_values:
+ SCons.Action.print_actions_presub = 1
+ if "stacktrace" in debug_values:
+ print_stacktrace = 1
+ if "stree" in debug_values:
+ options.tree_printers.append(TreePrinter(status=True))
+ if "time" in debug_values:
+ print_time = 1
+ if "tree" in debug_values:
+ options.tree_printers.append(TreePrinter())
+ if "prepare" in debug_values:
+ SCons.Taskmaster.print_prepare = 1
+ if "duplicate" in debug_values:
+ SCons.Node.print_duplicate = 1
+
+def _create_path(plist):
+ path = '.'
+ for d in plist:
+ if os.path.isabs(d):
+ path = d
+ else:
+ path = path + '/' + d
+ return path
+
+def _load_site_scons_dir(topdir, site_dir_name=None):
+ """Load the site_scons dir under topdir.
+ Prepends site_scons to sys.path, imports site_scons/site_init.py,
+ and prepends site_scons/site_tools to default toolpath."""
+ if site_dir_name:
+ err_if_not_found = True # user specified: err if missing
+ else:
+ site_dir_name = "site_scons"
+ err_if_not_found = False
+
+ site_dir = os.path.join(topdir, site_dir_name)
+ if not os.path.exists(site_dir):
+ if err_if_not_found:
+ raise SCons.Errors.UserError("site dir %s not found."%site_dir)
+ return
+
+ site_init_filename = "site_init.py"
+ site_init_modname = "site_init"
+ site_tools_dirname = "site_tools"
+ # prepend to sys.path
+ sys.path = [os.path.abspath(site_dir)] + sys.path
+ site_init_file = os.path.join(site_dir, site_init_filename)
+ site_tools_dir = os.path.join(site_dir, site_tools_dirname)
+ if os.path.exists(site_init_file):
+ import imp, re
+ try:
+ try:
+ fp, pathname, description = imp.find_module(site_init_modname,
+ [site_dir])
+ # Load the file into SCons.Script namespace. This is
+ # opaque and clever; m is the module object for the
+ # SCons.Script module, and the exec ... in call executes a
+ # file (or string containing code) in the context of the
+ # module's dictionary, so anything that code defines ends
+ # up adding to that module. This is really short, but all
+ # the error checking makes it longer.
+ try:
+ m = sys.modules['SCons.Script']
+ except Exception as e:
+ fmt = 'cannot import site_init.py: missing SCons.Script module %s'
+ raise SCons.Errors.InternalError(fmt % repr(e))
+ try:
+ sfx = description[0]
+ modname = os.path.basename(pathname)[:-len(sfx)]
+ site_m = {"__file__": pathname, "__name__": modname, "__doc__": None}
+ re_special = re.compile("__[^_]+__")
+ for k in list(m.__dict__.keys()):
+ if not re_special.match(k):
+ site_m[k] = m.__dict__[k]
+
+ # This is the magic.
+ exec(compile(fp.read(), fp.name, 'exec'), site_m)
+ except KeyboardInterrupt:
+ raise
+ except Exception as e:
+ fmt = '*** Error loading site_init file %s:\n'
+ sys.stderr.write(fmt % repr(site_init_file))
+ raise
+ else:
+ for k in site_m:
+ if not re_special.match(k):
+ m.__dict__[k] = site_m[k]
+ except KeyboardInterrupt:
+ raise
+ except ImportError as e:
+ fmt = '*** cannot import site init file %s:\n'
+ sys.stderr.write(fmt % repr(site_init_file))
+ raise
+ finally:
+ if fp:
+ fp.close()
+ if os.path.exists(site_tools_dir):
+ # prepend to DefaultToolpath
+ SCons.Tool.DefaultToolpath.insert(0, os.path.abspath(site_tools_dir))
+
+def _load_all_site_scons_dirs(topdir, verbose=None):
+ """Load all of the predefined site_scons dir.
+ Order is significant; we load them in order from most generic
+ (machine-wide) to most specific (topdir).
+ The verbose argument is only for testing.
+ """
+ platform = SCons.Platform.platform_default()
+
+ def homedir(d):
+ return os.path.expanduser('~/'+d)
+
+ if platform == 'win32' or platform == 'cygwin':
+ # Note we use $ here instead of %...% because older
+ # pythons (prior to 2.6?) didn't expand %...% on Windows.
+ # This set of dirs should work on XP, Vista, 7 and later.
+ sysdirs=[
+ os.path.expandvars('$ALLUSERSPROFILE\\Application Data\\scons'),
+ os.path.expandvars('$USERPROFILE\\Local Settings\\Application Data\\scons')]
+ appdatadir = os.path.expandvars('$APPDATA\\scons')
+ if appdatadir not in sysdirs:
+ sysdirs.append(appdatadir)
+ sysdirs.append(homedir('.scons'))
+
+ elif platform == 'darwin': # MacOS X
+ sysdirs=['/Library/Application Support/SCons',
+ '/opt/local/share/scons', # (for MacPorts)
+ '/sw/share/scons', # (for Fink)
+ homedir('Library/Application Support/SCons'),
+ homedir('.scons')]
+ elif platform == 'sunos': # Solaris
+ sysdirs=['/opt/sfw/scons',
+ '/usr/share/scons',
+ homedir('.scons')]
+ else: # Linux, HPUX, etc.
+ # assume posix-like, i.e. platform == 'posix'
+ sysdirs=['/usr/share/scons',
+ homedir('.scons')]
+
+ dirs=sysdirs + [topdir]
+ for d in dirs:
+ if verbose: # this is used by unit tests.
+ print("Loading site dir ", d)
+ _load_site_scons_dir(d)
+
+def test_load_all_site_scons_dirs(d):
+ _load_all_site_scons_dirs(d, True)
+
+def version_string(label, module):
+ version = module.__version__
+ build = module.__build__
+ if build:
+ if build[0] != '.':
+ build = '.' + build
+ version = version + build
+ fmt = "\t%s: v%s, %s, by %s on %s\n"
+ return fmt % (label,
+ version,
+ module.__date__,
+ module.__developer__,
+ module.__buildsys__)
+
+def path_string(label, module):
+ path = module.__path__
+ return "\t%s path: %s\n"%(label,path)
+
+def _main(parser):
+ global exit_status
+ global this_build_status
+
+ options = parser.values
+
+ # Here's where everything really happens.
+
+ # First order of business: set up default warnings and then
+ # handle the user's warning options, so that we can issue (or
+ # suppress) appropriate warnings about anything that might happen,
+ # as configured by the user.
+
+ default_warnings = [ SCons.Warnings.WarningOnByDefault,
+ SCons.Warnings.DeprecatedWarning,
+ ]
+
+ for warning in default_warnings:
+ SCons.Warnings.enableWarningClass(warning)
+ SCons.Warnings._warningOut = _scons_internal_warning
+ SCons.Warnings.process_warn_strings(options.warn)
+
+ # Now that we have the warnings configuration set up, we can actually
+ # issue (or suppress) any warnings about warning-worthy things that
+ # occurred while the command-line options were getting parsed.
+ try:
+ dw = options.delayed_warnings
+ except AttributeError:
+ pass
+ else:
+ delayed_warnings.extend(dw)
+ for warning_type, message in delayed_warnings:
+ SCons.Warnings.warn(warning_type, message)
+
+ if options.diskcheck:
+ SCons.Node.FS.set_diskcheck(options.diskcheck)
+
+ # Next, we want to create the FS object that represents the outside
+ # world's file system, as that's central to a lot of initialization.
+ # To do this, however, we need to be in the directory from which we
+ # want to start everything, which means first handling any relevant
+ # options that might cause us to chdir somewhere (-C, -D, -U, -u).
+ if options.directory:
+ script_dir = os.path.abspath(_create_path(options.directory))
+ else:
+ script_dir = os.getcwd()
+
+ target_top = None
+ if options.climb_up:
+ target_top = '.' # directory to prepend to targets
+ while script_dir and not _SConstruct_exists(script_dir,
+ options.repository,
+ options.file):
+ script_dir, last_part = os.path.split(script_dir)
+ if last_part:
+ target_top = os.path.join(last_part, target_top)
+ else:
+ script_dir = ''
+
+ if script_dir and script_dir != os.getcwd():
+ if not options.silent:
+ display("scons: Entering directory `%s'" % script_dir)
+ try:
+ os.chdir(script_dir)
+ except OSError:
+ sys.stderr.write("Could not change directory to %s\n" % script_dir)
+
+ # Now that we're in the top-level SConstruct directory, go ahead
+ # and initialize the FS object that represents the file system,
+ # and make it the build engine default.
+ fs = SCons.Node.FS.get_default_fs()
+
+ for rep in options.repository:
+ fs.Repository(rep)
+
+ # Now that we have the FS object, the next order of business is to
+ # check for an SConstruct file (or other specified config file).
+ # If there isn't one, we can bail before doing any more work.
+ scripts = []
+ if options.file:
+ scripts.extend(options.file)
+ if not scripts:
+ sfile = _SConstruct_exists(repositories=options.repository,
+ filelist=options.file)
+ if sfile:
+ scripts.append(sfile)
+
+ if not scripts:
+ if options.help:
+ # There's no SConstruct, but they specified -h.
+ # Give them the options usage now, before we fail
+ # trying to read a non-existent SConstruct file.
+ raise SConsPrintHelpException
+ raise SCons.Errors.UserError("No SConstruct file found.")
+
+ if scripts[0] == "-":
+ d = fs.getcwd()
+ else:
+ d = fs.File(scripts[0]).dir
+ fs.set_SConstruct_dir(d)
+
+ _set_debug_values(options)
+ SCons.Node.implicit_cache = options.implicit_cache
+ SCons.Node.implicit_deps_changed = options.implicit_deps_changed
+ SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged
+
+ if options.no_exec:
+ SCons.SConf.dryrun = 1
+ SCons.Action.execute_actions = None
+ if options.question:
+ SCons.SConf.dryrun = 1
+ if options.clean:
+ SCons.SConf.SetBuildType('clean')
+ if options.help:
+ SCons.SConf.SetBuildType('help')
+ SCons.SConf.SetCacheMode(options.config)
+ SCons.SConf.SetProgressDisplay(progress_display)
+
+ if options.no_progress or options.silent:
+ progress_display.set_mode(0)
+
+ if options.site_dir:
+ _load_site_scons_dir(d.get_internal_path(), options.site_dir)
+ elif not options.no_site_dir:
+ _load_all_site_scons_dirs(d.get_internal_path())
+
+ if options.include_dir:
+ sys.path = options.include_dir + sys.path
+
+ # If we're about to start SCons in the interactive mode,
+ # inform the FS about this right here. Else, the release_target_info
+ # method could get called on some nodes, like the used "gcc" compiler,
+ # when using the Configure methods within the SConscripts.
+ # This would then cause subtle bugs, as already happened in #2971.
+ if options.interactive:
+ SCons.Node.interactive = True
+
+ # That should cover (most of) the options. Next, set up the variables
+ # that hold command-line arguments, so the SConscript files that we
+ # read and execute have access to them.
+ targets = []
+ xmit_args = []
+ for a in parser.largs:
+ if a[:1] == '-':
+ continue
+ if '=' in a:
+ xmit_args.append(a)
+ else:
+ targets.append(a)
+ SCons.Script._Add_Targets(targets + parser.rargs)
+ SCons.Script._Add_Arguments(xmit_args)
+
+ # If stdout is not a tty, replace it with a wrapper object to call flush
+ # after every write.
+ #
+ # Tty devices automatically flush after every newline, so the replacement
+ # isn't necessary. Furthermore, if we replace sys.stdout, the readline
+ # module will no longer work. This affects the behavior during
+ # --interactive mode. --interactive should only be used when stdin and
+ # stdout refer to a tty.
+ if not hasattr(sys.stdout, 'isatty') or not sys.stdout.isatty():
+ sys.stdout = SCons.Util.Unbuffered(sys.stdout)
+ if not hasattr(sys.stderr, 'isatty') or not sys.stderr.isatty():
+ sys.stderr = SCons.Util.Unbuffered(sys.stderr)
+
+ memory_stats.append('before reading SConscript files:')
+ count_stats.append(('pre-', 'read'))
+
+ # And here's where we (finally) read the SConscript files.
+
+ progress_display("scons: Reading SConscript files ...")
+
+ start_time = time.time()
+ try:
+ for script in scripts:
+ SCons.Script._SConscript._SConscript(fs, script)
+ except SCons.Errors.StopError as e:
+ # We had problems reading an SConscript file, such as it
+ # couldn't be copied in to the VariantDir. Since we're just
+ # reading SConscript files and haven't started building
+ # things yet, stop regardless of whether they used -i or -k
+ # or anything else.
+ revert_io()
+ sys.stderr.write("scons: *** %s Stop.\n" % e)
+ sys.exit(2)
+ global sconscript_time
+ sconscript_time = time.time() - start_time
+
+ progress_display("scons: done reading SConscript files.")
+
+ memory_stats.append('after reading SConscript files:')
+ count_stats.append(('post-', 'read'))
+
+ # Re-{enable,disable} warnings in case they disabled some in
+ # the SConscript file.
+ #
+ # We delay enabling the PythonVersionWarning class until here so that,
+ # if they explicitly disabled it in either in the command line or in
+ # $SCONSFLAGS, or in the SConscript file, then the search through
+ # the list of deprecated warning classes will find that disabling
+ # first and not issue the warning.
+ #SCons.Warnings.enableWarningClass(SCons.Warnings.PythonVersionWarning)
+ SCons.Warnings.process_warn_strings(options.warn)
+
+ # Now that we've read the SConscript files, we can check for the
+ # warning about deprecated Python versions--delayed until here
+ # in case they disabled the warning in the SConscript files.
+ if python_version_deprecated():
+ msg = "Support for pre-%s Python version (%s) is deprecated.\n" + \
+ " If this will cause hardship, contact scons-dev@scons.org"
+ deprecated_version_string = ".".join(map(str, deprecated_python_version))
+ SCons.Warnings.warn(SCons.Warnings.PythonVersionWarning,
+ msg % (deprecated_version_string, python_version_string()))
+
+ if not options.help:
+ # [ ] Clarify why we need to create Builder here at all, and
+ # why it is created in DefaultEnvironment
+ # https://bitbucket.org/scons/scons/commits/d27a548aeee8ad5e67ea75c2d19a7d305f784e30
+ if SCons.SConf.NeedConfigHBuilder():
+ SCons.SConf.CreateConfigHBuilder(SCons.Defaults.DefaultEnvironment())
+
+ # Now re-parse the command-line options (any to the left of a '--'
+ # argument, that is) with any user-defined command-line options that
+ # the SConscript files may have added to the parser object. This will
+ # emit the appropriate error message and exit if any unknown option
+ # was specified on the command line.
+
+ parser.preserve_unknown_options = False
+ parser.parse_args(parser.largs, options)
+
+ if options.help:
+ help_text = SCons.Script.help_text
+ if help_text is None:
+ # They specified -h, but there was no Help() inside the
+ # SConscript files. Give them the options usage.
+ raise SConsPrintHelpException
+ else:
+ print(help_text)
+ print("Use scons -H for help about command-line options.")
+ exit_status = 0
+ return
+
+ # Change directory to the top-level SConstruct directory, then tell
+ # the Node.FS subsystem that we're all done reading the SConscript
+ # files and calling Repository() and VariantDir() and changing
+ # directories and the like, so it can go ahead and start memoizing
+ # the string values of file system nodes.
+
+ fs.chdir(fs.Top)
+
+ SCons.Node.FS.save_strings(1)
+
+ # Now that we've read the SConscripts we can set the options
+ # that are SConscript settable:
+ SCons.Node.implicit_cache = options.implicit_cache
+ SCons.Node.FS.set_duplicate(options.duplicate)
+ fs.set_max_drift(options.max_drift)
+
+ SCons.Job.explicit_stack_size = options.stack_size
+
+ if options.md5_chunksize:
+ SCons.Node.FS.File.md5_chunksize = options.md5_chunksize
+
+ platform = SCons.Platform.platform_module()
+
+ if options.interactive:
+ SCons.Script.Interactive.interact(fs, OptionsParser, options,
+ targets, target_top)
+
+ else:
+
+ # Build the targets
+ nodes = _build_targets(fs, options, targets, target_top)
+ if not nodes:
+ revert_io()
+ print('Found nothing to build')
+ exit_status = 2
+
+def _build_targets(fs, options, targets, target_top):
+
+ global this_build_status
+ this_build_status = 0
+
+ progress_display.set_mode(not (options.no_progress or options.silent))
+ display.set_mode(not options.silent)
+ SCons.Action.print_actions = not options.silent
+ SCons.Action.execute_actions = not options.no_exec
+ SCons.Node.do_store_info = not options.no_exec
+ SCons.SConf.dryrun = options.no_exec
+
+ if options.diskcheck:
+ SCons.Node.FS.set_diskcheck(options.diskcheck)
+
+ SCons.CacheDir.cache_enabled = not options.cache_disable
+ SCons.CacheDir.cache_readonly = options.cache_readonly
+ SCons.CacheDir.cache_debug = options.cache_debug
+ SCons.CacheDir.cache_force = options.cache_force
+ SCons.CacheDir.cache_show = options.cache_show
+
+ if options.no_exec:
+ CleanTask.execute = CleanTask.show
+ else:
+ CleanTask.execute = CleanTask.remove
+
+ lookup_top = None
+ if targets or SCons.Script.BUILD_TARGETS != SCons.Script._build_plus_default:
+ # They specified targets on the command line or modified
+ # BUILD_TARGETS in the SConscript file(s), so if they used -u,
+ # -U or -D, we have to look up targets relative to the top,
+ # but we build whatever they specified.
+ if target_top:
+ lookup_top = fs.Dir(target_top)
+ target_top = None
+
+ targets = SCons.Script.BUILD_TARGETS
+ else:
+ # There are no targets specified on the command line,
+ # so if they used -u, -U or -D, we may have to restrict
+ # what actually gets built.
+ d = None
+ if target_top:
+ if options.climb_up == 1:
+ # -u, local directory and below
+ target_top = fs.Dir(target_top)
+ lookup_top = target_top
+ elif options.climb_up == 2:
+ # -D, all Default() targets
+ target_top = None
+ lookup_top = None
+ elif options.climb_up == 3:
+ # -U, local SConscript Default() targets
+ target_top = fs.Dir(target_top)
+ def check_dir(x, target_top=target_top):
+ if hasattr(x, 'cwd') and not x.cwd is None:
+ cwd = x.cwd.srcnode()
+ return cwd == target_top
+ else:
+ # x doesn't have a cwd, so it's either not a target,
+ # or not a file, so go ahead and keep it as a default
+ # target and let the engine sort it out:
+ return 1
+ d = [tgt for tgt in SCons.Script.DEFAULT_TARGETS if check_dir(tgt)]
+ SCons.Script.DEFAULT_TARGETS[:] = d
+ target_top = None
+ lookup_top = None
+
+ targets = SCons.Script._Get_Default_Targets(d, fs)
+
+ if not targets:
+ sys.stderr.write("scons: *** No targets specified and no Default() targets found. Stop.\n")
+ return None
+
+ def Entry(x, ltop=lookup_top, ttop=target_top, fs=fs):
+ if isinstance(x, SCons.Node.Node):
+ node = x
+ else:
+ node = None
+ # Why would ltop be None? Unfortunately this happens.
+ if ltop is None: ltop = ''
+ # Curdir becomes important when SCons is called with -u, -C,
+ # or similar option that changes directory, and so the paths
+ # of targets given on the command line need to be adjusted.
+ curdir = os.path.join(os.getcwd(), str(ltop))
+ for lookup in SCons.Node.arg2nodes_lookups:
+ node = lookup(x, curdir=curdir)
+ if node is not None:
+ break
+ if node is None:
+ node = fs.Entry(x, directory=ltop, create=1)
+ if ttop and not node.is_under(ttop):
+ if isinstance(node, SCons.Node.FS.Dir) and ttop.is_under(node):
+ node = ttop
+ else:
+ node = None
+ return node
+
+ nodes = [_f for _f in map(Entry, targets) if _f]
+
+ task_class = BuildTask # default action is to build targets
+ opening_message = "Building targets ..."
+ closing_message = "done building targets."
+ if options.keep_going:
+ failure_message = "done building targets (errors occurred during build)."
+ else:
+ failure_message = "building terminated because of errors."
+ if options.question:
+ task_class = QuestionTask
+ try:
+ if options.clean:
+ task_class = CleanTask
+ opening_message = "Cleaning targets ..."
+ closing_message = "done cleaning targets."
+ if options.keep_going:
+ failure_message = "done cleaning targets (errors occurred during clean)."
+ else:
+ failure_message = "cleaning terminated because of errors."
+ except AttributeError:
+ pass
+
+ task_class.progress = ProgressObject
+
+ if options.random:
+ def order(dependencies):
+ """Randomize the dependencies."""
+ import random
+ random.shuffle(dependencies)
+ return dependencies
+ else:
+ def order(dependencies):
+ """Leave the order of dependencies alone."""
+ return dependencies
+
+ if options.taskmastertrace_file == '-':
+ tmtrace = sys.stdout
+ elif options.taskmastertrace_file:
+ tmtrace = open(options.taskmastertrace_file, 'w')
+ else:
+ tmtrace = None
+ taskmaster = SCons.Taskmaster.Taskmaster(nodes, task_class, order, tmtrace)
+
+ # Let the BuildTask objects get at the options to respond to the
+ # various print_* settings, tree_printer list, etc.
+ BuildTask.options = options
+
+
+ python_has_threads = sysconfig.get_config_var('WITH_THREAD')
+ # to check if python configured with threads.
+ global num_jobs
+ num_jobs = options.num_jobs
+ jobs = SCons.Job.Jobs(num_jobs, taskmaster)
+ if num_jobs > 1:
+ msg = None
+ if sys.platform == 'win32':
+ msg = fetch_win32_parallel_msg()
+ elif jobs.num_jobs == 1 or not python_has_threads:
+ msg = "parallel builds are unsupported by this version of Python;\n" + \
+ "\tignoring -j or num_jobs option.\n"
+ if msg:
+ SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
+
+ memory_stats.append('before building targets:')
+ count_stats.append(('pre-', 'build'))
+
+ def jobs_postfunc(
+ jobs=jobs,
+ options=options,
+ closing_message=closing_message,
+ failure_message=failure_message
+ ):
+ if jobs.were_interrupted():
+ if not options.no_progress and not options.silent:
+ sys.stderr.write("scons: Build interrupted.\n")
+ global exit_status
+ global this_build_status
+ exit_status = 2
+ this_build_status = 2
+
+ if this_build_status:
+ progress_display("scons: " + failure_message)
+ else:
+ progress_display("scons: " + closing_message)
+ if not options.no_exec:
+ if jobs.were_interrupted():
+ progress_display("scons: writing .sconsign file.")
+ SCons.SConsign.write()
+
+ progress_display("scons: " + opening_message)
+ jobs.run(postfunc = jobs_postfunc)
+
+ memory_stats.append('after building targets:')
+ count_stats.append(('post-', 'build'))
+
+ return nodes
+
+def _exec_main(parser, values):
+ sconsflags = os.environ.get('SCONSFLAGS', '')
+ all_args = sconsflags.split() + sys.argv[1:]
+
+ options, args = parser.parse_args(all_args, values)
+
+ if isinstance(options.debug, list) and "pdb" in options.debug:
+ import pdb
+ pdb.Pdb().runcall(_main, parser)
+ elif options.profile_file:
+ # compat layer imports "cProfile" for us if it's available.
+ from profile import Profile
+
+ prof = Profile()
+ try:
+ prof.runcall(_main, parser)
+ finally:
+ prof.dump_stats(options.profile_file)
+ else:
+ _main(parser)
+
+def main():
+ global OptionsParser
+ global exit_status
+ global first_command_start
+
+ # Check up front for a Python version we do not support. We
+ # delay the check for deprecated Python versions until later,
+ # after the SConscript files have been read, in case they
+ # disable that warning.
+ if python_version_unsupported():
+ msg = "scons: *** SCons version %s does not run under Python version %s.\n"
+ sys.stderr.write(msg % (SCons.__version__, python_version_string()))
+ sys.exit(1)
+
+ parts = ["SCons by Steven Knight et al.:\n"]
+ try:
+ import __main__
+ parts.append(version_string("script", __main__))
+ except (ImportError, AttributeError):
+ # On Windows there is no scons.py, so there is no
+ # __main__.__version__, hence there is no script version.
+ pass
+ parts.append(version_string("engine", SCons))
+ parts.append(path_string("engine", SCons))
+ parts.append("__COPYRIGHT__")
+ version = ''.join(parts)
+
+ from . import SConsOptions
+ parser = SConsOptions.Parser(version)
+ values = SConsOptions.SConsValues(parser.get_default_values())
+
+ OptionsParser = parser
+
+ try:
+ try:
+ _exec_main(parser, values)
+ finally:
+ revert_io()
+ except SystemExit as s:
+ if s:
+ exit_status = s
+ except KeyboardInterrupt:
+ print("scons: Build interrupted.")
+ sys.exit(2)
+ except SyntaxError as e:
+ _scons_syntax_error(e)
+ except SCons.Errors.InternalError:
+ _scons_internal_error()
+ except SCons.Errors.UserError as e:
+ _scons_user_error(e)
+ except SConsPrintHelpException:
+ parser.print_help()
+ exit_status = 0
+ except SCons.Errors.BuildError as e:
+ print(e)
+ exit_status = e.exitstatus
+ except:
+ # An exception here is likely a builtin Python exception Python
+ # code in an SConscript file. Show them precisely what the
+ # problem was and where it happened.
+ SCons.Script._SConscript.SConscript_exception()
+ sys.exit(2)
+
+ memory_stats.print_stats()
+ count_stats.print_stats()
+
+ if print_objects:
+ SCons.Debug.listLoggedInstances('*')
+ #SCons.Debug.dumpLoggedInstances('*')
+
+ if print_memoizer:
+ SCons.Memoize.Dump("Memoizer (memory cache) hits and misses:")
+
+ # Dump any development debug info that may have been enabled.
+ # These are purely for internal debugging during development, so
+ # there's no need to control them with --debug= options; they're
+ # controlled by changing the source code.
+ SCons.Debug.dump_caller_counts()
+ SCons.Taskmaster.dump_stats()
+
+ if print_time:
+ total_time = time.time() - SCons.Script.start_time
+ if num_jobs == 1:
+ ct = cumulative_command_time
+ else:
+ if last_command_end is None or first_command_start is None:
+ ct = 0.0
+ else:
+ ct = last_command_end - first_command_start
+ scons_time = total_time - sconscript_time - ct
+ print("Total build time: %f seconds"%total_time)
+ print("Total SConscript file execution time: %f seconds"%sconscript_time)
+ print("Total SCons execution time: %f seconds"%scons_time)
+ print("Total command execution time: %f seconds"%ct)
+
+ sys.exit(exit_status)
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Main.xml b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Main.xml
new file mode 100644
index 0000000..e95afbc
--- /dev/null
+++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/Main.xml
@@ -0,0 +1,818 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+__COPYRIGHT__
+
+This file is processed by the bin/SConsDoc.py module.
+See its __doc__ string for a discussion of the format.
+-->
+
+<!DOCTYPE sconsdoc [
+<!ENTITY % scons SYSTEM '../../../../doc/scons.mod'>
+%scons;
+<!ENTITY % builders-mod SYSTEM '../../../../doc/generated/builders.mod'>
+%builders-mod;
+<!ENTITY % functions-mod SYSTEM '../../../../doc/generated/functions.mod'>
+%functions-mod;
+<!ENTITY % tools-mod SYSTEM '../../../../doc/generated/tools.mod'>
+%tools-mod;
+<!ENTITY % variables-mod SYSTEM '../../../../doc/generated/variables.mod'>
+%variables-mod;
+]>
+
+<sconsdoc 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">
+
+
+<scons_function name="AddOption">
+<arguments signature="global">
+(arguments)
+</arguments>
+<summary>
+<para>
+This function adds a new command-line option to be recognized.
+The specified
+<varname>arguments</varname>
+are the same as supported by the standard Python
+<function>optparse.add_option</function>()
+method (with a few additional capabilities noted below);
+see the documentation for
+<literal>optparse</literal>
+for a thorough discussion of its option-processing capabities.
+</para>
+
+<para>
+In addition to the arguments and values supported by the
+<function>optparse.add_option</function>()
+method,
+the SCons
+&f-AddOption;
+function allows you to set the
+<literal>nargs</literal>
+keyword value to
+<literal>'?'</literal>
+(a string with just the question mark)
+to indicate that the specified long option(s) take(s) an
+<emphasis>optional</emphasis>
+argument.
+When
+<literal>nargs = '?'</literal>
+is passed to the
+&f-AddOption;
+function, the
+<literal>const</literal>
+keyword argument
+may be used to supply the "default"
+value that should be used when the
+option is specified on the command line
+without an explicit argument.
+</para>
+
+<para>
+If no
+<literal>default=</literal>
+keyword argument is supplied when calling
+&f-AddOption;,
+the option will have a default value of
+<literal>None</literal>.
+</para>
+
+<para>
+Once a new command-line option has been added with
+&f-AddOption;,
+the option value may be accessed using
+&f-GetOption;
+or
+<function>env.GetOption</function>().
+The value may also be set, using
+&f-SetOption;
+or
+<function>env.SetOption</function>(),
+if conditions in a
+&SConscript;
+require overriding any default value.
+Note, however, that a
+value specified on the command line will
+<emphasis>always</emphasis>
+override a value set by any SConscript file.
+</para>
+
+<para>
+Any specified
+<literal>help=</literal>
+strings for the new option(s)
+will be displayed by the
+<option>-H</option>
+or
+<option>-h</option>
+options
+(the latter only if no other help text is
+specified in the SConscript files).
+The help text for the local options specified by
+&f-AddOption;
+will appear below the SCons options themselves,
+under a separate
+<literal>Local Options</literal>
+heading.
+The options will appear in the help text
+in the order in which the
+&f-AddOption;
+calls occur.
+</para>
+
+<para>
+Example:
+</para>
+
+<example_commands>
+AddOption('--prefix',
+ dest='prefix',
+ nargs=1, type='string',
+ action='store',
+ metavar='DIR',
+ help='installation prefix')
+env = Environment(PREFIX = GetOption('prefix'))
+</example_commands>
+</summary>
+</scons_function>
+
+<scons_function name="GetBuildFailures">
+<arguments signature="global">
+()
+</arguments>
+<summary>
+<para>
+Returns a list of exceptions for the
+actions that failed while
+attempting to build targets.
+Each element in the returned list is a
+<classname>BuildError</classname>
+object
+with the following attributes
+that record various aspects
+of the build failure:
+</para>
+
+<para>
+<literal>.node</literal>
+The node that was being built
+when the build failure occurred.
+</para>
+
+<para>
+<literal>.status</literal>
+The numeric exit status
+returned by the command or Python function
+that failed when trying to build the
+specified Node.
+</para>
+
+<para>
+<literal>.errstr</literal>
+The SCons error string
+describing the build failure.
+(This is often a generic
+message like "Error 2"
+to indicate that an executed
+command exited with a status of 2.)
+</para>
+
+<para>
+<literal>.filename</literal>
+The name of the file or
+directory that actually caused the failure.
+This may be different from the
+<literal>.node</literal>
+attribute.
+For example,
+if an attempt to build a target named
+<filename>sub/dir/target</filename>
+fails because the
+<filename>sub/dir</filename>
+directory could not be created,
+then the
+<literal>.node</literal>
+attribute will be
+<filename>sub/dir/target</filename>
+but the
+<literal>.filename</literal>
+attribute will be
+<filename>sub/dir</filename>.
+</para>
+
+<para>
+<literal>.executor</literal>
+The SCons Executor object
+for the target Node
+being built.
+This can be used to retrieve
+the construction environment used
+for the failed action.
+</para>
+
+<para>
+<literal>.action</literal>
+The actual SCons Action object that failed.
+This will be one specific action
+out of the possible list of
+actions that would have been
+executed to build the target.
+</para>
+
+<para>
+<literal>.command</literal>
+The actual expanded command that was executed and failed,
+after expansion of
+&cv-link-TARGET;,
+&cv-link-SOURCE;,
+and other construction variables.
+</para>
+
+<para>
+Note that the
+&f-GetBuildFailures;
+function
+will always return an empty list
+until any build failure has occurred,
+which means that
+&f-GetBuildFailures;
+will always return an empty list
+while the
+&SConscript;
+files are being read.
+Its primary intended use is
+for functions that will be
+executed before SCons exits
+by passing them to the
+standard Python
+<function>atexit.register</function>()
+function.
+Example:
+</para>
+
+<example_commands>
+import atexit
+
+def print_build_failures():
+ from SCons.Script import GetBuildFailures
+ for bf in GetBuildFailures():
+ print("%s failed: %s" % (bf.node, bf.errstr))
+
+atexit.register(print_build_failures)
+</example_commands>
+</summary>
+</scons_function>
+
+<scons_function name="GetOption">
+<arguments>
+(name)
+</arguments>
+<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:
+</para>
+
+<para>
+<variablelist>
+<varlistentry>
+<term><literal>cache_debug</literal></term>
+<listitem>
+<para>
+which corresponds to --cache-debug;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>cache_disable</literal></term>
+<listitem>
+<para>
+which corresponds to --cache-disable;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>cache_force</literal></term>
+<listitem>
+<para>
+which corresponds to --cache-force;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>cache_show</literal></term>
+<listitem>
+<para>
+which corresponds to --cache-show;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>clean</literal></term>
+<listitem>
+<para>
+which corresponds to -c, --clean and --remove;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>config</literal></term>
+<listitem>
+<para>
+which corresponds to --config;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>directory</literal></term>
+<listitem>
+<para>
+which corresponds to -C and --directory;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>diskcheck</literal></term>
+<listitem>
+<para>
+which corresponds to --diskcheck
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>duplicate</literal></term>
+<listitem>
+<para>
+which corresponds to --duplicate;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>file</literal></term>
+<listitem>
+<para>
+which corresponds to -f, --file, --makefile and --sconstruct;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>help</literal></term>
+<listitem>
+<para>
+which corresponds to -h and --help;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>ignore_errors</literal></term>
+<listitem>
+<para>
+which corresponds to --ignore-errors;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>implicit_cache</literal></term>
+<listitem>
+<para>
+which corresponds to --implicit-cache;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>implicit_deps_changed</literal></term>
+<listitem>
+<para>
+which corresponds to --implicit-deps-changed;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>implicit_deps_unchanged</literal></term>
+<listitem>
+<para>
+which corresponds to --implicit-deps-unchanged;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>interactive</literal></term>
+<listitem>
+<para>
+which corresponds to --interact and --interactive;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>keep_going</literal></term>
+<listitem>
+<para>
+which corresponds to -k and --keep-going;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>max_drift</literal></term>
+<listitem>
+<para>
+which corresponds to --max-drift;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>no_exec</literal></term>
+<listitem>
+<para>
+which corresponds to -n, --no-exec, --just-print, --dry-run and --recon;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>no_site_dir</literal></term>
+<listitem>
+<para>
+which corresponds to --no-site-dir;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>num_jobs</literal></term>
+<listitem>
+<para>
+which corresponds to -j and --jobs;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>profile_file</literal></term>
+<listitem>
+<para>
+which corresponds to --profile;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>question</literal></term>
+<listitem>
+<para>
+which corresponds to -q and --question;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>random</literal></term>
+<listitem>
+<para>
+which corresponds to --random;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>repository</literal></term>
+<listitem>
+<para>
+which corresponds to -Y, --repository and --srcdir;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>silent</literal></term>
+<listitem>
+<para>
+which corresponds to -s, --silent and --quiet;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>site_dir</literal></term>
+<listitem>
+<para>
+which corresponds to --site-dir;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>stack_size</literal></term>
+<listitem>
+<para>
+which corresponds to --stack-size;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>taskmastertrace_file</literal></term>
+<listitem>
+<para>
+which corresponds to --taskmastertrace; and
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>warn</literal></term>
+<listitem>
+<para>
+which corresponds to --warn and --warning.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+
+<para>
+See the documentation for the
+corresponding command line object for information about each specific
+option.
+</para>
+</summary>
+</scons_function>
+
+<scons_function name="Progress">
+<arguments signature="global">
+(callable, [interval])
+</arguments>
+<arguments signature="global">
+(string, [interval, file, overwrite])
+</arguments>
+<arguments signature="global">
+(list_of_strings, [interval, file, overwrite])
+</arguments>
+<summary>
+<para>
+Allows SCons to show progress made during the build
+by displaying a string or calling a function while
+evaluating Nodes (e.g. files).
+</para>
+
+<para>
+If the first specified argument is a Python callable
+(a function or an object that has a
+<function>__call__</function>()
+method),
+the function will be called
+once every
+<varname>interval</varname>
+times a Node is evaluated.
+The callable will be passed the evaluated Node
+as its only argument.
+(For future compatibility,
+it's a good idea to also add
+<literal>*args</literal>
+and
+<literal>**kw</literal>
+as arguments to your function or method.
+This will prevent the code from breaking
+if SCons ever changes the interface
+to call the function with additional arguments in the future.)
+</para>
+
+<para>
+An example of a simple custom progress function
+that prints a string containing the Node name
+every 10 Nodes:
+</para>
+
+<example_commands>
+def my_progress_function(node, *args, **kw):
+ print('Evaluating node %s!' % node)
+Progress(my_progress_function, interval=10)
+</example_commands>
+
+<para>
+A more complicated example of a custom progress display object
+that prints a string containing a count
+every 100 evaluated Nodes.
+Note the use of
+<literal>\r</literal>
+(a carriage return)
+at the end so that the string
+will overwrite itself on a display:
+</para>
+
+<example_commands>
+import sys
+class ProgressCounter(object):
+ count = 0
+ def __call__(self, node, *args, **kw):
+ self.count += 100
+ sys.stderr.write('Evaluated %s nodes\r' % self.count)
+Progress(ProgressCounter(), interval=100)
+</example_commands>
+
+<para>
+If the first argument
+&f-link-Progress;
+is a string,
+the string will be displayed
+every
+<varname>interval</varname>
+evaluated Nodes.
+The default is to print the string on standard output;
+an alternate output stream
+may be specified with the
+<literal>file=</literal>
+argument.
+The following will print a series of dots
+on the error output,
+one dot for every 100 evaluated Nodes:
+</para>
+
+<example_commands>
+import sys
+Progress('.', interval=100, file=sys.stderr)
+</example_commands>
+
+<para>
+If the string contains the verbatim substring
+&cv-TARGET;,
+it will be replaced with the Node.
+Note that, for performance reasons, this is
+<emphasis>not</emphasis>
+a regular SCons variable substition,
+so you can not use other variables
+or use curly braces.
+The following example will print the name of
+every evaluated Node,
+using a
+<literal>\r</literal>
+(carriage return) to cause each line to overwritten by the next line,
+and the
+<literal>overwrite=</literal>
+keyword argument to make sure the previously-printed
+file name is overwritten with blank spaces:
+</para>
+
+<example_commands>
+import sys
+Progress('$TARGET\r', overwrite=True)
+</example_commands>
+
+<para>
+If the first argument to
+&f-Progress;
+is a list of strings,
+then each string in the list will be displayed
+in rotating fashion every
+<varname>interval</varname>
+evaluated Nodes.
+This can be used to implement a "spinner"
+on the user's screen as follows:
+</para>
+
+<example_commands>
+Progress(['-\r', '\\\r', '|\r', '/\r'], interval=5)
+</example_commands>
+</summary>
+</scons_function>
+
+<scons_function name="Precious">
+<arguments>
+(target, ...)
+</arguments>
+<summary>
+<para>
+Marks each given
+<varname>target</varname>
+as precious so it is not deleted before it is rebuilt. Normally
+&scons;
+deletes a target before building it.
+Multiple targets can be passed in to a single call to
+&f-Precious;.
+</para>
+</summary>
+</scons_function>
+
+<scons_function name="Pseudo">
+<arguments>
+(target, ...)
+</arguments>
+<summary>
+<para>
+This indicates that each given
+<varname>target</varname>
+should not be created by the build rule, and if the target is created,
+an error will be generated. This is similar to the gnu make .PHONY
+target. However, in the vast majority of cases, an
+&f-Alias;
+is more appropriate.
+
+Multiple targets can be passed in to a single call to
+&f-Pseudo;.
+</para>
+</summary>
+</scons_function>
+<scons_function name="SetOption">
+<arguments>
+(name, value)
+</arguments>
+<summary>
+<para>
+This function provides a way to set a select subset of the scons command
+line options from a SConscript file. The options supported are:
+</para>
+
+<para>
+<variablelist>
+<varlistentry>
+<term><literal>clean</literal></term>
+<listitem>
+<para>
+which corresponds to -c, --clean and --remove;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>duplicate</literal></term>
+<listitem>
+<para>
+which corresponds to --duplicate;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>help</literal></term>
+<listitem>
+<para>
+which corresponds to -h and --help;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>implicit_cache</literal></term>
+<listitem>
+<para>
+which corresponds to --implicit-cache;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>max_drift</literal></term>
+<listitem>
+<para>
+which corresponds to --max-drift;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>no_exec</literal></term>
+<listitem>
+<para>
+which corresponds to -n, --no-exec, --just-print, --dry-run and --recon;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>num_jobs</literal></term>
+<listitem>
+<para>
+which corresponds to -j and --jobs;
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>random</literal></term>
+<listitem>
+<para>
+which corresponds to --random; and
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>silent</literal></term>
+<listitem>
+<para>
+which corresponds to --silent.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry>
+<term><literal>stack_size</literal></term>
+<listitem>
+<para>
+which corresponds to --stack-size.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+
+<para>
+See the documentation for the
+corresponding command line object for information about each specific
+option.
+</para>
+
+<para>
+Example:
+</para>
+
+<example_commands>
+SetOption('max_drift', 1)
+</example_commands>
+</summary>
+</scons_function>
+
+</sconsdoc>
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/MainTests.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/MainTests.py
new file mode 100644
index 0000000..fd6aaf4
--- /dev/null
+++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/MainTests.py
@@ -0,0 +1,55 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import unittest
+
+import TestUnit
+
+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
+# in the test/ hierarchy.
+#
+# This module is for specific bits of functionality that we can test
+# more effectively here, instead of in an end-to-end test that would
+# have to reach into SCons.Script.Main for various classes or other bits
+# of private functionality.
+
+if __name__ == "__main__":
+ suite = unittest.TestSuite()
+ tclasses = []
+ for tclass in tclasses:
+ names = unittest.getTestCaseNames(tclass, 'test_')
+ suite.addTests(list(map(tclass, names)))
+ TestUnit.run(suite)
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConsOptions.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConsOptions.py
new file mode 100644
index 0000000..60d456e
--- /dev/null
+++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConsOptions.py
@@ -0,0 +1,988 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import optparse
+import re
+import sys
+import textwrap
+
+no_hyphen_re = re.compile(r'(\s+|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))')
+
+try:
+ from gettext import gettext
+except ImportError:
+ def gettext(message):
+ return message
+_ = gettext
+
+import SCons.Node.FS
+import SCons.Warnings
+
+OptionValueError = optparse.OptionValueError
+SUPPRESS_HELP = optparse.SUPPRESS_HELP
+
+diskcheck_all = SCons.Node.FS.diskcheck_types()
+
+def diskcheck_convert(value):
+ if value is None:
+ return []
+ if not SCons.Util.is_List(value):
+ value = value.split(',')
+ result = []
+ for v in value:
+ v = v.lower()
+ if v == 'all':
+ result = diskcheck_all
+ elif v == 'none':
+ result = []
+ elif v in diskcheck_all:
+ result.append(v)
+ else:
+ raise ValueError(v)
+ return result
+
+
+class SConsValues(optparse.Values):
+ """
+ Holder class for uniform access to SCons options, regardless
+ of whether or not they can be set on the command line or in the
+ SConscript files (using the SetOption() function).
+
+ A SCons option value can originate three different ways:
+
+ 1) set on the command line;
+ 2) set in an SConscript file;
+ 3) the default setting (from the the op.add_option()
+ calls in the Parser() function, below).
+
+ The command line always overrides a value set in a SConscript file,
+ which in turn always overrides default settings. Because we want
+ to support user-specified options in the SConscript file itself,
+ though, we may not know about all of the options when the command
+ line is first parsed, so we can't make all the necessary precedence
+ decisions at the time the option is configured.
+
+ The solution implemented in this class is to keep these different sets
+ of settings separate (command line, SConscript file, and default)
+ and to override the __getattr__() method to check them in turn.
+ This should allow the rest of the code to just fetch values as
+ attributes of an instance of this class, without having to worry
+ about where they came from.
+
+ Note that not all command line options are settable from SConscript
+ files, and the ones that are must be explicitly added to the
+ "settable" list in this class, and optionally validated and coerced
+ in the set_option() method.
+ """
+
+ def __init__(self, defaults):
+ self.__dict__['__defaults__'] = defaults
+ self.__dict__['__SConscript_settings__'] = {}
+
+ def __getattr__(self, attr):
+ """
+ Fetches an options value, checking first for explicit settings
+ from the command line (which are direct attributes), then the
+ SConscript file settings, then the default values.
+ """
+ try:
+ return self.__dict__[attr]
+ except KeyError:
+ try:
+ return self.__dict__['__SConscript_settings__'][attr]
+ except KeyError:
+ try:
+ return getattr(self.__dict__['__defaults__'], attr)
+ except KeyError:
+ # Added because with py3 this is a new class,
+ # not a classic class, and due to the way
+ # In that case it will create an object without
+ # __defaults__, and then query for __setstate__
+ # which will throw an exception of KeyError
+ # deepcopy() is expecting AttributeError if __setstate__
+ # is not available.
+ raise AttributeError(attr)
+
+
+ settable = [
+ 'clean',
+ 'diskcheck',
+ 'duplicate',
+ 'help',
+ 'implicit_cache',
+ 'max_drift',
+ 'md5_chunksize',
+ 'no_exec',
+ 'num_jobs',
+ 'random',
+ 'stack_size',
+ 'warn',
+ 'silent'
+ ]
+
+ def set_option(self, name, value):
+ """
+ Sets an option from an SConscript file.
+ """
+ if not name in self.settable:
+ raise SCons.Errors.UserError("This option is not settable from a SConscript file: %s"%name)
+
+ 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))
+ elif name == 'max_drift':
+ try:
+ value = int(value)
+ except ValueError:
+ 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))
+ if not value in SCons.Node.FS.Valid_Duplicates:
+ 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)
+ elif name == 'diskcheck':
+ try:
+ value = diskcheck_convert(value)
+ except ValueError as 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
+ # file/Node lookups while processing the SConscript files.
+ SCons.Node.FS.set_diskcheck(value)
+ elif name == 'stack_size':
+ try:
+ value = int(value)
+ except ValueError:
+ raise SCons.Errors.UserError("An integer is required: %s"%repr(value))
+ elif name == 'md5_chunksize':
+ try:
+ value = int(value)
+ except ValueError:
+ raise SCons.Errors.UserError("An integer is required: %s"%repr(value))
+ elif name == 'warn':
+ if SCons.Util.is_String(value):
+ value = [value]
+ value = self.__SConscript_settings__.get(name, []) + value
+ SCons.Warnings.process_warn_strings(value)
+
+ self.__SConscript_settings__[name] = value
+
+
+class SConsOption(optparse.Option):
+ def convert_value(self, opt, value):
+ if value is not None:
+ if self.nargs in (1, '?'):
+ return self.check_value(opt, value)
+ else:
+ return tuple([self.check_value(opt, v) for v in value])
+
+ def process(self, opt, value, values, parser):
+
+ # First, convert the value(s) to the right type. Howl if any
+ # value(s) are bogus.
+ value = self.convert_value(opt, value)
+
+ # And then take whatever action is expected of us.
+ # This is a separate method to make life easier for
+ # subclasses to add new actions.
+ return self.take_action(
+ self.action, self.dest, opt, value, values, parser)
+
+ def _check_nargs_optional(self):
+ if self.nargs == '?' and self._short_opts:
+ fmt = "option %s: nargs='?' is incompatible with short options"
+ raise SCons.Errors.UserError(fmt % self._short_opts[0])
+
+ try:
+ _orig_CONST_ACTIONS = optparse.Option.CONST_ACTIONS
+
+ _orig_CHECK_METHODS = optparse.Option.CHECK_METHODS
+
+ except AttributeError:
+ # optparse.Option had no CONST_ACTIONS before Python 2.5.
+
+ _orig_CONST_ACTIONS = ("store_const",)
+
+ def _check_const(self):
+ if self.action not in self.CONST_ACTIONS and self.const is not None:
+ raise OptionError(
+ "'const' must not be supplied for action %r" % self.action,
+ self)
+
+ # optparse.Option collects its list of unbound check functions
+ # up front. This sucks because it means we can't just override
+ # the _check_const() function like a normal method, we have to
+ # actually replace it in the list. This seems to be the most
+ # straightforward way to do that.
+
+ _orig_CHECK_METHODS = [optparse.Option._check_action,
+ optparse.Option._check_type,
+ optparse.Option._check_choice,
+ optparse.Option._check_dest,
+ _check_const,
+ optparse.Option._check_nargs,
+ optparse.Option._check_callback]
+
+ CHECK_METHODS = _orig_CHECK_METHODS + [_check_nargs_optional]
+
+ CONST_ACTIONS = _orig_CONST_ACTIONS + optparse.Option.TYPED_ACTIONS
+
+class SConsOptionGroup(optparse.OptionGroup):
+ """
+ A subclass for SCons-specific option groups.
+
+ The only difference between this and the base class is that we print
+ the group's help text flush left, underneath their own title but
+ lined up with the normal "SCons Options".
+ """
+ def format_help(self, formatter):
+ """
+ Format an option group's help text, outdenting the title so it's
+ flush with the "SCons Options" title we print at the top.
+ """
+ formatter.dedent()
+ result = formatter.format_heading(self.title)
+ formatter.indent()
+ result = result + optparse.OptionContainer.format_help(self, formatter)
+ return result
+
+class SConsOptionParser(optparse.OptionParser):
+ preserve_unknown_options = False
+
+ def error(self, msg):
+ # overridden OptionValueError exception handler
+ self.print_usage(sys.stderr)
+ sys.stderr.write("SCons Error: %s\n" % msg)
+ sys.exit(2)
+
+ def _process_long_opt(self, rargs, values):
+ """
+ SCons-specific processing of long options.
+
+ This is copied directly from the normal
+ optparse._process_long_opt() method, except that, if configured
+ to do so, we catch the exception thrown when an unknown option
+ is encountered and just stick it back on the "leftover" arguments
+ for later (re-)processing.
+ """
+ arg = rargs.pop(0)
+
+ # Value explicitly attached to arg? Pretend it's the next
+ # argument.
+ if "=" in arg:
+ (opt, next_arg) = arg.split("=", 1)
+ rargs.insert(0, next_arg)
+ had_explicit_value = True
+ else:
+ opt = arg
+ had_explicit_value = False
+
+ try:
+ opt = self._match_long_opt(opt)
+ except optparse.BadOptionError:
+ if self.preserve_unknown_options:
+ # SCons-specific: if requested, add unknown options to
+ # the "leftover arguments" list for later processing.
+ self.largs.append(arg)
+ if had_explicit_value:
+ # The unknown option will be re-processed later,
+ # so undo the insertion of the explicit value.
+ rargs.pop(0)
+ return
+ raise
+
+ option = self._long_opt[opt]
+ if option.takes_value():
+ nargs = option.nargs
+ if nargs == '?':
+ if had_explicit_value:
+ value = rargs.pop(0)
+ else:
+ value = option.const
+ elif len(rargs) < nargs:
+ if nargs == 1:
+ if not option.choices:
+ self.error(_("%s option requires an argument") % opt)
+ else:
+ msg = _("%s option requires an argument " % opt)
+ msg += _("(choose from %s)"
+ % ', '.join(option.choices))
+ self.error(msg)
+ else:
+ self.error(_("%s option requires %d arguments")
+ % (opt, nargs))
+ elif nargs == 1:
+ value = rargs.pop(0)
+ else:
+ value = tuple(rargs[0:nargs])
+ del rargs[0:nargs]
+
+ elif had_explicit_value:
+ self.error(_("%s option does not take a value") % opt)
+
+ else:
+ value = None
+
+ option.process(opt, value, values, self)
+
+ def reparse_local_options(self):
+ """
+ Re-parse the leftover command-line options stored
+ in self.largs, so that any value overridden on the
+ command line is immediately available if the user turns
+ around and does a GetOption() right away.
+
+ We mimic the processing of the single args
+ in the original OptionParser._process_args(), but here we
+ allow exact matches for long-opts only (no partial
+ argument names!).
+
+ Else, this would lead to problems in add_local_option()
+ below. When called from there, we try to reparse the
+ command-line arguments that
+ 1. haven't been processed so far (self.largs), but
+ 2. are possibly not added to the list of options yet.
+
+ So, when we only have a value for "--myargument" yet,
+ a command-line argument of "--myarg=test" would set it.
+ Responsible for this behaviour is the method
+ _match_long_opt(), which allows for partial matches of
+ the option name, as long as the common prefix appears to
+ be unique.
+ This would lead to further confusion, because we might want
+ to add another option "--myarg" later on (see issue #2929).
+
+ """
+ rargs = []
+ largs_restore = []
+ # Loop over all remaining arguments
+ skip = False
+ for l in self.largs:
+ if skip:
+ # Accept all remaining arguments as they are
+ largs_restore.append(l)
+ else:
+ if len(l) > 2 and l[0:2] == "--":
+ # Check long option
+ lopt = (l,)
+ if "=" in l:
+ # Split into option and value
+ lopt = l.split("=", 1)
+
+ if lopt[0] in self._long_opt:
+ # Argument is already known
+ rargs.append('='.join(lopt))
+ else:
+ # Not known yet, so reject for now
+ largs_restore.append('='.join(lopt))
+ else:
+ if l == "--" or l == "-":
+ # Stop normal processing and don't
+ # process the rest of the command-line opts
+ largs_restore.append(l)
+ skip = True
+ else:
+ rargs.append(l)
+
+ # Parse the filtered list
+ self.parse_args(rargs, self.values)
+ # Restore the list of remaining arguments for the
+ # next call of AddOption/add_local_option...
+ self.largs = self.largs + largs_restore
+
+ def add_local_option(self, *args, **kw):
+ """
+ Adds a local option to the parser.
+
+ This is initiated by a SetOption() call to add a user-defined
+ command-line option. We add the option to a separate option
+ group for the local options, creating the group if necessary.
+ """
+ try:
+ group = self.local_option_group
+ except AttributeError:
+ group = SConsOptionGroup(self, 'Local Options')
+ group = self.add_option_group(group)
+ self.local_option_group = group
+
+ result = group.add_option(*args, **kw)
+
+ if result:
+ # The option was added successfully. We now have to add the
+ # default value to our object that holds the default values
+ # (so that an attempt to fetch the option's attribute will
+ # yield the default value when not overridden) and then
+ # we re-parse the leftover command-line options, so that
+ # any value overridden on the command line is immediately
+ # available if the user turns around and does a GetOption()
+ # right away.
+ setattr(self.values.__defaults__, result.dest, result.default)
+ self.reparse_local_options()
+
+ return result
+
+class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
+ def format_usage(self, usage):
+ return "usage: %s\n" % usage
+
+ def format_heading(self, heading):
+ """
+ This translates any heading of "options" or "Options" into
+ "SCons Options." Unfortunately, we have to do this here,
+ because those titles are hard-coded in the optparse calls.
+ """
+ if heading == 'Options':
+ heading = "SCons Options"
+ return optparse.IndentedHelpFormatter.format_heading(self, heading)
+
+ def format_option(self, option):
+ """
+ A copy of the normal optparse.IndentedHelpFormatter.format_option()
+ method. This has been snarfed so we can modify text wrapping to
+ out liking:
+
+ -- add our own regular expression that doesn't break on hyphens
+ (so things like --no-print-directory don't get broken);
+
+ -- wrap the list of options themselves when it's too long
+ (the wrapper.fill(opts) call below);
+
+ -- set the subsequent_indent when wrapping the help_text.
+ """
+ # The help for each option consists of two parts:
+ # * the opt strings and metavars
+ # eg. ("-x", or "-fFILENAME, --file=FILENAME")
+ # * the user-supplied help string
+ # eg. ("turn on expert mode", "read data from FILENAME")
+ #
+ # If possible, we write both of these on the same line:
+ # -x turn on expert mode
+ #
+ # But if the opt string list is too long, we put the help
+ # string on a second line, indented to the same column it would
+ # start in if it fit on the first line.
+ # -fFILENAME, --file=FILENAME
+ # read data from FILENAME
+ result = []
+
+ opts = self.option_strings[option]
+ opt_width = self.help_position - self.current_indent - 2
+ if len(opts) > opt_width:
+ wrapper = textwrap.TextWrapper(width=self.width,
+ initial_indent = ' ',
+ subsequent_indent = ' ')
+ wrapper.wordsep_re = no_hyphen_re
+ opts = wrapper.fill(opts) + '\n'
+ indent_first = self.help_position
+ else: # start help on same line as opts
+ opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts)
+ indent_first = 0
+ result.append(opts)
+ if option.help:
+
+ help_text = self.expand_default(option)
+
+ # SCons: indent every line of the help text but the first.
+ wrapper = textwrap.TextWrapper(width=self.help_width,
+ subsequent_indent = ' ')
+ wrapper.wordsep_re = no_hyphen_re
+ help_lines = wrapper.wrap(help_text)
+ result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
+ for line in help_lines[1:]:
+ result.append("%*s%s\n" % (self.help_position, "", line))
+ elif opts[-1] != "\n":
+ result.append("\n")
+ return "".join(result)
+
+def Parser(version):
+ """
+ Returns an options parser object initialized with the standard
+ SCons options.
+ """
+
+ formatter = SConsIndentedHelpFormatter(max_help_position=30)
+
+ op = SConsOptionParser(option_class=SConsOption,
+ add_help_option=False,
+ formatter=formatter,
+ usage="usage: scons [OPTION] [TARGET] ...",)
+
+ op.preserve_unknown_options = True
+ op.version = version
+
+ # Add the options to the parser we just created.
+ #
+ # These are in the order we want them to show up in the -H help
+ # text, basically alphabetical. Each op.add_option() call below
+ # should have a consistent format:
+ #
+ # op.add_option("-L", "--long-option-name",
+ # nargs=1, type="string",
+ # dest="long_option_name", default='foo',
+ # action="callback", callback=opt_long_option,
+ # help="help text goes here",
+ # metavar="VAR")
+ #
+ # Even though the optparse module constructs reasonable default
+ # destination names from the long option names, we're going to be
+ # explicit about each one for easier readability and so this code
+ # will at least show up when grepping the source for option attribute
+ # names, or otherwise browsing the source code.
+
+ # options ignored for compatibility
+ def opt_ignore(option, opt, value, parser):
+ sys.stderr.write("Warning: ignoring %s option\n" % opt)
+ op.add_option("-b", "-d", "-e", "-m", "-S", "-t", "-w",
+ "--environment-overrides",
+ "--no-keep-going",
+ "--no-print-directory",
+ "--print-directory",
+ "--stop",
+ "--touch",
+ action="callback", callback=opt_ignore,
+ help="Ignored for compatibility.")
+
+ op.add_option('-c', '--clean', '--remove',
+ dest="clean", default=False,
+ action="store_true",
+ help="Remove specified targets and dependencies.")
+
+ op.add_option('-C', '--directory',
+ nargs=1, type="string",
+ dest="directory", default=[],
+ action="append",
+ help="Change to DIR before doing anything.",
+ metavar="DIR")
+
+ op.add_option('--cache-debug',
+ nargs=1,
+ dest="cache_debug", default=None,
+ action="store",
+ help="Print CacheDir debug info to FILE.",
+ metavar="FILE")
+
+ op.add_option('--cache-disable', '--no-cache',
+ dest='cache_disable', default=False,
+ action="store_true",
+ help="Do not retrieve built targets from CacheDir.")
+
+ op.add_option('--cache-force', '--cache-populate',
+ dest='cache_force', default=False,
+ action="store_true",
+ help="Copy already-built targets into the CacheDir.")
+
+ op.add_option('--cache-readonly',
+ dest='cache_readonly', default=False,
+ action="store_true",
+ help="Do not update CacheDir with built targets.")
+
+ op.add_option('--cache-show',
+ dest='cache_show', default=False,
+ action="store_true",
+ help="Print build actions for files from CacheDir.")
+
+ def opt_invalid(group, value, options):
+ errmsg = "`%s' is not a valid %s option type, try:\n" % (value, group)
+ return errmsg + " %s" % ", ".join(options)
+
+ config_options = ["auto", "force" ,"cache"]
+
+ opt_config_help = "Controls Configure subsystem: %s." \
+ % ", ".join(config_options)
+
+ op.add_option('--config',
+ nargs=1, choices=config_options,
+ dest="config", default="auto",
+ help = opt_config_help,
+ metavar="MODE")
+
+ op.add_option('-D',
+ dest="climb_up", default=None,
+ action="store_const", const=2,
+ help="Search up directory tree for SConstruct, "
+ "build all Default() targets.")
+
+ deprecated_debug_options = {
+ "dtree" : '; please use --tree=derived instead',
+ "nomemoizer" : ' and has no effect',
+ "stree" : '; please use --tree=all,status instead',
+ "tree" : '; please use --tree=all instead',
+ }
+
+ debug_options = ["count", "duplicate", "explain", "findlibs",
+ "includes", "memoizer", "memory", "objects",
+ "pdb", "prepare", "presub", "stacktrace",
+ "time"]
+
+ def opt_debug(option, opt, value__, parser,
+ debug_options=debug_options,
+ deprecated_debug_options=deprecated_debug_options):
+ for value in value__.split(','):
+ if value in debug_options:
+ parser.values.debug.append(value)
+ elif value in list(deprecated_debug_options.keys()):
+ parser.values.debug.append(value)
+ try:
+ parser.values.delayed_warnings
+ except AttributeError:
+ parser.values.delayed_warnings = []
+ msg = deprecated_debug_options[value]
+ w = "The --debug=%s option is deprecated%s." % (value, msg)
+ t = (SCons.Warnings.DeprecatedDebugOptionsWarning, w)
+ parser.values.delayed_warnings.append(t)
+ else:
+ raise OptionValueError(opt_invalid('debug', value, debug_options))
+
+ opt_debug_help = "Print various types of debugging information: %s." \
+ % ", ".join(debug_options)
+ op.add_option('--debug',
+ nargs=1, type="string",
+ dest="debug", default=[],
+ action="callback", callback=opt_debug,
+ help=opt_debug_help,
+ metavar="TYPE")
+
+ def opt_diskcheck(option, opt, value, parser):
+ try:
+ diskcheck_value = diskcheck_convert(value)
+ except ValueError as e:
+ raise OptionValueError("`%s' is not a valid diskcheck type" % e)
+ setattr(parser.values, option.dest, diskcheck_value)
+
+ op.add_option('--diskcheck',
+ nargs=1, type="string",
+ dest='diskcheck', default=None,
+ action="callback", callback=opt_diskcheck,
+ help="Enable specific on-disk checks.",
+ metavar="TYPE")
+
+ def opt_duplicate(option, opt, value, parser):
+ if not value in SCons.Node.FS.Valid_Duplicates:
+ raise OptionValueError(opt_invalid('duplication', value,
+ SCons.Node.FS.Valid_Duplicates))
+ setattr(parser.values, option.dest, value)
+ # Set the duplicate style right away so it can affect linking
+ # of SConscript files.
+ SCons.Node.FS.set_duplicate(value)
+
+ opt_duplicate_help = "Set the preferred duplication methods. Must be one of " \
+ + ", ".join(SCons.Node.FS.Valid_Duplicates)
+
+ op.add_option('--duplicate',
+ nargs=1, type="string",
+ dest="duplicate", default='hard-soft-copy',
+ action="callback", callback=opt_duplicate,
+ help=opt_duplicate_help)
+
+ op.add_option('-f', '--file', '--makefile', '--sconstruct',
+ nargs=1, type="string",
+ dest="file", default=[],
+ action="append",
+ help="Read FILE as the top-level SConstruct file.")
+
+ op.add_option('-h', '--help',
+ dest="help", default=False,
+ action="store_true",
+ help="Print defined help message, or this one.")
+
+ op.add_option("-H", "--help-options",
+ action="help",
+ help="Print this message and exit.")
+
+ op.add_option('-i', '--ignore-errors',
+ dest='ignore_errors', default=False,
+ action="store_true",
+ help="Ignore errors from build actions.")
+
+ op.add_option('-I', '--include-dir',
+ nargs=1,
+ dest='include_dir', default=[],
+ action="append",
+ help="Search DIR for imported Python modules.",
+ metavar="DIR")
+
+ op.add_option('--implicit-cache',
+ dest='implicit_cache', default=False,
+ action="store_true",
+ help="Cache implicit dependencies")
+
+ def opt_implicit_deps(option, opt, value, parser):
+ setattr(parser.values, 'implicit_cache', True)
+ setattr(parser.values, option.dest, True)
+
+ op.add_option('--implicit-deps-changed',
+ dest="implicit_deps_changed", default=False,
+ action="callback", callback=opt_implicit_deps,
+ help="Ignore cached implicit dependencies.")
+
+ op.add_option('--implicit-deps-unchanged',
+ dest="implicit_deps_unchanged", default=False,
+ action="callback", callback=opt_implicit_deps,
+ help="Ignore changes in implicit dependencies.")
+
+ op.add_option('--interact', '--interactive',
+ dest='interactive', default=False,
+ action="store_true",
+ help="Run in interactive mode.")
+
+ op.add_option('-j', '--jobs',
+ nargs=1, type="int",
+ dest="num_jobs", default=1,
+ action="store",
+ help="Allow N jobs at once.",
+ metavar="N")
+
+ op.add_option('-k', '--keep-going',
+ dest='keep_going', default=False,
+ action="store_true",
+ help="Keep going when a target can't be made.")
+
+ op.add_option('--max-drift',
+ nargs=1, type="int",
+ dest='max_drift', default=SCons.Node.FS.default_max_drift,
+ action="store",
+ help="Set maximum system clock drift to N seconds.",
+ metavar="N")
+
+ op.add_option('--md5-chunksize',
+ nargs=1, type="int",
+ dest='md5_chunksize', default=SCons.Node.FS.File.md5_chunksize,
+ action="store",
+ help="Set chunk-size for MD5 signature computation to N kilobytes.",
+ metavar="N")
+
+ op.add_option('-n', '--no-exec', '--just-print', '--dry-run', '--recon',
+ dest='no_exec', default=False,
+ action="store_true",
+ help="Don't build; just print commands.")
+
+ op.add_option('--no-site-dir',
+ dest='no_site_dir', default=False,
+ action="store_true",
+ help="Don't search or use the usual site_scons dir.")
+
+ op.add_option('--profile',
+ nargs=1,
+ dest="profile_file", default=None,
+ action="store",
+ help="Profile SCons and put results in FILE.",
+ metavar="FILE")
+
+ op.add_option('-q', '--question',
+ dest="question", default=False,
+ action="store_true",
+ help="Don't build; exit status says if up to date.")
+
+ op.add_option('-Q',
+ dest='no_progress', default=False,
+ action="store_true",
+ help="Suppress \"Reading/Building\" progress messages.")
+
+ op.add_option('--random',
+ dest="random", default=False,
+ action="store_true",
+ help="Build dependencies in random order.")
+
+ op.add_option('-s', '--silent', '--quiet',
+ dest="silent", default=False,
+ action="store_true",
+ help="Don't print commands.")
+
+ op.add_option('--site-dir',
+ nargs=1,
+ dest='site_dir', default=None,
+ action="store",
+ help="Use DIR instead of the usual site_scons dir.",
+ metavar="DIR")
+
+ op.add_option('--stack-size',
+ nargs=1, type="int",
+ dest='stack_size',
+ action="store",
+ help="Set the stack size of the threads used to run jobs to N kilobytes.",
+ metavar="N")
+
+ op.add_option('--taskmastertrace',
+ nargs=1,
+ dest="taskmastertrace_file", default=None,
+ action="store",
+ help="Trace Node evaluation to FILE.",
+ metavar="FILE")
+
+ tree_options = ["all", "derived", "prune", "status"]
+
+ def opt_tree(option, opt, value, parser, tree_options=tree_options):
+ from . import Main
+ tp = Main.TreePrinter()
+ for o in value.split(','):
+ if o == 'all':
+ tp.derived = False
+ elif o == 'derived':
+ tp.derived = True
+ elif o == 'prune':
+ tp.prune = True
+ elif o == 'status':
+ tp.status = True
+ else:
+ raise OptionValueError(opt_invalid('--tree', o, tree_options))
+ parser.values.tree_printers.append(tp)
+
+ opt_tree_help = "Print a dependency tree in various formats: %s." \
+ % ", ".join(tree_options)
+
+ op.add_option('--tree',
+ nargs=1, type="string",
+ dest="tree_printers", default=[],
+ action="callback", callback=opt_tree,
+ help=opt_tree_help,
+ metavar="OPTIONS")
+
+ op.add_option('-u', '--up', '--search-up',
+ dest="climb_up", default=0,
+ action="store_const", const=1,
+ help="Search up directory tree for SConstruct, "
+ "build targets at or below current directory.")
+
+ op.add_option('-U',
+ dest="climb_up", default=0,
+ action="store_const", const=3,
+ help="Search up directory tree for SConstruct, "
+ "build Default() targets from local SConscript.")
+
+ def opt_version(option, opt, value, parser):
+ sys.stdout.write(parser.version + '\n')
+ sys.exit(0)
+ op.add_option("-v", "--version",
+ action="callback", callback=opt_version,
+ help="Print the SCons version number and exit.")
+
+ def opt_warn(option, opt, value, parser, tree_options=tree_options):
+ if SCons.Util.is_String(value):
+ value = value.split(',')
+ parser.values.warn.extend(value)
+
+ op.add_option('--warn', '--warning',
+ nargs=1, type="string",
+ dest="warn", default=[],
+ action="callback", callback=opt_warn,
+ help="Enable or disable warnings.",
+ metavar="WARNING-SPEC")
+
+ op.add_option('-Y', '--repository', '--srcdir',
+ nargs=1,
+ dest="repository", default=[],
+ action="append",
+ help="Search REPOSITORY for source and target files.")
+
+ # Options from Make and Cons classic that we do not yet support,
+ # but which we may support someday and whose (potential) meanings
+ # we don't want to change. These all get a "the -X option is not
+ # yet implemented" message and don't show up in the help output.
+
+ def opt_not_yet(option, opt, value, parser):
+ msg = "Warning: the %s option is not yet implemented\n" % opt
+ sys.stderr.write(msg)
+
+ op.add_option('-l', '--load-average', '--max-load',
+ nargs=1, type="float",
+ dest="load_average", default=0,
+ action="callback", callback=opt_not_yet,
+ # action="store",
+ # help="Don't start multiple jobs unless load is below "
+ # "LOAD-AVERAGE."
+ help=SUPPRESS_HELP)
+ op.add_option('--list-actions',
+ dest="list_actions",
+ action="callback", callback=opt_not_yet,
+ # help="Don't build; list files and build actions."
+ help=SUPPRESS_HELP)
+ op.add_option('--list-derived',
+ dest="list_derived",
+ action="callback", callback=opt_not_yet,
+ # help="Don't build; list files that would be built."
+ help=SUPPRESS_HELP)
+ op.add_option('--list-where',
+ dest="list_where",
+ action="callback", callback=opt_not_yet,
+ # help="Don't build; list files and where defined."
+ help=SUPPRESS_HELP)
+ op.add_option('-o', '--old-file', '--assume-old',
+ nargs=1, type="string",
+ dest="old_file", default=[],
+ action="callback", callback=opt_not_yet,
+ # action="append",
+ # help = "Consider FILE to be old; don't rebuild it."
+ help=SUPPRESS_HELP)
+ op.add_option('--override',
+ nargs=1, type="string",
+ action="callback", callback=opt_not_yet,
+ dest="override",
+ # help="Override variables as specified in FILE."
+ help=SUPPRESS_HELP)
+ op.add_option('-p',
+ action="callback", callback=opt_not_yet,
+ dest="p",
+ # help="Print internal environments/objects."
+ help=SUPPRESS_HELP)
+ op.add_option('-r', '-R', '--no-builtin-rules', '--no-builtin-variables',
+ action="callback", callback=opt_not_yet,
+ dest="no_builtin_rules",
+ # help="Clear default environments and variables."
+ help=SUPPRESS_HELP)
+ op.add_option('--write-filenames',
+ nargs=1, type="string",
+ dest="write_filenames",
+ action="callback", callback=opt_not_yet,
+ # help="Write all filenames examined into FILE."
+ help=SUPPRESS_HELP)
+ op.add_option('-W', '--new-file', '--assume-new', '--what-if',
+ nargs=1, type="string",
+ dest="new_file",
+ action="callback", callback=opt_not_yet,
+ # help="Consider FILE to be changed."
+ help=SUPPRESS_HELP)
+ op.add_option('--warn-undefined-variables',
+ dest="warn_undefined_variables",
+ action="callback", callback=opt_not_yet,
+ # help="Warn when an undefined variable is referenced."
+ help=SUPPRESS_HELP)
+
+ return op
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscript.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscript.py
new file mode 100644
index 0000000..db6552c
--- /dev/null
+++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscript.py
@@ -0,0 +1,640 @@
+"""SCons.Script.SConscript
+
+This module defines the Python API provided to SConscript and SConstruct
+files.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import SCons
+import SCons.Action
+import SCons.Builder
+import SCons.Defaults
+import SCons.Environment
+import SCons.Errors
+import SCons.Node
+import SCons.Node.Alias
+import SCons.Node.FS
+import SCons.Platform
+import SCons.SConf
+import SCons.Script.Main
+import SCons.Tool
+import SCons.Util
+
+from . import Main
+
+import collections
+import os
+import os.path
+import re
+import sys
+import traceback
+import time
+
+class SConscriptReturn(Exception):
+ pass
+
+launch_dir = os.path.abspath(os.curdir)
+
+GlobalDict = None
+
+# global exports set by Export():
+global_exports = {}
+
+# chdir flag
+sconscript_chdir = 1
+
+def get_calling_namespaces():
+ """Return the locals and globals for the function that called
+ into this module in the current call stack."""
+ try: 1//0
+ except ZeroDivisionError:
+ # Don't start iterating with the current stack-frame to
+ # prevent creating reference cycles (f_back is safe).
+ frame = sys.exc_info()[2].tb_frame.f_back
+
+ # Find the first frame that *isn't* from this file. This means
+ # that we expect all of the SCons frames that implement an Export()
+ # or SConscript() call to be in this file, so that we can identify
+ # the first non-Script.SConscript frame as the user's local calling
+ # environment, and the locals and globals dictionaries from that
+ # frame as the calling namespaces. See the comment below preceding
+ # the DefaultEnvironmentCall block for even more explanation.
+ while frame.f_globals.get("__name__") == __name__:
+ frame = frame.f_back
+
+ return frame.f_locals, frame.f_globals
+
+
+def compute_exports(exports):
+ """Compute a dictionary of exports given one of the parameters
+ to the Export() function or the exports argument to SConscript()."""
+
+ loc, glob = get_calling_namespaces()
+
+ retval = {}
+ try:
+ for export in exports:
+ if SCons.Util.is_Dict(export):
+ retval.update(export)
+ else:
+ try:
+ retval[export] = loc[export]
+ except KeyError:
+ retval[export] = glob[export]
+ except KeyError as x:
+ raise SCons.Errors.UserError("Export of non-existent variable '%s'"%x)
+
+ return retval
+
+class Frame(object):
+ """A frame on the SConstruct/SConscript call stack"""
+ def __init__(self, fs, exports, sconscript):
+ self.globals = BuildDefaultGlobals()
+ self.retval = None
+ self.prev_dir = fs.getcwd()
+ self.exports = compute_exports(exports) # exports from the calling SConscript
+ # make sure the sconscript attr is a Node.
+ if isinstance(sconscript, SCons.Node.Node):
+ self.sconscript = sconscript
+ elif sconscript == '-':
+ self.sconscript = None
+ else:
+ self.sconscript = fs.File(str(sconscript))
+
+# the SConstruct/SConscript call stack:
+call_stack = []
+
+# For documentation on the methods in this file, see the scons man-page
+
+def Return(*vars, **kw):
+ retval = []
+ try:
+ fvars = SCons.Util.flatten(vars)
+ for var in fvars:
+ for v in var.split():
+ retval.append(call_stack[-1].globals[v])
+ except KeyError as x:
+ raise SCons.Errors.UserError("Return of non-existent variable '%s'"%x)
+
+ if len(retval) == 1:
+ call_stack[-1].retval = retval[0]
+ else:
+ call_stack[-1].retval = tuple(retval)
+
+ stop = kw.get('stop', True)
+
+ if stop:
+ raise SConscriptReturn
+
+
+stack_bottom = '% Stack boTTom %' # hard to define a variable w/this name :)
+
+def _SConscript(fs, *files, **kw):
+ top = fs.Top
+ sd = fs.SConstruct_dir.rdir()
+ exports = kw.get('exports', [])
+
+ # evaluate each SConscript file
+ results = []
+ for fn in files:
+ call_stack.append(Frame(fs, exports, fn))
+ old_sys_path = sys.path
+ try:
+ SCons.Script.sconscript_reading = SCons.Script.sconscript_reading + 1
+ if fn == "-":
+ exec(sys.stdin.read(), call_stack[-1].globals)
+ else:
+ if isinstance(fn, SCons.Node.Node):
+ f = fn
+ else:
+ f = fs.File(str(fn))
+ _file_ = None
+
+ # Change directory to the top of the source
+ # tree to make sure the os's cwd and the cwd of
+ # fs match so we can open the SConscript.
+ fs.chdir(top, change_os_dir=1)
+ if f.rexists():
+ actual = f.rfile()
+ _file_ = open(actual.get_abspath(), "rb")
+ elif f.srcnode().rexists():
+ actual = f.srcnode().rfile()
+ _file_ = open(actual.get_abspath(), "rb")
+ elif f.has_src_builder():
+ # The SConscript file apparently exists in a source
+ # code management system. Build it, but then clear
+ # the builder so that it doesn't get built *again*
+ # during the actual build phase.
+ f.build()
+ f.built()
+ f.builder_set(None)
+ if f.exists():
+ _file_ = open(f.get_abspath(), "rb")
+ if _file_:
+ # Chdir to the SConscript directory. Use a path
+ # name relative to the SConstruct file so that if
+ # we're using the -f option, we're essentially
+ # creating a parallel SConscript directory structure
+ # in our local directory tree.
+ #
+ # XXX This is broken for multiple-repository cases
+ # where the SConstruct and SConscript files might be
+ # in different Repositories. For now, cross that
+ # bridge when someone comes to it.
+ try:
+ src_dir = kw['src_dir']
+ except KeyError:
+ ldir = fs.Dir(f.dir.get_path(sd))
+ else:
+ ldir = fs.Dir(src_dir)
+ if not ldir.is_under(f.dir):
+ # They specified a source directory, but
+ # it's above the SConscript directory.
+ # Do the sensible thing and just use the
+ # SConcript directory.
+ ldir = fs.Dir(f.dir.get_path(sd))
+ try:
+ fs.chdir(ldir, change_os_dir=sconscript_chdir)
+ except OSError:
+ # There was no local directory, so we should be
+ # able to chdir to the Repository directory.
+ # Note that we do this directly, not through
+ # fs.chdir(), because we still need to
+ # interpret the stuff within the SConscript file
+ # relative to where we are logically.
+ fs.chdir(ldir, change_os_dir=0)
+ os.chdir(actual.dir.get_abspath())
+
+ # Append the SConscript directory to the beginning
+ # of sys.path so Python modules in the SConscript
+ # directory can be easily imported.
+ sys.path = [ f.dir.get_abspath() ] + sys.path
+
+ # This is the magic line that actually reads up
+ # and executes the stuff in the SConscript file.
+ # The locals for this frame contain the special
+ # bottom-of-the-stack marker so that any
+ # exceptions that occur when processing this
+ # SConscript can base the printed frames at this
+ # level and not show SCons internals as well.
+ call_stack[-1].globals.update({stack_bottom:1})
+ old_file = call_stack[-1].globals.get('__file__')
+ try:
+ del call_stack[-1].globals['__file__']
+ except KeyError:
+ pass
+ try:
+ try:
+# _file_ = SCons.Util.to_str(_file_)
+ if Main.print_time:
+ time1 = time.time()
+ exec(compile(_file_.read(), _file_.name, 'exec'),
+ call_stack[-1].globals)
+ except SConscriptReturn:
+ pass
+ finally:
+ if Main.print_time:
+ time2 = time.time()
+ print('SConscript:%s took %0.3f ms' % (f.get_abspath(), (time2 - time1) * 1000.0))
+
+ if old_file is not None:
+ call_stack[-1].globals.update({__file__:old_file})
+ else:
+ SCons.Warnings.warn(SCons.Warnings.MissingSConscriptWarning,
+ "Ignoring missing SConscript '%s'" % f.get_internal_path())
+
+ finally:
+ SCons.Script.sconscript_reading = SCons.Script.sconscript_reading - 1
+ sys.path = old_sys_path
+ frame = call_stack.pop()
+ try:
+ fs.chdir(frame.prev_dir, change_os_dir=sconscript_chdir)
+ except OSError:
+ # There was no local directory, so chdir to the
+ # Repository directory. Like above, we do this
+ # directly.
+ fs.chdir(frame.prev_dir, change_os_dir=0)
+ rdir = frame.prev_dir.rdir()
+ rdir._create() # Make sure there's a directory there.
+ try:
+ os.chdir(rdir.get_abspath())
+ except OSError as e:
+ # We still couldn't chdir there, so raise the error,
+ # but only if actions are being executed.
+ #
+ # If the -n option was used, the directory would *not*
+ # have been created and we should just carry on and
+ # let things muddle through. This isn't guaranteed
+ # to work if the SConscript files are reading things
+ # from disk (for example), but it should work well
+ # enough for most configurations.
+ if SCons.Action.execute_actions:
+ raise e
+
+ results.append(frame.retval)
+
+ # if we only have one script, don't return a tuple
+ if len(results) == 1:
+ return results[0]
+ else:
+ return tuple(results)
+
+def SConscript_exception(file=sys.stderr):
+ """Print an exception stack trace just for the SConscript file(s).
+ This will show users who have Python errors where the problem is,
+ without cluttering the output with all of the internal calls leading
+ up to where we exec the SConscript."""
+ exc_type, exc_value, exc_tb = sys.exc_info()
+ tb = exc_tb
+ while tb and stack_bottom not in tb.tb_frame.f_locals:
+ tb = tb.tb_next
+ if not tb:
+ # We did not find our exec statement, so this was actually a bug
+ # in SCons itself. Show the whole stack.
+ tb = exc_tb
+ stack = traceback.extract_tb(tb)
+ try:
+ type = exc_type.__name__
+ except AttributeError:
+ type = str(exc_type)
+ if type[:11] == "exceptions.":
+ type = type[11:]
+ file.write('%s: %s:\n' % (type, exc_value))
+ for fname, line, func, text in stack:
+ file.write(' File "%s", line %d:\n' % (fname, line))
+ file.write(' %s\n' % text)
+
+def annotate(node):
+ """Annotate a node with the stack frame describing the
+ SConscript file and line number that created it."""
+ tb = sys.exc_info()[2]
+ while tb and stack_bottom not in tb.tb_frame.f_locals:
+ tb = tb.tb_next
+ if not tb:
+ # We did not find any exec of an SConscript file: what?!
+ raise SCons.Errors.InternalError("could not find SConscript stack frame")
+ node.creator = traceback.extract_stack(tb)[0]
+
+# The following line would cause each Node to be annotated using the
+# above function. Unfortunately, this is a *huge* performance hit, so
+# leave this disabled until we find a more efficient mechanism.
+#SCons.Node.Annotate = annotate
+
+class SConsEnvironment(SCons.Environment.Base):
+ """An Environment subclass that contains all of the methods that
+ are particular to the wrapper SCons interface and which aren't
+ (or shouldn't be) part of the build engine itself.
+
+ Note that not all of the methods of this class have corresponding
+ global functions, there are some private methods.
+ """
+
+ #
+ # Private methods of an SConsEnvironment.
+ #
+ def _exceeds_version(self, major, minor, v_major, v_minor):
+ """Return 1 if 'major' and 'minor' are greater than the version
+ in 'v_major' and 'v_minor', and 0 otherwise."""
+ return (major > v_major or (major == v_major and minor > v_minor))
+
+ def _get_major_minor_revision(self, version_string):
+ """Split a version string into major, minor and (optionally)
+ revision parts.
+
+ This is complicated by the fact that a version string can be
+ something like 3.2b1."""
+ version = version_string.split(' ')[0].split('.')
+ v_major = int(version[0])
+ v_minor = int(re.match('\d+', version[1]).group())
+ if len(version) >= 3:
+ v_revision = int(re.match('\d+', version[2]).group())
+ else:
+ v_revision = 0
+ return v_major, v_minor, v_revision
+
+ def _get_SConscript_filenames(self, ls, kw):
+ """
+ Convert the parameters passed to SConscript() calls into a list
+ of files and export variables. If the parameters are invalid,
+ throws SCons.Errors.UserError. Returns a tuple (l, e) where l
+ is a list of SConscript filenames and e is a list of exports.
+ """
+ exports = []
+
+ if len(ls) == 0:
+ try:
+ dirs = kw["dirs"]
+ except KeyError:
+ raise SCons.Errors.UserError("Invalid SConscript usage - no parameters")
+
+ if not SCons.Util.is_List(dirs):
+ dirs = [ dirs ]
+ dirs = list(map(str, dirs))
+
+ name = kw.get('name', 'SConscript')
+
+ files = [os.path.join(n, name) for n in dirs]
+
+ elif len(ls) == 1:
+
+ files = ls[0]
+
+ elif len(ls) == 2:
+
+ files = ls[0]
+ exports = self.Split(ls[1])
+
+ else:
+
+ raise SCons.Errors.UserError("Invalid SConscript() usage - too many arguments")
+
+ if not SCons.Util.is_List(files):
+ files = [ files ]
+
+ if kw.get('exports'):
+ exports.extend(self.Split(kw['exports']))
+
+ variant_dir = kw.get('variant_dir') or kw.get('build_dir')
+ if variant_dir:
+ if len(files) != 1:
+ raise SCons.Errors.UserError("Invalid SConscript() usage - can only specify one SConscript with a variant_dir")
+ duplicate = kw.get('duplicate', 1)
+ src_dir = kw.get('src_dir')
+ if not src_dir:
+ src_dir, fname = os.path.split(str(files[0]))
+ files = [os.path.join(str(variant_dir), fname)]
+ else:
+ if not isinstance(src_dir, SCons.Node.Node):
+ src_dir = self.fs.Dir(src_dir)
+ fn = files[0]
+ if not isinstance(fn, SCons.Node.Node):
+ fn = self.fs.File(fn)
+ if fn.is_under(src_dir):
+ # Get path relative to the source directory.
+ fname = fn.get_path(src_dir)
+ files = [os.path.join(str(variant_dir), fname)]
+ else:
+ files = [fn.get_abspath()]
+ kw['src_dir'] = variant_dir
+ self.fs.VariantDir(variant_dir, src_dir, duplicate)
+
+ return (files, exports)
+
+ #
+ # Public methods of an SConsEnvironment. These get
+ # entry points in the global namespace so they can be called
+ # as global functions.
+ #
+
+ def Configure(self, *args, **kw):
+ if not SCons.Script.sconscript_reading:
+ raise SCons.Errors.UserError("Calling Configure from Builders is not supported.")
+ kw['_depth'] = kw.get('_depth', 0) + 1
+ return SCons.Environment.Base.Configure(self, *args, **kw)
+
+ def Default(self, *targets):
+ SCons.Script._Set_Default_Targets(self, targets)
+
+ def EnsureSConsVersion(self, major, minor, revision=0):
+ """Exit abnormally if the SCons version is not late enough."""
+ # split string to avoid replacement during build process
+ if SCons.__version__ == '__' + 'VERSION__':
+ SCons.Warnings.warn(SCons.Warnings.DevelopmentVersionWarning,
+ "EnsureSConsVersion is ignored for development version")
+ return
+ scons_ver = self._get_major_minor_revision(SCons.__version__)
+ if scons_ver < (major, minor, revision):
+ if revision:
+ scons_ver_string = '%d.%d.%d' % (major, minor, revision)
+ else:
+ scons_ver_string = '%d.%d' % (major, minor)
+ print("SCons %s or greater required, but you have SCons %s" % \
+ (scons_ver_string, SCons.__version__))
+ sys.exit(2)
+
+ def EnsurePythonVersion(self, major, minor):
+ """Exit abnormally if the Python version is not late enough."""
+ if sys.version_info < (major, minor):
+ v = sys.version.split()[0]
+ print("Python %d.%d or greater required, but you have Python %s" %(major,minor,v))
+ sys.exit(2)
+
+ def Exit(self, value=0):
+ sys.exit(value)
+
+ def Export(self, *vars, **kw):
+ for var in vars:
+ global_exports.update(compute_exports(self.Split(var)))
+ global_exports.update(kw)
+
+ def GetLaunchDir(self):
+ global launch_dir
+ return launch_dir
+
+ def GetOption(self, name):
+ name = self.subst(name)
+ return SCons.Script.Main.GetOption(name)
+
+ def Help(self, text, append=False):
+ text = self.subst(text, raw=1)
+ SCons.Script.HelpFunction(text, append=append)
+
+ def Import(self, *vars):
+ try:
+ frame = call_stack[-1]
+ globals = frame.globals
+ exports = frame.exports
+ for var in vars:
+ var = self.Split(var)
+ for v in var:
+ if v == '*':
+ globals.update(global_exports)
+ globals.update(exports)
+ else:
+ if v in exports:
+ globals[v] = exports[v]
+ else:
+ globals[v] = global_exports[v]
+ except KeyError as x:
+ raise SCons.Errors.UserError("Import of non-existent variable '%s'"%x)
+
+ def SConscript(self, *ls, **kw):
+ if 'build_dir' in kw:
+ msg = """The build_dir keyword has been deprecated; use the variant_dir keyword instead."""
+ SCons.Warnings.warn(SCons.Warnings.DeprecatedBuildDirWarning, msg)
+ def subst_element(x, subst=self.subst):
+ if SCons.Util.is_List(x):
+ x = list(map(subst, x))
+ else:
+ x = subst(x)
+ return x
+ ls = list(map(subst_element, ls))
+ subst_kw = {}
+ for key, val in kw.items():
+ if SCons.Util.is_String(val):
+ val = self.subst(val)
+ elif SCons.Util.is_List(val):
+ result = []
+ for v in val:
+ if SCons.Util.is_String(v):
+ v = self.subst(v)
+ result.append(v)
+ val = result
+ subst_kw[key] = val
+
+ files, exports = self._get_SConscript_filenames(ls, subst_kw)
+ subst_kw['exports'] = exports
+ return _SConscript(self.fs, *files, **subst_kw)
+
+ def SConscriptChdir(self, flag):
+ global sconscript_chdir
+ sconscript_chdir = flag
+
+ def SetOption(self, name, value):
+ name = self.subst(name)
+ SCons.Script.Main.SetOption(name, value)
+
+#
+#
+#
+SCons.Environment.Environment = SConsEnvironment
+
+def Configure(*args, **kw):
+ if not SCons.Script.sconscript_reading:
+ raise SCons.Errors.UserError("Calling Configure from Builders is not supported.")
+ kw['_depth'] = 1
+ return SCons.SConf.SConf(*args, **kw)
+
+# It's very important that the DefaultEnvironmentCall() class stay in this
+# file, with the get_calling_namespaces() function, the compute_exports()
+# function, the Frame class and the SConsEnvironment.Export() method.
+# These things make up the calling stack leading up to the actual global
+# Export() or SConscript() call that the user issued. We want to allow
+# users to export local variables that they define, like so:
+#
+# def func():
+# x = 1
+# Export('x')
+#
+# To support this, the get_calling_namespaces() function assumes that
+# the *first* stack frame that's not from this file is the local frame
+# for the Export() or SConscript() call.
+
+_DefaultEnvironmentProxy = None
+
+def get_DefaultEnvironmentProxy():
+ global _DefaultEnvironmentProxy
+ if not _DefaultEnvironmentProxy:
+ default_env = SCons.Defaults.DefaultEnvironment()
+ _DefaultEnvironmentProxy = SCons.Environment.NoSubstitutionProxy(default_env)
+ return _DefaultEnvironmentProxy
+
+class DefaultEnvironmentCall(object):
+ """A class that implements "global function" calls of
+ Environment methods by fetching the specified method from the
+ DefaultEnvironment's class. Note that this uses an intermediate
+ proxy class instead of calling the DefaultEnvironment method
+ directly so that the proxy can override the subst() method and
+ thereby prevent expansion of construction variables (since from
+ the user's point of view this was called as a global function,
+ with no associated construction environment)."""
+ def __init__(self, method_name, subst=0):
+ self.method_name = method_name
+ if subst:
+ self.factory = SCons.Defaults.DefaultEnvironment
+ else:
+ self.factory = get_DefaultEnvironmentProxy
+ def __call__(self, *args, **kw):
+ env = self.factory()
+ method = getattr(env, self.method_name)
+ return method(*args, **kw)
+
+
+def BuildDefaultGlobals():
+ """
+ Create a dictionary containing all the default globals for
+ SConstruct and SConscript files.
+ """
+
+ global GlobalDict
+ if GlobalDict is None:
+ GlobalDict = {}
+
+ import SCons.Script
+ d = SCons.Script.__dict__
+ def not_a_module(m, d=d, mtype=type(SCons.Script)):
+ return not isinstance(d[m], mtype)
+ for m in filter(not_a_module, dir(SCons.Script)):
+ GlobalDict[m] = d[m]
+
+ return GlobalDict.copy()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscript.xml b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscript.xml
new file mode 100644
index 0000000..8553fbe
--- /dev/null
+++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscript.xml
@@ -0,0 +1,602 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+__COPYRIGHT__
+
+This file is processed by the bin/SConsDoc.py module.
+See its __doc__ string for a discussion of the format.
+-->
+
+<!DOCTYPE sconsdoc [
+<!ENTITY % scons SYSTEM '../../../../doc/scons.mod'>
+%scons;
+<!ENTITY % builders-mod SYSTEM '../../../../doc/generated/builders.mod'>
+%builders-mod;
+<!ENTITY % functions-mod SYSTEM '../../../../doc/generated/functions.mod'>
+%functions-mod;
+<!ENTITY % tools-mod SYSTEM '../../../../doc/generated/tools.mod'>
+%tools-mod;
+<!ENTITY % variables-mod SYSTEM '../../../../doc/generated/variables.mod'>
+%variables-mod;
+]>
+
+<sconsdoc 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">
+
+
+<scons_function name="Default">
+<arguments>
+(targets)
+</arguments>
+<summary>
+<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
+&f-Default;
+are legal,
+and add to the list of default 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.
+</para>
+
+<para>
+Examples:
+</para>
+
+<example_commands>
+Default('foo', 'bar', 'baz')
+env.Default(['a', 'b', 'c'])
+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>
+</summary>
+</scons_function>
+
+<scons_function name="EnsurePythonVersion">
+<arguments>
+(major, minor)
+</arguments>
+<summary>
+<para>
+Ensure that the Python version is at least
+<varname>major</varname>.<varname>minor</varname>.
+This function will
+print out an error message and exit SCons with a non-zero exit code if the
+actual Python version is not late enough.
+</para>
+
+<para>
+Example:
+</para>
+
+<example_commands>
+EnsurePythonVersion(2,2)
+</example_commands>
+</summary>
+</scons_function>
+
+<scons_function name="EnsureSConsVersion">
+<arguments>
+(major, minor, [revision])
+</arguments>
+<summary>
+<para>
+Ensure that the SCons version is at least
+<varname>major.minor</varname>,
+or
+<varname>major.minor.revision</varname>.
+if
+<varname>revision</varname>
+is specified.
+This function will
+print out an error message and exit SCons with a non-zero exit code if the
+actual SCons version is not late enough.
+</para>
+
+<para>
+Examples:
+</para>
+
+<example_commands>
+EnsureSConsVersion(0,14)
+
+EnsureSConsVersion(0,96,90)
+</example_commands>
+</summary>
+</scons_function>
+
+<scons_function name="Exit">
+<arguments>
+([value])
+</arguments>
+<summary>
+<para>
+This tells
+&scons;
+to exit immediately
+with the specified
+<varname>value</varname>.
+A default exit value of
+<literal>0</literal>
+(zero)
+is used if no value is specified.
+</para>
+</summary>
+</scons_function>
+
+<scons_function name="Export">
+<arguments>
+(vars)
+</arguments>
+<summary>
+<para>
+This tells
+&scons;
+to export a list of variables from the current
+SConscript file to all other SConscript files.
+The exported variables are kept in a global collection,
+so subsequent calls to
+&f-Export;
+will over-write previous exports that have the same name.
+Multiple variable names can be passed to
+&f-Export;
+as separate arguments or as a list.
+Keyword arguments can be used to provide names and their values.
+A dictionary can be used to map variables to a different name when exported.
+Both local variables and global variables can be exported.
+</para>
+
+<para>
+Examples:
+</para>
+
+<example_commands>
+env = Environment()
+# Make env available for all SConscript files to Import().
+Export("env")
+
+package = 'my_name'
+# Make env and package available for all SConscript files:.
+Export("env", "package")
+
+# Make env and package available for all SConscript files:
+Export(["env", "package"])
+
+# Make env available using the name debug:
+Export(debug = env)
+
+# Make env available using the name debug:
+Export({"debug":env})
+</example_commands>
+
+<para>
+Note that the
+&f-SConscript;
+function supports an
+<varname>exports</varname>
+argument that makes it easier to to export a variable or
+set of variables to a single SConscript file.
+See the description of the
+&f-SConscript;
+function, below.
+</para>
+</summary>
+</scons_function>
+
+<scons_function name="GetLaunchDir">
+<arguments>
+()
+</arguments>
+<summary>
+<para>
+Returns the absolute path name of the directory from which
+&scons;
+was initially invoked.
+This can be useful when using the
+<option>-u</option>,
+<option>-U</option>
+or
+<option>-D</option>
+options, which internally
+change to the directory in which the
+&SConstruct;
+file is found.
+</para>
+</summary>
+</scons_function>
+
+<scons_function name="Help">
+<arguments>
+(text, append=False)
+</arguments>
+<summary>
+<para>
+This specifies help text to be printed if the
+<option>-h</option>
+argument is given to
+&scons;.
+If
+&f-Help;
+is called multiple times, the text is appended together in the order that
+&f-Help;
+is called. With append set to False, any
+&f-Help;
+text generated with
+&f-AddOption;
+is clobbered. If append is True, the AddOption help is prepended to the help
+string, thus preserving the
+<option>-h</option>
+message.
+</para>
+</summary>
+</scons_function>
+
+<scons_function name="Import">
+<arguments>
+(vars)
+</arguments>
+<summary>
+<para>
+This tells
+&scons;
+to import a list of variables into the current SConscript file. This
+will import variables that were exported with
+&f-Export;
+or in the
+<varname>exports</varname>
+argument to
+&f-link-SConscript;.
+Variables exported by
+&f-SConscript;
+have precedence.
+Multiple variable names can be passed to
+&f-Import;
+as separate arguments or as a list. The variable "*" can be used
+to import all variables.
+</para>
+
+<para>
+Examples:
+</para>
+
+<example_commands>
+Import("env")
+Import("env", "variable")
+Import(["env", "variable"])
+Import("*")
+</example_commands>
+</summary>
+</scons_function>
+
+<scons_function name="Return">
+<arguments signature="global">
+([vars..., stop=])
+</arguments>
+<summary>
+<para>
+By default,
+this stops processing the current SConscript
+file and returns to the calling SConscript file
+the values of the variables named in the
+<varname>vars</varname>
+string arguments.
+Multiple strings contaning variable names may be passed to
+&f-Return;.
+Any strings that contain white space
+</para>
+
+<para>
+The optional
+<literal>stop=</literal>
+keyword argument may be set to a false value
+to continue processing the rest of the SConscript
+file after the
+&f-Return;
+call.
+This was the default behavior prior to SCons 0.98.
+However, the values returned
+are still the values of the variables in the named
+<varname>vars</varname>
+at the point
+&f-Return;
+is called.
+</para>
+
+<para>
+Examples:
+</para>
+
+<example_commands>
+# Returns without returning a value.
+Return()
+
+# Returns the value of the 'foo' Python variable.
+Return("foo")
+
+# Returns the values of the Python variables 'foo' and 'bar'.
+Return("foo", "bar")
+
+# Returns the values of Python variables 'val1' and 'val2'.
+Return('val1 val2')
+</example_commands>
+</summary>
+</scons_function>
+
+<scons_function name="SConscript">
+<arguments>
+(scripts, [exports, variant_dir, duplicate])
+<!-- (scripts, [exports, variant_dir, src_dir, duplicate]) -->
+</arguments>
+<arguments>
+(dirs=subdirs, [name=script, exports, variant_dir, duplicate])
+<!-- (dirs=subdirs, [name=script, exports, variant_dir, src_dir, duplicate]) -->
+</arguments>
+<summary>
+<para>
+This tells
+&scons;
+to execute
+one or more subsidiary SConscript (configuration) files.
+Any variables returned by a called script using
+&f-link-Return;
+will be returned by the call to
+&f-SConscript;.
+There are two ways to call the
+&f-SConscript;
+function.
+</para>
+
+<para>
+The first way you can call
+&f-SConscript;
+is to explicitly specify one or more
+<varname>scripts</varname>
+as the first argument.
+A single script may be specified as a string;
+multiple scripts must be specified as a list
+(either explicitly or as created by
+a function like
+&f-Split;).
+Examples:
+</para>
+<example_commands>
+SConscript('SConscript') # run SConscript in the current directory
+SConscript('src/SConscript') # run SConscript in the src directory
+SConscript(['src/SConscript', 'doc/SConscript'])
+config = SConscript('MyConfig.py')
+</example_commands>
+
+<para>
+The second way you can call
+&f-SConscript;
+is to specify a list of (sub)directory names
+as a
+<literal>dirs=</literal><varname>subdirs</varname>
+keyword argument.
+In this case,
+&scons;
+will, by default,
+execute a subsidiary configuration file named
+&SConscript;
+in each of the specified directories.
+You may specify a name other than
+&SConscript;
+by supplying an optional
+<literal>name=</literal><varname>script</varname>
+keyword argument.
+The first three examples below have the same effect
+as the first three examples above:
+</para>
+<example_commands>
+SConscript(dirs='.') # run SConscript in the current directory
+SConscript(dirs='src') # run SConscript in the src directory
+SConscript(dirs=['src', 'doc'])
+SConscript(dirs=['sub1', 'sub2'], name='MySConscript')
+</example_commands>
+
+<para>
+The optional
+<varname>exports</varname>
+argument provides a list of variable names or a dictionary of
+named values to export to the
+<varname>script(s)</varname>.
+These variables are locally exported only to the specified
+<varname>script(s)</varname>,
+and do not affect the global pool of variables used by the
+&f-Export;
+function.
+<!-- If multiple dirs are provided, each script gets a fresh export. -->
+The subsidiary
+<varname>script(s)</varname>
+must use the
+&f-link-Import;
+function to import the variables.
+Examples:
+</para>
+<example_commands>
+foo = SConscript('sub/SConscript', exports='env')
+SConscript('dir/SConscript', exports=['env', 'variable'])
+SConscript(dirs='subdir', exports='env variable')
+SConscript(dirs=['one', 'two', 'three'], exports='shared_info')
+</example_commands>
+
+<para>
+If the optional
+<varname>variant_dir</varname>
+argument is present, it causes an effect equivalent to the
+&f-link-VariantDir;
+method described below.
+(If
+<varname>variant_dir</varname>
+is not present, the
+<!-- <varname>src_dir</varname> and -->
+<varname>duplicate</varname>
+<!-- arguments are ignored.) -->
+argument is ignored.)
+The
+<varname>variant_dir</varname>
+<!--
+and
+<varname>src_dir</varname>
+arguments are interpreted relative to the directory of the calling
+-->
+argument is interpreted relative to the directory of the calling
+&SConscript;
+file.
+See the description of the
+&f-VariantDir;
+function below for additional details and restrictions.
+</para>
+
+<para>
+If
+<varname>variant_dir</varname>
+is present,
+<!--
+but
+<varname>src_dir</varname>
+is not,
+-->
+the source directory is the directory in which the
+&SConscript;
+file resides and the
+&SConscript;
+file is evaluated as if it were in the
+<varname>variant_dir</varname>
+directory:
+</para>
+<example_commands>
+SConscript('src/SConscript', variant_dir = 'build')
+</example_commands>
+
+<para>
+is equivalent to
+</para>
+
+<example_commands>
+VariantDir('build', 'src')
+SConscript('build/SConscript')
+</example_commands>
+
+<para>
+This later paradigm is often used when the sources are
+in the same directory as the
+&SConstruct;:
+</para>
+
+<example_commands>
+SConscript('SConscript', variant_dir = 'build')
+</example_commands>
+
+<para>
+is equivalent to
+</para>
+
+<example_commands>
+VariantDir('build', '.')
+SConscript('build/SConscript')
+</example_commands>
+
+<para>
+<!--
+If
+<varname>variant_dir</varname>
+and"
+<varname>src_dir</varname>
+are both present,
+xxxxx everything is in a state of confusion.
+</para>
+<example_commands>
+SConscript(dirs = 'src', variant_dir = 'build', src_dir = '.')
+runs src/SConscript in build/src, but
+SConscript(dirs = 'lib', variant_dir = 'build', src_dir = 'src')
+runs lib/SConscript (in lib!). However,
+SConscript(dirs = 'src', variant_dir = 'build', src_dir = 'src')
+runs src/SConscript in build. Moreover,
+SConscript(dirs = 'src/lib', variant_dir = 'build', src_dir = 'src')
+runs src/lib/SConscript in build/lib. Moreover,
+SConscript(dirs = 'build/src/lib', variant_dir = 'build', src_dir = 'src')
+can't find build/src/lib/SConscript, even though it ought to exist.
+</example_commands>
+<para>
+is equivalent to
+</para>
+<example_commands>
+????????????????
+</example_commands>
+<para>
+and what about this alternative?
+TODO??? SConscript('build/SConscript', src_dir='src')
+-->
+</para>
+
+<para>
+Here are some composite examples:
+</para>
+
+<example_commands>
+# collect the configuration information and use it to build src and doc
+shared_info = SConscript('MyConfig.py')
+SConscript('src/SConscript', exports='shared_info')
+SConscript('doc/SConscript', exports='shared_info')
+</example_commands>
+
+<example_commands>
+# build debugging and production versions. SConscript
+# can use Dir('.').path to determine variant.
+SConscript('SConscript', variant_dir='debug', duplicate=0)
+SConscript('SConscript', variant_dir='prod', duplicate=0)
+</example_commands>
+
+<example_commands>
+# build debugging and production versions. SConscript
+# is passed flags to use.
+opts = { 'CPPDEFINES' : ['DEBUG'], 'CCFLAGS' : '-pgdb' }
+SConscript('SConscript', variant_dir='debug', duplicate=0, exports=opts)
+opts = { 'CPPDEFINES' : ['NODEBUG'], 'CCFLAGS' : '-O' }
+SConscript('SConscript', variant_dir='prod', duplicate=0, exports=opts)
+</example_commands>
+
+<example_commands>
+# build common documentation and compile for different architectures
+SConscript('doc/SConscript', variant_dir='build/doc', duplicate=0)
+SConscript('src/SConscript', variant_dir='build/x86', duplicate=0)
+SConscript('src/SConscript', variant_dir='build/ppc', duplicate=0)
+</example_commands>
+</summary>
+</scons_function>
+
+</sconsdoc>
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscriptTests.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscriptTests.py
new file mode 100644
index 0000000..8b2521d
--- /dev/null
+++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/SConscriptTests.py
@@ -0,0 +1,34 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import SCons.Script.SConscript
+
+# all of the SConscript.py tests are in test/SConscript.py
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/__init__.py b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/__init__.py
new file mode 100644
index 0000000..5bdd63e
--- /dev/null
+++ b/3rdParty/SCons/scons-3.0.1/engine/SCons/Script/__init__.py
@@ -0,0 +1,429 @@
+"""SCons.Script
+
+This file implements the main() function used by the scons script.
+
+Architecturally, this *is* the scons script, and will likely only be
+called from the external "scons" wrapper. Consequently, anything here
+should not be, or be considered, part of the build engine. If it's
+something that we expect other software to want to use, it should go in
+some other module. If it's specific to the "scons" script invocation,
+it goes here.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import time
+start_time = time.time()
+
+import collections
+import os
+
+try:
+ from StringIO import StringIO
+except ImportError:
+ from io import StringIO
+
+import sys
+
+# Special chicken-and-egg handling of the "--debug=memoizer" flag:
+#
+# SCons.Memoize contains a metaclass implementation that affects how
+# the other classes are instantiated. The Memoizer may add shim methods
+# to classes that have methods that cache computed values in order to
+# count and report the hits and misses.
+#
+# If we wait to enable the Memoization until after we've parsed the
+# command line options normally, it will be too late, because the Memoizer
+# will have already analyzed the classes that it's Memoizing and decided
+# to not add the shims. So we use a special-case, up-front check for
+# the "--debug=memoizer" flag and enable Memoizer before we import any
+# of the other modules that use it.
+
+_args = sys.argv + os.environ.get('SCONSFLAGS', '').split()
+if "--debug=memoizer" in _args:
+ import SCons.Memoize
+ import SCons.Warnings
+ try:
+ SCons.Memoize.EnableMemoization()
+ except SCons.Warnings.Warning:
+ # Some warning was thrown. Arrange for it to be displayed
+ # or not after warnings are configured.
+ from . import Main
+ exc_type, exc_value, tb = sys.exc_info()
+ Main.delayed_warnings.append((exc_type, exc_value))
+del _args
+
+import SCons.Action
+import SCons.Builder
+import SCons.Environment
+import SCons.Node.FS
+import SCons.Options
+import SCons.Platform
+import SCons.Scanner
+import SCons.SConf
+import SCons.Subst
+import SCons.Tool
+import SCons.Util
+import SCons.Variables
+import SCons.Defaults
+
+from . import Main
+
+main = Main.main
+
+# The following are global class definitions and variables that used to
+# live directly in this module back before 0.96.90, when it contained
+# a lot of code. Some SConscript files in widely-distributed packages
+# (Blender is the specific example) actually reached into SCons.Script
+# directly to use some of these. Rather than break those SConscript
+# files, we're going to propagate these names into the SCons.Script
+# namespace here.
+#
+# Some of these are commented out because it's *really* unlikely anyone
+# used them, but we're going to leave the comment here to try to make
+# it obvious what to do if the situation arises.
+BuildTask = Main.BuildTask
+CleanTask = Main.CleanTask
+QuestionTask = Main.QuestionTask
+#PrintHelp = Main.PrintHelp
+#SConscriptSettableOptions = Main.SConscriptSettableOptions
+
+AddOption = Main.AddOption
+PrintHelp = Main.PrintHelp
+GetOption = Main.GetOption
+SetOption = Main.SetOption
+Progress = Main.Progress
+GetBuildFailures = Main.GetBuildFailures
+
+#keep_going_on_error = Main.keep_going_on_error
+#print_dtree = Main.print_dtree
+#print_explanations = Main.print_explanations
+#print_includes = Main.print_includes
+#print_objects = Main.print_objects
+#print_time = Main.print_time
+#print_tree = Main.print_tree
+#memory_stats = Main.memory_stats
+#ignore_errors = Main.ignore_errors
+#sconscript_time = Main.sconscript_time
+#command_time = Main.command_time
+#exit_status = Main.exit_status
+#profiling = Main.profiling
+#repositories = Main.repositories
+
+#
+from . import SConscript
+_SConscript = SConscript
+
+call_stack = _SConscript.call_stack
+
+#
+Action = SCons.Action.Action
+AddMethod = SCons.Util.AddMethod
+AllowSubstExceptions = SCons.Subst.SetAllowableExceptions
+Builder = SCons.Builder.Builder
+Configure = _SConscript.Configure
+Environment = SCons.Environment.Environment
+#OptParser = SCons.SConsOptions.OptParser
+FindPathDirs = SCons.Scanner.FindPathDirs
+Platform = SCons.Platform.Platform
+Return = _SConscript.Return
+Scanner = SCons.Scanner.Base
+Tool = SCons.Tool.Tool
+WhereIs = SCons.Util.WhereIs
+
+#
+BoolVariable = SCons.Variables.BoolVariable
+EnumVariable = SCons.Variables.EnumVariable
+ListVariable = SCons.Variables.ListVariable
+PackageVariable = SCons.Variables.PackageVariable
+PathVariable = SCons.Variables.PathVariable
+
+# Deprecated names that will go away some day.
+BoolOption = SCons.Options.BoolOption
+EnumOption = SCons.Options.EnumOption
+ListOption = SCons.Options.ListOption
+PackageOption = SCons.Options.PackageOption
+PathOption = SCons.Options.PathOption
+
+# Action factories.
+Chmod = SCons.Defaults.Chmod
+Copy = SCons.Defaults.Copy
+Delete = SCons.Defaults.Delete
+Mkdir = SCons.Defaults.Mkdir
+Move = SCons.Defaults.Move
+Touch = SCons.Defaults.Touch
+
+# Pre-made, public scanners.
+CScanner = SCons.Tool.CScanner
+DScanner = SCons.Tool.DScanner
+DirScanner = SCons.Defaults.DirScanner
+ProgramScanner = SCons.Tool.ProgramScanner
+SourceFileScanner = SCons.Tool.SourceFileScanner
+
+# Functions we might still convert to Environment methods.
+CScan = SCons.Defaults.CScan
+DefaultEnvironment = SCons.Defaults.DefaultEnvironment
+
+# Other variables we provide.
+class TargetList(collections.UserList):
+ def _do_nothing(self, *args, **kw):
+ pass
+ def _add_Default(self, list):
+ self.extend(list)
+ def _clear(self):
+ del self[:]
+
+ARGUMENTS = {}
+ARGLIST = []
+BUILD_TARGETS = TargetList()
+COMMAND_LINE_TARGETS = []
+DEFAULT_TARGETS = []
+
+# BUILD_TARGETS can be modified in the SConscript files. If so, we
+# want to treat the modified BUILD_TARGETS list as if they specified
+# targets on the command line. To do that, though, we need to know if
+# BUILD_TARGETS was modified through "official" APIs or by hand. We do
+# this by updating two lists in parallel, the documented BUILD_TARGETS
+# list, above, and this internal _build_plus_default targets list which
+# should only have "official" API changes. Then Script/Main.py can
+# compare these two afterwards to figure out if the user added their
+# own targets to BUILD_TARGETS.
+_build_plus_default = TargetList()
+
+def _Add_Arguments(alist):
+ for arg in alist:
+ a, b = arg.split('=', 1)
+ ARGUMENTS[a] = b
+ ARGLIST.append((a, b))
+
+def _Add_Targets(tlist):
+ if tlist:
+ COMMAND_LINE_TARGETS.extend(tlist)
+ BUILD_TARGETS.extend(tlist)
+ BUILD_TARGETS._add_Default = BUILD_TARGETS._do_nothing
+ BUILD_TARGETS._clear = BUILD_TARGETS._do_nothing
+ _build_plus_default.extend(tlist)
+ _build_plus_default._add_Default = _build_plus_default._do_nothing
+ _build_plus_default._clear = _build_plus_default._do_nothing
+
+def _Set_Default_Targets_Has_Been_Called(d, fs):
+ return DEFAULT_TARGETS
+
+def _Set_Default_Targets_Has_Not_Been_Called(d, fs):
+ if d is None:
+ d = [fs.Dir('.')]
+ return d
+
+_Get_Default_Targets = _Set_Default_Targets_Has_Not_Been_Called
+
+def _Set_Default_Targets(env, tlist):
+ global DEFAULT_TARGETS
+ global _Get_Default_Targets
+ _Get_Default_Targets = _Set_Default_Targets_Has_Been_Called
+ for t in tlist:
+ if t is None:
+ # Delete the elements from the list in-place, don't
+ # reassign an empty list to DEFAULT_TARGETS, so that the
+ # variables will still point to the same object we point to.
+ del DEFAULT_TARGETS[:]
+ BUILD_TARGETS._clear()
+ _build_plus_default._clear()
+ elif isinstance(t, SCons.Node.Node):
+ DEFAULT_TARGETS.append(t)
+ BUILD_TARGETS._add_Default([t])
+ _build_plus_default._add_Default([t])
+ else:
+ nodes = env.arg2nodes(t, env.fs.Entry)
+ DEFAULT_TARGETS.extend(nodes)
+ BUILD_TARGETS._add_Default(nodes)
+ _build_plus_default._add_Default(nodes)
+
+#
+help_text = None
+
+def HelpFunction(text, append=False):
+ global help_text
+ if help_text is None:
+ if append:
+ s = StringIO()
+ PrintHelp(s)
+ help_text = s.getvalue()
+ s.close()
+ else:
+ help_text = ""
+
+ help_text= help_text + text
+
+
+#
+# Will be non-zero if we are reading an SConscript file.
+sconscript_reading = 0
+
+#
+def Variables(files=[], args=ARGUMENTS):
+ return SCons.Variables.Variables(files, args)
+
+def Options(files=[], args=ARGUMENTS):
+ return SCons.Options.Options(files, args)
+
+# The list of global functions to add to the SConscript name space
+# that end up calling corresponding methods or Builders in the
+# DefaultEnvironment().
+GlobalDefaultEnvironmentFunctions = [
+ # Methods from the SConsEnvironment class, above.
+ 'Default',
+ 'EnsurePythonVersion',
+ 'EnsureSConsVersion',
+ 'Exit',
+ 'Export',
+ 'GetLaunchDir',
+ 'Help',
+ 'Import',
+ #'SConscript', is handled separately, below.
+ 'SConscriptChdir',
+
+ # Methods from the Environment.Base class.
+ 'AddPostAction',
+ 'AddPreAction',
+ 'Alias',
+ 'AlwaysBuild',
+ 'BuildDir',
+ 'CacheDir',
+ 'Clean',
+ #The Command() method is handled separately, below.
+ 'Decider',
+ 'Depends',
+ 'Dir',
+ 'NoClean',
+ 'NoCache',
+ 'Entry',
+ 'Execute',
+ 'File',
+ 'FindFile',
+ 'FindInstalledFiles',
+ 'FindSourceFiles',
+ 'Flatten',
+ 'GetBuildPath',
+ 'Glob',
+ 'Ignore',
+ 'Install',
+ 'InstallAs',
+ 'InstallVersionedLib',
+ 'Literal',
+ 'Local',
+ 'ParseDepends',
+ 'Precious',
+ 'PyPackageDir',
+ 'Repository',
+ 'Requires',
+ 'SConsignFile',
+ 'SideEffect',
+ 'SourceCode',
+ 'SourceSignatures',
+ 'Split',
+ 'Tag',
+ 'TargetSignatures',
+ 'Value',
+ 'VariantDir',
+]
+
+GlobalDefaultBuilders = [
+ # Supported builders.
+ 'CFile',
+ 'CXXFile',
+ 'DVI',
+ 'Jar',
+ 'Java',
+ 'JavaH',
+ 'Library',
+ 'LoadableModule',
+ 'M4',
+ 'MSVSProject',
+ 'Object',
+ 'PCH',
+ 'PDF',
+ 'PostScript',
+ 'Program',
+ 'RES',
+ 'RMIC',
+ 'SharedLibrary',
+ 'SharedObject',
+ 'StaticLibrary',
+ 'StaticObject',
+ 'Tar',
+ 'TypeLibrary',
+ 'Zip',
+ 'Package',
+]
+
+for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
+ exec ("%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name)))
+del name
+
+# There are a handful of variables that used to live in the
+# Script/SConscript.py module that some SConscript files out there were
+# accessing directly as SCons.Script.SConscript.*. The problem is that
+# "SConscript" in this namespace is no longer a module, it's a global
+# function call--or more precisely, an object that implements a global
+# function call through the default Environment. Nevertheless, we can
+# maintain backwards compatibility for SConscripts that were reaching in
+# this way by hanging some attributes off the "SConscript" object here.
+SConscript = _SConscript.DefaultEnvironmentCall('SConscript')
+
+# Make SConscript look enough like the module it used to be so
+# that pychecker doesn't barf.
+SConscript.__name__ = 'SConscript'
+
+SConscript.Arguments = ARGUMENTS
+SConscript.ArgList = ARGLIST
+SConscript.BuildTargets = BUILD_TARGETS
+SConscript.CommandLineTargets = COMMAND_LINE_TARGETS
+SConscript.DefaultTargets = DEFAULT_TARGETS
+
+# The global Command() function must be handled differently than the
+# global functions for other construction environment methods because
+# we want people to be able to use Actions that must expand $TARGET
+# and $SOURCE later, when (and if) the Action is invoked to build
+# the target(s). We do this with the subst=1 argument, which creates
+# a DefaultEnvironmentCall instance that wraps up a normal default
+# construction environment that performs variable substitution, not a
+# proxy that doesn't.
+#
+# There's a flaw here, though, because any other $-variables on a command
+# line will *also* be expanded, each to a null string, but that should
+# only be a problem in the unusual case where someone was passing a '$'
+# on a command line and *expected* the $ to get through to the shell
+# because they were calling Command() and not env.Command()... This is
+# unlikely enough that we're going to leave this as is and cross that
+# bridge if someone actually comes to it.
+Command = _SConscript.DefaultEnvironmentCall('Command', subst=1)
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: