diff options
| author | Steven Knight <knight@baldmt.com> | 2001-10-24 14:18:02 (GMT) |
|---|---|---|
| committer | Steven Knight <knight@baldmt.com> | 2001-10-24 14:18:02 (GMT) |
| commit | 6a98a941a75eab2e4c22fa3e19cb973046f613b6 (patch) | |
| tree | fbedd2a2caa8c7d0e4a1e4b774adc6e1b1ed6d8e /src/engine/SCons/Taskmaster.py | |
| parent | 908b74a3a3ecba5eccc6fd1f844505050d9dad2f (diff) | |
| download | SCons-6a98a941a75eab2e4c22fa3e19cb973046f613b6.zip SCons-6a98a941a75eab2e4c22fa3e19cb973046f613b6.tar.gz SCons-6a98a941a75eab2e4c22fa3e19cb973046f613b6.tar.bz2 | |
Add -k support and more
Diffstat (limited to 'src/engine/SCons/Taskmaster.py')
| -rw-r--r-- | src/engine/SCons/Taskmaster.py | 89 |
1 files changed, 68 insertions, 21 deletions
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 3fd787e..3b4ee85 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -46,6 +46,9 @@ class Task: def set_state(self, state): return self.target.set_state(state) + + def get_target(self): + return self.target def current(node): """Default SCons build engine is-it-current function. @@ -64,38 +67,55 @@ class Taskmaster: the base class method, so this class can do it's thing. """ - def __init__(self, targets=[], tasker=Task, current=current): + def __init__(self, + targets=[], + tasker=Task, + current=current, + ignore_errors=0, + keep_going_on_error=0): self.walkers = map(SCons.Node.Walker, targets) self.tasker = tasker self.current = current self.targets = targets + self.ready = [] + self.pending = 0 + self.ignore_errors = ignore_errors + self.keep_going_on_error = keep_going_on_error + self._find_next_ready_node() + def next_task(self): + if self.ready: + n = self.ready.pop() + n.set_state(SCons.Node.executing) + if not self.ready: + self._find_next_ready_node() + + return self.tasker(n) + else: + return None + + def _find_next_ready_node(self): + """Find the next node that is ready to be built""" while self.walkers: n = self.walkers[0].next() if n == None: self.walkers.pop(0) elif n.get_state() == SCons.Node.up_to_date: self.up_to_date(n, self.walkers[0].is_done()) - elif n.get_state() == SCons.Node.failed: - # XXX do the right thing here - pass - elif n.get_state() == SCons.Node.executing: - # XXX do the right thing here - pass - elif n.get_state() == SCons.Node.executed: - # skip this node because it has already been executed - pass - elif self.current(n): - n.set_state(SCons.Node.up_to_date) - self.up_to_date(n, self.walkers[0].is_done()) - else: - n.set_state(SCons.Node.executing) - return self.tasker(n) - return None - + elif n.get_state() == None: + if not n.children_are_executed(): + n.set_state(SCons.Node.pending) + self.pending = self.pending + 1 + elif self.current(n): + n.set_state(SCons.Node.up_to_date) + self.up_to_date(n, self.walkers[0].is_done()) + else: + self.ready.append(n) + return + def is_blocked(self): - return 0 + return not self.ready and self.pending def up_to_date(self, node): pass @@ -103,6 +123,33 @@ class Taskmaster: def executed(self, task): task.set_state(SCons.Node.executed) + # add all the pending parents that are now executable to the 'ready' + # queue: + n = task.get_target() + ready = filter(lambda x: (x.get_state() == SCons.Node.pending + and x.children_are_executed()), + n.get_parents()) + self.ready.extend(ready) + self.pending = self.pending - len(ready) + def failed(self, task): - self.walkers = [] - task.set_state(SCons.Node.failed) + if self.ignore_errors: + self.executed(task) + else: + if self.keep_going_on_error: + # mark all the depants of this node as failed: + def get_parents(node): return node.get_parents() + walker = SCons.Node.Walker(task.get_target(), get_parents) + while 1: + node = walker.next() + if node == None: break + if node.get_state() == SCons.Node.pending: + self.pending = self.pending - 1 + node.set_state(SCons.Node.failed) + else: + # terminate the build: + self.walkers = [] + self.pending = 0 + self.ready = [] + + task.set_state(SCons.Node.failed) |
