init
This commit is contained in:
376
scons-local-3.0.0/SCons/Script/Interactive.py
Normal file
376
scons-local-3.0.0/SCons/Script/Interactive.py
Normal file
@@ -0,0 +1,376 @@
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/Interactive.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
__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:
|
1427
scons-local-3.0.0/SCons/Script/Main.py
Normal file
1427
scons-local-3.0.0/SCons/Script/Main.py
Normal file
File diff suppressed because it is too large
Load Diff
988
scons-local-3.0.0/SCons/Script/SConsOptions.py
Normal file
988
scons-local-3.0.0/SCons/Script/SConsOptions.py
Normal file
@@ -0,0 +1,988 @@
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/SConsOptions.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
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:
|
633
scons-local-3.0.0/SCons/Script/SConscript.py
Normal file
633
scons-local-3.0.0/SCons/Script/SConscript.py
Normal file
@@ -0,0 +1,633 @@
|
||||
"""SCons.Script.SConscript
|
||||
|
||||
This module defines the Python API provided to SConscript and SConstruct
|
||||
files.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/SConscript.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
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
|
||||
|
||||
import collections
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
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_)
|
||||
exec(compile(_file_.read(), _file_.name, 'exec'),
|
||||
call_stack[-1].globals)
|
||||
except SConscriptReturn:
|
||||
pass
|
||||
finally:
|
||||
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:
|
429
scons-local-3.0.0/SCons/Script/__init__.py
Normal file
429
scons-local-3.0.0/SCons/Script/__init__.py
Normal file
@@ -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 (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/__init__.py rel_3.0.0:4395:8972f6a2f699 2017/09/18 12:59:24 bdbaddog"
|
||||
|
||||
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:
|
Reference in New Issue
Block a user