diff options
-rw-r--r-- | src/engine/SCons/Node/FS.py | 47 | ||||
-rw-r--r-- | src/engine/SCons/Node/FSTests.py | 7 | ||||
-rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 6 | ||||
-rw-r--r-- | src/engine/SCons/Node/__init__.py | 72 | ||||
-rw-r--r-- | src/script/sconsign.py | 8 |
5 files changed, 88 insertions, 52 deletions
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 1863d93..50b725b 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1089,6 +1089,8 @@ class DummyExecutor: return '' def get_timestamp(self): return 0 + def get_build_env(self): + return None class Dir(Base): """A class for directories in a file system. @@ -1210,34 +1212,25 @@ class Dir(Base): else: return self.entries['..'].root() - def children(self, scan=1): - return filter(lambda x, i=self.ignore: x not in i, - self.all_children(scan)) - - def all_children(self, scan=1): - # Before we traverse our children, make sure we have created Nodes - # for any files that this directory contains. We need to do this - # so any change in a file in this directory will cause it to - # be out of date. - if not self.searched: - try: - for filename in self.fs.listdir(self.abspath): - if filename != '.sconsign': - self.Entry(filename) - except OSError: - # Directory does not exist. No big deal - pass - self.searched = 1 + def scan(self): + if not self.implicit is None: + return + self.implicit = [] + self.implicit_dict = {} + self._children_reset() + try: + for filename in self.fs.listdir(self.abspath): + if filename != '.sconsign': + self.Entry(filename) + except OSError: + # Directory does not exist. No big deal + pass keys = filter(lambda k: k != '.' and k != '..', self.entries.keys()) kids = map(lambda x, s=self: s.entries[x], keys) def c(one, two): - if one.abspath < two.abspath: - return -1 - if one.abspath > two.abspath: - return 1 - return 0 + return cmp(one.abspath, two.abspath) kids.sort(c) - return kids + SCons.Node.Node.all_children(self, 0) + self._add_child(self.implicit, self.implicit_dict, kids) def get_actions(self): """A null "builder" for directories.""" @@ -1259,7 +1252,7 @@ class Dir(Base): def get_contents(self): """Return aggregate contents of all our children.""" contents = cStringIO.StringIO() - for kid in self.children(None): + for kid in self.children(): contents.write(kid.get_contents()) return contents.getvalue() @@ -1270,7 +1263,7 @@ class Dir(Base): """If all of our children were up-to-date, then this directory was up-to-date, too.""" state = 0 - for kid in self.children(None): + for kid in self.children(): s = kid.get_state() if s and (not state or s > state): state = s @@ -1319,7 +1312,7 @@ class Dir(Base): def get_timestamp(self): """Return the latest timestamp from among our children""" stamp = 0 - for kid in self.children(None): + for kid in self.children(): if kid.get_timestamp() > stamp: stamp = kid.get_timestamp() return stamp diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index f537acf..d9ffd83 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -716,7 +716,7 @@ class FSTestCase(unittest.TestCase): dir = fs.Dir(drive) assert str(dir) == drive + os.sep, str(dir) - # Test Dir.children() + # Test Dir.scan() dir = fs.Dir('ddd') fs.File(string.join(['ddd', 'f1'], sep)) fs.File(string.join(['ddd', 'f2'], sep)) @@ -724,18 +724,19 @@ class FSTestCase(unittest.TestCase): fs.Dir(string.join(['ddd', 'd1'], sep)) fs.Dir(string.join(['ddd', 'd1', 'f4'], sep)) fs.Dir(string.join(['ddd', 'd1', 'f5'], sep)) + dir.scan() kids = map(lambda x: x.path, dir.children(None)) kids.sort() assert kids == [os.path.join('ddd', 'd1'), os.path.join('ddd', 'f1'), os.path.join('ddd', 'f2'), - os.path.join('ddd', 'f3')] + os.path.join('ddd', 'f3')], kids kids = map(lambda x: x.path_, dir.children(None)) kids.sort() assert kids == [os.path.join('ddd', 'd1', ''), os.path.join('ddd', 'f1'), os.path.join('ddd', 'f2'), - os.path.join('ddd', 'f3')] + os.path.join('ddd', 'f3')], kids # Test for a bug in 0.04 that did not like looking up # dirs with a trailing slash on Win32. diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index f14339e..4c7d9c2 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -399,6 +399,12 @@ class NodeTestCase(unittest.TestCase): node = SCons.Node.Node() binfo = node.gen_binfo(Calculator(666)) assert isinstance(binfo, SCons.Node.BuildInfo), binfo + assert hasattr(binfo, 'bsources') + assert hasattr(binfo, 'bsourcesigs') + assert hasattr(binfo, 'bdepends') + assert hasattr(binfo, 'bdependsigs') + assert hasattr(binfo, 'bimplicit') + assert hasattr(binfo, 'bimplicitsigs') assert binfo.bsig == 666, binfo.bsig def test_explain(self): diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 24c70b8..65cb683 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -524,12 +524,30 @@ class Node: binfo = self.new_binfo() - children = self.children() + self.scan() - sigs = map(lambda n, c=calc: n.calc_signature(c), children) + sources = self.filter_ignore(self.sources) + depends = self.filter_ignore(self.depends) + if self.implicit is None: + implicit = [] + else: + implicit = self.filter_ignore(self.implicit) + + def calc_signature(node, calc=calc): + return node.calc_signature(calc) + sourcesigs = map(calc_signature, sources) + dependsigs = map(calc_signature, depends) + implicitsigs = map(calc_signature, implicit) + + binfo.bsources = map(str, sources) + binfo.bdepends = map(str, depends) + binfo.bimplicit = map(str, implicit) - binfo.bkids = map(str, children) - binfo.bkidsigs = sigs[:] + binfo.bsourcesigs = sourcesigs + binfo.bdependsigs = dependsigs + binfo.bimplicitsigs = implicitsigs + + sigs = sourcesigs + dependsigs + implicitsigs if self.has_builder(): executor = self.get_executor() @@ -672,6 +690,14 @@ class Node: except AttributeError: pass + def filter_ignore(self, nodelist): + ignore = self.ignore + result = [] + for node in nodelist: + if node not in ignore: + result.append(node) + return result + def children(self, scan=1): """Return a list of the node's direct children, minus those that are ignored by this node.""" @@ -680,10 +706,9 @@ class Node: try: return self._children except AttributeError: - c = filter(lambda x, i=self.ignore: x not in i, - self.all_children(scan=0)) - self._children = c - return c + c = self.all_children(scan=0) + self._children = self.filter_ignore(c) + return self._children def all_children(self, scan=1): """Return a list of all the node's direct children.""" @@ -830,26 +855,35 @@ class Node: if old is None: return None - def dictify(kids, sigs): - result = {} + def dictify(result, kids, sigs): for k, s in zip(kids, sigs): result[k] = s - return result try: - osig = dictify(old.bkids, old.bkidsigs) + old_bkids = old.bsources + old.bdepends + old.bimplicit except AttributeError: return "Cannot explain why `%s' is being rebuilt: No previous build information found\n" % self + osig = {} + dictify(osig, old.bsources, old.bsourcesigs) + dictify(osig, old.bdepends, old.bdependsigs) + dictify(osig, old.bimplicit, old.bimplicitsigs) + + new_bsources = map(str, self.binfo.bsources) + new_bdepends = map(str, self.binfo.bdepends) + new_bimplicit = map(str, self.binfo.bimplicit) - newkids = map(str, self.binfo.bkids) - nsig = dictify(newkids, self.binfo.bkidsigs) + nsig = {} + dictify(nsig, new_bsources, self.binfo.bsourcesigs) + dictify(nsig, new_bdepends, self.binfo.bdependsigs) + dictify(nsig, new_bimplicit, self.binfo.bimplicitsigs) + new_bkids = new_bsources + new_bdepends + new_bimplicit lines = map(lambda x: "`%s' is no longer a dependency\n" % x, - filter(lambda x, nk=newkids: not x in nk, old.bkids)) + filter(lambda x, nk=new_bkids: not x in nk, old_bkids)) - for k in newkids: - if not k in old.bkids: + for k in new_bkids: + if not k in old_bkids: lines.append("`%s' is a new dependency\n" % k) elif osig[k] != nsig[k]: lines.append("`%s' changed\n" % k) @@ -863,8 +897,8 @@ class Node: if len(lines) == 0: lines.append("the dependency order changed:\n" + - "%sold: %s\n" % (' '*15, old.bkids) + - "%snew: %s\n" % (' '*15, newkids)) + "%sold: %s\n" % (' '*15, old_bkids) + + "%snew: %s\n" % (' '*15, new_bkids)) preamble = "rebuilding `%s' because" % self if len(lines) == 1: diff --git a/src/script/sconsign.py b/src/script/sconsign.py index e4b7b07..a886fee 100644 --- a/src/script/sconsign.py +++ b/src/script/sconsign.py @@ -203,12 +203,14 @@ def map_timestamp(entry, name): return str(timestamp) def map_bkids(entry, name): - result = [] try: - for i in xrange(len(entry.bkids)): - result.append("%s: %s" % (entry.bkids[i], entry.bkidsigs[i])) + bkids = entry.bsources + entry.bdepends + entry.bimplicit + bkidsigs = entry.bsourcesigs + entry.bdependsigs + entry.bimplicitsigs except AttributeError: return None + result = [] + for i in xrange(len(bkids)): + result.append("%s: %s" % (bkids[i], bkidsigs[i])) if result == []: return None return string.join(result, "\n ") |