summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/engine/SCons/Node/FS.py47
-rw-r--r--src/engine/SCons/Node/FSTests.py7
-rw-r--r--src/engine/SCons/Node/NodeTests.py6
-rw-r--r--src/engine/SCons/Node/__init__.py72
-rw-r--r--src/script/sconsign.py8
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 ")