| Index: third_party/scons/scons-local/SCons/Action.py
|
| ===================================================================
|
| --- third_party/scons/scons-local/SCons/Action.py (revision 9094)
|
| +++ third_party/scons/scons-local/SCons/Action.py (working copy)
|
| @@ -76,7 +76,7 @@
|
|
|
| """
|
|
|
| -# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
| +# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons Foundation
|
| #
|
| # Permission is hereby granted, free of charge, to any person obtaining
|
| # a copy of this software and associated documentation files (the
|
| @@ -97,7 +97,7 @@
|
| # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
| # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
| -__revision__ = "src/engine/SCons/Action.py 3842 2008/12/20 22:59:52 scons"
|
| +__revision__ = "src/engine/SCons/Action.py 3897 2009/01/13 06:45:54 scons"
|
|
|
| import cPickle
|
| import dis
|
| @@ -392,7 +392,7 @@
|
| aa = _do_create_action(a, kw)
|
| if aa is not None: acts.append(aa)
|
| if not acts:
|
| - return None
|
| + return ListAction([])
|
| elif len(acts) == 1:
|
| return acts[0]
|
| else:
|
| @@ -414,6 +414,11 @@
|
| def __cmp__(self, other):
|
| return cmp(self.__dict__, other)
|
|
|
| + def no_batch_key(self, env, target, source):
|
| + return None
|
| +
|
| + batch_key = no_batch_key
|
| +
|
| def genstring(self, target, source, env):
|
| return str(self)
|
|
|
| @@ -446,15 +451,18 @@
|
| self.presub_env = None # don't need this any more
|
| return lines
|
|
|
| - def get_executor(self, env, overrides, tlist, slist, executor_kw):
|
| - """Return the Executor for this Action."""
|
| - return SCons.Executor.Executor(self, env, overrides,
|
| - tlist, slist, executor_kw)
|
| + def get_targets(self, env, executor):
|
| + """
|
| + Returns the type of targets ($TARGETS, $CHANGED_TARGETS) used
|
| + by this action.
|
| + """
|
| + return self.targets
|
|
|
| class _ActionAction(ActionBase):
|
| """Base class for actions that create output objects."""
|
| def __init__(self, cmdstr=_null, strfunction=_null, varlist=(),
|
| presub=_null, chdir=None, exitstatfunc=None,
|
| + batch_key=None, targets='$TARGETS',
|
| **kw):
|
| self.cmdstr = cmdstr
|
| if strfunction is not _null:
|
| @@ -469,6 +477,19 @@
|
| exitstatfunc = default_exitstatfunc
|
| self.exitstatfunc = exitstatfunc
|
|
|
| + self.targets = targets
|
| +
|
| + if batch_key:
|
| + if not callable(batch_key):
|
| + # They have set batch_key, but not to their own
|
| + # callable. The default behavior here will batch
|
| + # *all* targets+sources using this action, separated
|
| + # for each construction environment.
|
| + def default_batch_key(self, env, target, source):
|
| + return (id(self), id(env))
|
| + batch_key = default_batch_key
|
| + SCons.Util.AddMethod(self, batch_key, 'batch_key')
|
| +
|
| def print_cmd_line(self, s, target, source, env):
|
| sys.stdout.write(s + "\n")
|
|
|
| @@ -477,7 +498,8 @@
|
| presub=_null,
|
| show=_null,
|
| execute=_null,
|
| - chdir=_null):
|
| + chdir=_null,
|
| + executor=None):
|
| if not is_List(target):
|
| target = [target]
|
| if not is_List(source):
|
| @@ -498,15 +520,27 @@
|
| chdir = str(chdir.abspath)
|
| except AttributeError:
|
| if not is_String(chdir):
|
| - chdir = str(target[0].dir)
|
| + if executor:
|
| + chdir = str(executor.batches[0].targets[0].dir)
|
| + else:
|
| + chdir = str(target[0].dir)
|
| if presub:
|
| + if executor:
|
| + target = executor.get_all_targets()
|
| + source = executor.get_all_sources()
|
| t = string.join(map(str, target), ' and ')
|
| l = string.join(self.presub_lines(env), '\n ')
|
| out = "Building %s with action:\n %s\n" % (t, l)
|
| sys.stdout.write(out)
|
| cmd = None
|
| if show and self.strfunction:
|
| - cmd = self.strfunction(target, source, env)
|
| + if executor:
|
| + target = executor.get_all_targets()
|
| + source = executor.get_all_sources()
|
| + try:
|
| + cmd = self.strfunction(target, source, env, executor)
|
| + except TypeError:
|
| + cmd = self.strfunction(target, source, env)
|
| if cmd:
|
| if chdir:
|
| cmd = ('os.chdir(%s)\n' % repr(chdir)) + cmd
|
| @@ -524,7 +558,7 @@
|
| if chdir:
|
| os.chdir(chdir)
|
| try:
|
| - stat = self.execute(target, source, env)
|
| + stat = self.execute(target, source, env, executor=executor)
|
| if isinstance(stat, SCons.Errors.BuildError):
|
| s = exitstatfunc(stat.status)
|
| if s:
|
| @@ -657,8 +691,11 @@
|
| return string.join(map(str, self.cmd_list), ' ')
|
| return str(self.cmd_list)
|
|
|
| - def process(self, target, source, env):
|
| - result = env.subst_list(self.cmd_list, 0, target, source)
|
| + def process(self, target, source, env, executor=None):
|
| + if executor:
|
| + result = env.subst_list(self.cmd_list, 0, executor=executor)
|
| + else:
|
| + result = env.subst_list(self.cmd_list, 0, target, source)
|
| silent = None
|
| ignore = None
|
| while 1:
|
| @@ -675,20 +712,23 @@
|
| pass
|
| return result, ignore, silent
|
|
|
| - def strfunction(self, target, source, env):
|
| + def strfunction(self, target, source, env, executor=None):
|
| if self.cmdstr is None:
|
| return None
|
| if self.cmdstr is not _null:
|
| from SCons.Subst import SUBST_RAW
|
| - c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
| + if executor:
|
| + c = env.subst(self.cmdstr, SUBST_RAW, executor=executor)
|
| + else:
|
| + c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
| if c:
|
| return c
|
| - cmd_list, ignore, silent = self.process(target, source, env)
|
| + cmd_list, ignore, silent = self.process(target, source, env, executor)
|
| if silent:
|
| return ''
|
| return _string_from_cmd_list(cmd_list[0])
|
|
|
| - def execute(self, target, source, env):
|
| + def execute(self, target, source, env, executor=None):
|
| """Execute a command action.
|
|
|
| This will handle lists of commands as well as individual commands,
|
| @@ -733,7 +773,10 @@
|
| # reasonable for just about everything else:
|
| ENV[key] = str(value)
|
|
|
| - cmd_list, ignore, silent = self.process(target, map(rfile, source), env)
|
| + if executor:
|
| + target = executor.get_all_targets()
|
| + source = executor.get_all_sources()
|
| + cmd_list, ignore, silent = self.process(target, map(rfile, source), env, executor)
|
|
|
| # Use len() to filter out any "command" that's zero-length.
|
| for cmd_line in filter(len, cmd_list):
|
| @@ -748,7 +791,7 @@
|
| command=cmd_line)
|
| return 0
|
|
|
| - def get_presig(self, target, source, env):
|
| + def get_presig(self, target, source, env, executor=None):
|
| """Return the signature contents of this action's command line.
|
|
|
| This strips $(-$) and everything in between the string,
|
| @@ -760,16 +803,22 @@
|
| cmd = string.join(map(str, cmd))
|
| else:
|
| cmd = str(cmd)
|
| - return env.subst_target_source(cmd, SUBST_SIG, target, source)
|
| + if executor:
|
| + return env.subst_target_source(cmd, SUBST_SIG, executor=executor)
|
| + else:
|
| + return env.subst_target_source(cmd, SUBST_SIG, target, source)
|
|
|
| - def get_implicit_deps(self, target, source, env):
|
| + def get_implicit_deps(self, target, source, env, executor=None):
|
| icd = env.get('IMPLICIT_COMMAND_DEPENDENCIES', True)
|
| if is_String(icd) and icd[:1] == '$':
|
| icd = env.subst(icd)
|
| if not icd or icd in ('0', 'None'):
|
| return []
|
| from SCons.Subst import SUBST_SIG
|
| - cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, target, source)
|
| + if executor:
|
| + cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, executor=executor)
|
| + else:
|
| + cmd_list = env.subst_list(self.cmd_list, SUBST_SIG, target, source)
|
| res = []
|
| for cmd_line in cmd_list:
|
| if cmd_line:
|
| @@ -785,14 +834,21 @@
|
| self.generator = generator
|
| self.gen_kw = kw
|
| self.varlist = kw.get('varlist', ())
|
| + self.targets = kw.get('targets', '$TARGETS')
|
|
|
| - def _generate(self, target, source, env, for_signature):
|
| + def _generate(self, target, source, env, for_signature, executor=None):
|
| # ensure that target is a list, to make it easier to write
|
| # generator functions:
|
| if not is_List(target):
|
| target = [target]
|
|
|
| - ret = self.generator(target=target, source=source, env=env, for_signature=for_signature)
|
| + if executor:
|
| + target = executor.get_all_targets()
|
| + source = executor.get_all_sources()
|
| + ret = self.generator(target=target,
|
| + source=source,
|
| + env=env,
|
| + for_signature=for_signature)
|
| #TODO(1.5) gen_cmd = Action(ret, **self.gen_kw)
|
| gen_cmd = apply(Action, (ret,), self.gen_kw)
|
| if not gen_cmd:
|
| @@ -809,28 +865,36 @@
|
| act = self._generate([], [], env, 1)
|
| return str(act)
|
|
|
| - def genstring(self, target, source, env):
|
| - return self._generate(target, source, env, 1).genstring(target, source, env)
|
| + def batch_key(self, env, target, source):
|
| + return self._generate(target, source, env, 1).batch_key(env, target, source)
|
|
|
| + def genstring(self, target, source, env, executor=None):
|
| + return self._generate(target, source, env, 1, executor).genstring(target, source, env)
|
| +
|
| def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
|
| - show=_null, execute=_null, chdir=_null):
|
| - act = self._generate(target, source, env, 0)
|
| + show=_null, execute=_null, chdir=_null, executor=None):
|
| + act = self._generate(target, source, env, 0, executor)
|
| + if act is None:
|
| + raise UserError("While building `%s': Cannot deduce file extension from source files: %s" % (repr(map(str, target)), repr(map(str, source))))
|
| return act(target, source, env, exitstatfunc, presub,
|
| - show, execute, chdir)
|
| + show, execute, chdir, executor)
|
|
|
| - def get_presig(self, target, source, env):
|
| + def get_presig(self, target, source, env, executor=None):
|
| """Return the signature contents of this action's command line.
|
|
|
| This strips $(-$) and everything in between the string,
|
| since those parts don't affect signatures.
|
| """
|
| - return self._generate(target, source, env, 1).get_presig(target, source, env)
|
| + return self._generate(target, source, env, 1, executor).get_presig(target, source, env)
|
|
|
| - def get_implicit_deps(self, target, source, env):
|
| - return self._generate(target, source, env, 1).get_implicit_deps(target, source, env)
|
| + def get_implicit_deps(self, target, source, env, executor=None):
|
| + return self._generate(target, source, env, 1, executor).get_implicit_deps(target, source, env)
|
|
|
| + def get_targets(self, env, executor):
|
| + return self._generate(None, None, env, 1, executor).get_targets(env, executor)
|
|
|
|
|
| +
|
| # A LazyAction is a kind of hybrid generator and command action for
|
| # strings of the form "$VAR". These strings normally expand to other
|
| # strings (think "$CCCOM" to "$CC -c -o $TARGET $SOURCE"), but we also
|
| @@ -864,14 +928,17 @@
|
| return CommandGeneratorAction
|
|
|
| def _generate_cache(self, env):
|
| - c = env.get(self.var, '')
|
| + if env:
|
| + c = env.get(self.var, '')
|
| + else:
|
| + c = ''
|
| #TODO(1.5) gen_cmd = Action(c, **self.gen_kw)
|
| gen_cmd = apply(Action, (c,), self.gen_kw)
|
| if not gen_cmd:
|
| raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c)))
|
| return gen_cmd
|
|
|
| - def _generate(self, target, source, env, for_signature):
|
| + def _generate(self, target, source, env, for_signature, executor=None):
|
| return self._generate_cache(env)
|
|
|
| def __call__(self, target, source, env, *args, **kw):
|
| @@ -915,12 +982,15 @@
|
| except AttributeError:
|
| return "unknown_python_function"
|
|
|
| - def strfunction(self, target, source, env):
|
| + def strfunction(self, target, source, env, executor=None):
|
| if self.cmdstr is None:
|
| return None
|
| if self.cmdstr is not _null:
|
| from SCons.Subst import SUBST_RAW
|
| - c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
| + if executor:
|
| + c = env.subst(self.cmdstr, SUBST_RAW, executor=executor)
|
| + else:
|
| + c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
| if c:
|
| return c
|
| def array(a):
|
| @@ -953,9 +1023,12 @@
|
| return str(self.execfunction)
|
| return "%s(target, source, env)" % name
|
|
|
| - def execute(self, target, source, env):
|
| + def execute(self, target, source, env, executor=None):
|
| exc_info = (None,None,None)
|
| try:
|
| + if executor:
|
| + target = executor.get_all_targets()
|
| + source = executor.get_all_sources()
|
| rsources = map(rfile, source)
|
| try:
|
| result = self.execfunction(target=target, source=rsources, env=env)
|
| @@ -971,7 +1044,10 @@
|
| result = SCons.Errors.convert_to_BuildError(result, exc_info)
|
| result.node=target
|
| result.action=self
|
| - result.command=self.strfunction(target, source, env)
|
| + try:
|
| + result.command=self.strfunction(target, source, env, executor)
|
| + except TypeError:
|
| + result.command=self.strfunction(target, source, env)
|
|
|
| # FIXME: This maintains backward compatibility with respect to
|
| # which type of exceptions were returned by raising an
|
| @@ -1013,6 +1089,7 @@
|
| # our children will have had any varlist
|
| # applied; we don't need to do it again
|
| self.varlist = ()
|
| + self.targets = '$TARGETS'
|
|
|
| def genstring(self, target, source, env):
|
| return string.join(map(lambda a, t=target, s=source, e=env:
|
| @@ -1038,10 +1115,13 @@
|
| "")
|
|
|
| def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
|
| - show=_null, execute=_null, chdir=_null):
|
| + show=_null, execute=_null, chdir=_null, executor=None):
|
| + if executor:
|
| + target = executor.get_all_targets()
|
| + source = executor.get_all_sources()
|
| for act in self.list:
|
| stat = act(target, source, env, exitstatfunc, presub,
|
| - show, execute, chdir)
|
| + show, execute, chdir, executor)
|
| if stat:
|
| return stat
|
| return 0
|
| @@ -1111,7 +1191,7 @@
|
| kw[key] = self.subst(self.kw[key], target, source, env)
|
| return kw
|
|
|
| - def __call__(self, target, source, env):
|
| + def __call__(self, target, source, env, executor=None):
|
| args = self.subst_args(target, source, env)
|
| kw = self.subst_kw(target, source, env)
|
| #TODO(1.5) return self.parent.actfunc(*args, **kw)
|
|
|