diff options
-rw-r--r-- | src/engine/SCons/Taskmaster.py | 37 | ||||
-rw-r--r-- | src/engine/SCons/TaskmasterTests.py | 64 | ||||
-rw-r--r-- | src/script/scons.py | 21 | ||||
-rw-r--r-- | test/up-to-date.py | 2 |
4 files changed, 71 insertions, 53 deletions
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 9e8e105..0b96999 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -45,7 +45,8 @@ class Task: self.top = top def execute(self): - self.target.build() + if not self.target.get_state() == SCons.Node.up_to_date: + self.target.build() def get_target(self): return self.target @@ -56,13 +57,11 @@ class Task: def set_state(self, state): self.target.set_state(state) - def up_to_date(self): - self.set_state(SCons.Node.up_to_date) - def executed(self): - self.set_state(SCons.Node.executed) - self.tm.add_pending(self.target) - self.target.set_signature(self.sig) + if self.target.get_state() == SCons.Node.executing: + self.set_state(SCons.Node.executed) + self.tm.add_pending(self.target) + self.target.set_signature(self.sig) def failed(self): self.fail_stop() @@ -114,16 +113,15 @@ class Taskmaster: self.walkers = map(SCons.Node.Walker, targets) self.tasker = tasker self.calc = calc - self.targets = targets self.ready = [] self.pending = 0 - + self._find_next_ready_node() def next_task(self): if self.ready: task = self.ready.pop() - task.set_state(SCons.Node.executing) + if not self.ready: self._find_next_ready_node() return task @@ -146,6 +144,10 @@ class Taskmaster: # but mark it as "up to date" so targets won't # wait for it. n.set_state(SCons.Node.up_to_date) + # set the signature for non-derived files + # here so they don't get recalculated over + # and over again: + n.set_signature(self.calc.get_signature(n)) continue task = self.tasker(self, n, self.walkers[0].is_done()) if not n.children_are_executed(): @@ -156,11 +158,13 @@ class Taskmaster: sig = self.calc.get_signature(n) task.set_sig(sig) if self.calc.current(n, sig): - task.up_to_date() + task.set_state(SCons.Node.up_to_date) else: - self.ready.append(task) - return None - + task.set_state(SCons.Node.executing) + + self.ready.append(task) + return + def is_blocked(self): return not self.ready and self.pending @@ -181,9 +185,10 @@ class Taskmaster: sig = self.calc.get_signature(n) task.set_sig(sig) if self.calc.current(n, sig): - task.up_to_date() + task.set_state(SCons.Node.up_to_date) else: - self.ready.append(task) + task.set_state(SCons.Node.executing) + self.ready.append(task) self.pending = self.pending - len(ready) def remove_pending(self, node): diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index a15a673..00a91eb 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -103,21 +103,6 @@ class Node: -class Task: - def __init__(self, target): - self.target = target - - def get_target(self): - return self.target - - def up_to_date(self): - pass - - def executed(self): - pass - - def failed(self): - pass class TaskmasterTestCase(unittest.TestCase): @@ -157,29 +142,47 @@ class TaskmasterTestCase(unittest.TestCase): assert tm.next_task() == None - built = "up to date: " - global top_node top_node = n3 - class MyTask(SCons.Taskmaster.Task): - def up_to_date(self): - if self.target == top_node: - assert self.top - global built - built = built + " " + self.target.name - SCons.Taskmaster.Task.up_to_date(self) class MyCalc(SCons.Taskmaster.Calc): def current(self, node, sig): return 1 + class MyTask(SCons.Taskmaster.Task): + def execute(self): + global built + if self.target.get_state() == SCons.Node.up_to_date: + if self.top: + built = self.target.name + " up-to-date top" + else: + built = self.target.name + " up-to-date" + else: + self.target.build() + n1.set_state(None) n2.set_state(None) n3.set_state(None) tm = SCons.Taskmaster.Taskmaster(targets = [n3], tasker = MyTask, calc = MyCalc()) + + t = tm.next_task() + t.execute() + print built + assert built == "n1 up-to-date" + t.executed() + + t = tm.next_task() + t.execute() + assert built == "n2 up-to-date" + t.executed() + + t = tm.next_task() + t.execute() + assert built == "n3 up-to-date top" + t.executed() + assert tm.next_task() == None - assert built == "up to date: n1 n2 n3" n1 = Node("n1") @@ -226,6 +229,17 @@ class TaskmasterTestCase(unittest.TestCase): n4.set_state(SCons.Node.executed) tm = SCons.Taskmaster.Taskmaster([n4]) assert tm.next_task() == None + + n1 = Node("n1") + n2 = Node("n2", [n1]) + tm = SCons.Taskmaster.Taskmaster([n2,n2]) + t = tm.next_task() + assert tm.is_blocked() + t.executed() + assert not tm.is_blocked() + t = tm.next_task() + assert tm. next_task() == None + def test_is_blocked(self): """Test whether a task is blocked diff --git a/src/script/scons.py b/src/script/scons.py index 5f5d45d..8f48f9c 100644 --- a/src/script/scons.py +++ b/src/script/scons.py @@ -61,17 +61,16 @@ from SCons.Defaults import * class BuildTask(SCons.Taskmaster.Task): """An SCons build task.""" def execute(self): - try: - self.target.build() - except BuildError, e: - sys.stderr.write("scons: *** [%s] Error %d\n" % (e.node, e.stat)) - raise - - def up_to_date(self): - if self.top: - print 'scons: "%s" is up to date.' % str(self.target) - SCons.Taskmaster.Task.up_to_date(self) - + if self.target.get_state() == SCons.Node.up_to_date: + if self.top: + print 'scons: "%s" is up to date.' % str(self.target) + else: + try: + self.target.build() + except BuildError, e: + sys.stderr.write("scons: *** [%s] Error %d\n" % (e.node, e.stat)) + raise + def failed(self): global ignore_errors if ignore_errors: diff --git a/test/up-to-date.py b/test/up-to-date.py index cb17621..dd7d86a 100644 --- a/test/up-to-date.py +++ b/test/up-to-date.py @@ -59,8 +59,8 @@ test.run(arguments = 'f1.out f3.out') test.run(arguments = 'f1.out f2.out f3.out f4.out', stdout = """scons: "f1.out" is up to date. -scons: "f3.out" is up to date. %s build.py f2.out f2.in +scons: "f3.out" is up to date. %s build.py f4.out f4.in """ % (python, python)) |