summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/engine/SCons/Taskmaster.py37
-rw-r--r--src/engine/SCons/TaskmasterTests.py64
-rw-r--r--src/script/scons.py21
-rw-r--r--test/up-to-date.py2
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))