Index: third_party/scons/scons-local/SCons/Taskmaster.py |
=================================================================== |
--- third_party/scons/scons-local/SCons/Taskmaster.py (revision 9094) |
+++ third_party/scons/scons-local/SCons/Taskmaster.py (working copy) |
@@ -1,5 +1,5 @@ |
# |
-# 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 |
@@ -48,7 +48,7 @@ |
target(s) that it decides need to be evaluated and/or built. |
""" |
-__revision__ = "src/engine/SCons/Taskmaster.py 3842 2008/12/20 22:59:52 scons" |
+__revision__ = "src/engine/SCons/Taskmaster.py 3897 2009/01/13 06:45:54 scons" |
from itertools import chain |
import operator |
@@ -58,6 +58,7 @@ |
import SCons.Errors |
import SCons.Node |
+import SCons.Warnings |
StateString = SCons.Node.StateString |
NODE_NO_STATE = SCons.Node.no_state |
@@ -185,8 +186,9 @@ |
# target t.prepare() methods check that each target's explicit |
# or implicit dependencies exists, and also initialize the |
# .sconsign info. |
- self.targets[0].get_executor().prepare() |
- for t in self.targets: |
+ executor = self.targets[0].get_executor() |
+ executor.prepare() |
+ for t in executor.get_action_targets(): |
t.prepare() |
for s in t.side_effects: |
s.prepare() |
@@ -197,14 +199,14 @@ |
return self.node |
def needs_execute(self): |
- """ |
- Called to determine whether the task's execute() method should |
- be run. |
- |
- This method allows one to skip the somethat costly execution |
- of the execute() method in a seperate thread. For example, |
- that would be unnecessary for up-to-date targets. |
- """ |
+ # TODO(deprecate): "return True" is the old default behavior; |
+ # change it to NotImplementedError (after running through the |
+ # Deprecation Cycle) so the desired behavior is explicitly |
+ # determined by which concrete subclass is used. |
+ #raise NotImplementedError |
+ msg = ('Direct use of the Taskmaster.Task class will be deprecated\n' |
+ + '\tin a future release.') |
+ SCons.Warnings.warn(SCons.Warnings.TaskmasterNeedsExecuteWarning, msg) |
return True |
def execute(self): |
@@ -501,7 +503,31 @@ |
exc_traceback = None |
raise exc_type, exc_value, exc_traceback |
+class AlwaysTask(Task): |
+ def needs_execute(self): |
+ """ |
+ Always returns True (indicating this Task should always |
+ be executed). |
+ Subclasses that need this behavior (as opposed to the default |
+ of only executing Nodes that are out of date w.r.t. their |
+ dependencies) can use this as follows: |
+ |
+ class MyTaskSubclass(SCons.Taskmaster.Task): |
+ needs_execute = SCons.Taskmaster.Task.execute_always |
+ """ |
+ return True |
+ |
+class OutOfDateTask(Task): |
+ def needs_execute(self): |
+ """ |
+ Returns True (indicating this Task should be executed) if this |
+ Task's target state indicates it needs executing, which has |
+ already been determined by an earlier up-to-date check. |
+ """ |
+ return self.targets[0].get_state() == SCons.Node.executing |
+ |
+ |
def find_cycle(stack, visited): |
if stack[-1] in visited: |
return None |
@@ -521,11 +547,13 @@ |
The Taskmaster for walking the dependency DAG. |
""" |
- def __init__(self, targets=[], tasker=Task, order=None, trace=None): |
+ def __init__(self, targets=[], tasker=None, order=None, trace=None): |
self.original_top = targets |
self.top_targets_left = targets[:] |
self.top_targets_left.reverse() |
self.candidates = [] |
+ if tasker is None: |
+ tasker = OutOfDateTask |
self.tasker = tasker |
if not order: |
order = lambda l: l |
@@ -736,8 +764,10 @@ |
if T: T.write(self.trace_message(' already handled (executed)')) |
continue |
+ executor = node.get_executor() |
+ |
try: |
- children = node.children() |
+ children = executor.get_all_children() |
except SystemExit: |
exc_value = sys.exc_info()[1] |
e = SCons.Errors.ExplicitExit(node, exc_value.code) |
@@ -759,7 +789,7 @@ |
children_not_ready = [] |
children_failed = False |
- for child in chain(children,node.prerequisites): |
+ for child in chain(children, executor.get_all_prerequisites()): |
childstate = child.get_state() |
if T: T.write(self.trace_message(' ' + self.trace_node(child))) |
@@ -803,7 +833,8 @@ |
# added the other children to the list of candidate nodes |
# to keep on building (--keep-going). |
if children_failed: |
- node.set_state(NODE_FAILED) |
+ for n in executor.get_action_targets(): |
+ n.set_state(NODE_FAILED) |
if S: S.child_failed = S.child_failed + 1 |
if T: T.write(self.trace_message('****** %s\n' % self.trace_node(node))) |
@@ -834,7 +865,7 @@ |
# Skip this node if it has side-effects that are |
# currently being built: |
wait_side_effects = False |
- for se in node.side_effects: |
+ for se in executor.get_action_side_effects(): |
if se.get_state() == NODE_EXECUTING: |
se.add_to_waiting_s_e(node) |
wait_side_effects = True |
@@ -873,7 +904,7 @@ |
if node is None: |
return None |
- tlist = node.get_executor().targets |
+ tlist = node.get_executor().get_all_targets() |
task = self.tasker(self, tlist, node in self.original_top, node) |
try: |