summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/engine/SCons/Debug.py1
-rw-r--r--src/engine/SCons/Node/FS.py53
-rw-r--r--src/engine/SCons/Node/NodeTests.py21
-rw-r--r--src/engine/SCons/Node/__init__.py14
-rw-r--r--src/engine/SCons/SConf.py11
-rw-r--r--src/engine/SCons/SConsign.py19
-rw-r--r--src/engine/SCons/SConsignTests.py29
-rw-r--r--src/engine/SCons/Sig/__init__.py4
8 files changed, 107 insertions, 45 deletions
diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py
index 0dbb116..179eb66 100644
--- a/src/engine/SCons/Debug.py
+++ b/src/engine/SCons/Debug.py
@@ -122,6 +122,7 @@ def caller(back=0):
entry[key] = entry[key] + 1
except KeyError:
entry[key] = 1
+ return '%s:%d(%s)' % func_shorten(key)
def dump_caller_counts(file=sys.stdout):
keys = caller_dicts.keys()
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 07093d0..c728ece 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -1465,12 +1465,52 @@ class RootDir(Dir):
return _null
class BuildInfo:
+ # bsig needs to stay here, if it's initialized in __init__() then
+ # the assignment overwrites any values read from .sconsign files.
bsig = None
+ def __init__(self, node):
+ self.node = node
def __cmp__(self, other):
try:
return cmp(self.bsig, other.bsig)
except AttributeError:
return 1
+ def convert_to_sconsign(self):
+ """Convert this BuildInfo object for writing to a .sconsign file
+
+ We hung onto the node that we refer to so that we can translate
+ the lists of bsources, bdepends and bimplicit Nodes into strings
+ relative to the node, but we don't want to write out that Node
+ itself to the .sconsign file, so we delete the attribute in
+ preparation.
+ """
+ rel_path = self.node.rel_path
+ delattr(self, 'node')
+ for attr in ['bsources', 'bdepends', 'bimplicit']:
+ try:
+ val = getattr(self, attr)
+ except AttributeError:
+ pass
+ else:
+ setattr(self, attr, map(rel_path, val))
+ def convert_from_sconsign(self, dir, name):
+ """Convert a newly-read BuildInfo object for in-SCons use
+
+ An on-disk BuildInfo comes without a reference to the node
+ for which it's intended, so we have to convert the arguments
+ and add back a self.node attribute. The bsources, bdepends and
+ bimplicit lists all come from disk as paths relative to that node,
+ so convert them to actual Nodes for use by the rest of SCons.
+ """
+ self.node = dir.Entry(name)
+ Entry_func = self.node.dir.Entry
+ for attr in ['bsources', 'bdepends', 'bimplicit']:
+ try:
+ val = getattr(self, attr)
+ except AttributeError:
+ pass
+ else:
+ setattr(self, attr, map(Entry_func, val))
class File(Base):
"""A class for files in a file system.
@@ -1537,7 +1577,7 @@ class File(Base):
try:
stored = self.dir.sconsign().get_entry(self.name)
except (KeyError, OSError):
- return BuildInfo()
+ return self.new_binfo()
else:
if isinstance(stored, BuildInfo):
return stored
@@ -1546,16 +1586,15 @@ class File(Base):
# 0.95 or before. The relevant attribute names are the same,
# though, so just copy the attributes over to an object of
# the correct type.
- binfo = BuildInfo()
+ binfo = self.new_binfo()
for key, val in stored.__dict__.items():
setattr(binfo, key, val)
return binfo
def get_stored_implicit(self):
binfo = self.get_stored_info()
- try: implicit = binfo.bimplicit
+ try: return binfo.bimplicit
except AttributeError: return None
- else: return map(self.dir.Entry, implicit)
def rel_path(self, other):
return self.dir.rel_path(other)
@@ -1727,7 +1766,7 @@ class File(Base):
return Base.exists(self)
def new_binfo(self):
- return BuildInfo()
+ return BuildInfo(self)
def del_cinfo(self):
try:
@@ -1759,7 +1798,7 @@ class File(Base):
if calc.max_drift >= 0:
old = self.get_stored_info()
else:
- old = BuildInfo()
+ old = self.new_binfo()
try:
mtime = self.get_timestamp()
@@ -1810,7 +1849,7 @@ class File(Base):
return None
else:
old = self.get_stored_info()
- return (old == self.binfo)
+ return (self.binfo == old)
def rfile(self):
"__cacheable__"
diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py
index 70b9672..3be1d6b 100644
--- a/src/engine/SCons/Node/NodeTests.py
+++ b/src/engine/SCons/Node/NodeTests.py
@@ -503,24 +503,19 @@ class NodeTestCase(unittest.TestCase):
"""Test generating a build information structure
"""
node = SCons.Node.Node()
- binfo = node.gen_binfo(Calculator(666))
+ d = SCons.Node.Node()
+ i = SCons.Node.Node()
+ node.depends = [d]
+ node.implicit = [i]
+ binfo = node.gen_binfo(Calculator(1998))
assert isinstance(binfo, SCons.Node.BuildInfo), binfo
assert hasattr(binfo, 'bsources')
assert hasattr(binfo, 'bsourcesigs')
- assert hasattr(binfo, 'bdepends')
+ assert binfo.bdepends == [d]
assert hasattr(binfo, 'bdependsigs')
- assert hasattr(binfo, 'bimplicit')
+ assert binfo.bimplicit == [i]
assert hasattr(binfo, 'bimplicitsigs')
- assert binfo.bsig == 666, binfo.bsig
-
- def test_rel_path(self):
- """Test the rel_path() method
- """
- node = SCons.Node.Node()
- other = SCons.Node.Node()
- other.__str__ = lambda: "xyzzy"
- r = node.rel_path(other)
- assert r == "xyzzy", r
+ assert binfo.bsig == 5994, binfo.bsig
def test_explain(self):
"""Test explaining why a Node must be rebuilt
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index b9d5a75..627d020 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -574,7 +574,7 @@ class Node:
def calc_signature(node, calc=calc):
return node.calc_signature(calc)
- bsources = executor.process_sources(self.rel_path, self.ignore)
+ sources = executor.process_sources(None, self.ignore)
sourcesigs = executor.process_sources(calc_signature, self.ignore)
depends = self.depends
@@ -594,9 +594,9 @@ class Node:
binfo.bactsig = calc.module.signature(executor)
sigs.append(binfo.bactsig)
- binfo.bsources = bsources
- binfo.bdepends = map(self.rel_path, depends)
- binfo.bimplicit = map(self.rel_path, implicit)
+ binfo.bsources = sources
+ binfo.bdepends = depends
+ binfo.bimplicit = implicit
binfo.bsourcesigs = sourcesigs
binfo.bdependsigs = dependsigs
@@ -606,12 +606,6 @@ class Node:
return binfo
- def rel_path(self, other):
- # Using other.__str__() instead of str(other) lets the Memoizer
- # get the right method for the underlying Node object, not the
- # __str__() method for the Memoizer wrapper object.
- return other.__str__()
-
def del_cinfo(self):
try:
del self.binfo.csig
diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py
index b89ca4a..3d1a145 100644
--- a/src/engine/SCons/SConf.py
+++ b/src/engine/SCons/SConf.py
@@ -159,7 +159,8 @@ class SConfBuildInfo(SCons.Node.FS.BuildInfo):
result = None # -> 0/None -> no error, != 0 error
string = None # the stdout / stderr output when building the target
- def __init__(self, result, string, sig):
+ def __init__(self, node, result, string, sig):
+ SCons.Node.FS.BuildInfo.__init__(self, node)
self.result = result
self.string = string
self.bsig = sig
@@ -305,15 +306,15 @@ class SConfBuildTask(SCons.Taskmaster.Task):
for t in self.targets:
sig = t.calc_signature(sconf.calc)
string = s.getvalue()
- t.dir.sconsign().set_entry(t.name,
- SConfBuildInfo(1,string,sig))
+ binfo = SConfBuildInfo(t,1,string,sig)
+ t.dir.sconsign().set_entry(t.name, binfo)
raise
else:
for t in self.targets:
sig = t.calc_signature(sconf.calc)
string = s.getvalue()
- t.dir.sconsign().set_entry(t.name,
- SConfBuildInfo(0,string,sig))
+ binfo = SConfBuildInfo(t,0,string,sig)
+ t.dir.sconsign().set_entry(t.name, binfo)
class SConf:
"""This is simply a class to represent a configure context. After
diff --git a/src/engine/SCons/SConsign.py b/src/engine/SCons/SConsign.py
index cbe0b8c..073cfc4 100644
--- a/src/engine/SCons/SConsign.py
+++ b/src/engine/SCons/SConsign.py
@@ -177,9 +177,11 @@ class DB(Base):
raise TypeError
except KeyboardInterrupt:
raise
- except:
+ except Exception, e:
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
- "Ignoring corrupt sconsign entry : %s"%self.dir.tpath)
+ "Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.tpath, e))
+ for key, entry in self.entries.items():
+ entry.convert_from_sconsign(dir, key)
if mode == "r":
# This directory is actually under a repository, which means
@@ -202,6 +204,8 @@ class DB(Base):
# the Repository; we only write to our own .sconsign file,
# not to .sconsign files in Repositories.
path = norm_entry(self.dir.path)
+ for key, entry in self.entries.items():
+ entry.convert_to_sconsign()
db[path] = cPickle.dumps(self.entries, 1)
if sync:
@@ -256,6 +260,15 @@ class DirFile(Dir):
global sig_files
sig_files.append(self)
+ def get_entry(self, filename):
+ """
+ Fetch the specified entry attribute, converting from .sconsign
+ format to in-memory format.
+ """
+ entry = Dir.get_entry(self, filename)
+ entry.convert_from_sconsign(self.dir, filename)
+ return entry
+
def write(self, sync=1):
"""
Write the .sconsign file to disk.
@@ -280,6 +293,8 @@ class DirFile(Dir):
fname = self.sconsign
except IOError:
return
+ for key, entry in self.entries.items():
+ entry.convert_to_sconsign()
cPickle.dump(self.entries, file, 1)
file.close()
if fname != self.sconsign:
diff --git a/src/engine/SCons/SConsignTests.py b/src/engine/SCons/SConsignTests.py
index 025ad8e..e292aed 100644
--- a/src/engine/SCons/SConsignTests.py
+++ b/src/engine/SCons/SConsignTests.py
@@ -35,6 +35,10 @@ import SCons.SConsign
class BuildInfo:
def __init__(self, name):
self.name = name
+ def convert_to_sconsign(self):
+ self.c_to_s = 1
+ def convert_from_sconsign(self, dir, name):
+ self.c_from_s = 1
class DummyModule:
def to_string(self, sig):
@@ -159,22 +163,26 @@ class SConsignDBTestCase(SConsignTestCase):
class SConsignDirFileTestCase(SConsignTestCase):
def runTest(self):
- foo = BuildInfo('foo')
- bar = BuildInfo('bar')
+ bi_foo = BuildInfo('foo')
+ bi_bar = BuildInfo('bar')
f = SCons.SConsign.DirFile(DummyNode(), DummyModule())
- f.set_entry('foo', foo)
- f.set_entry('bar', bar)
+ f.set_entry('foo', bi_foo)
+ f.set_entry('bar', bi_bar)
e = f.get_entry('foo')
- assert e == foo, e
+ assert e == bi_foo, e
assert e.name == 'foo', e.name
+ assert bi_foo.c_from_s, bi_foo.c_from_s
+
e = f.get_entry('bar')
- assert e == bar, e
+ assert e == bi_bar, e
assert e.name == 'bar', e.name
assert not hasattr(e, 'arg'), e
+ assert bi_bar.c_from_s, bi_bar.c_from_s
+
bbb = BuildInfo('bbb')
bbb.arg = 'bbb arg'
f.set_entry('bar', bbb)
@@ -257,11 +265,16 @@ class writeTestCase(SConsignTestCase):
f = SCons.SConsign.DB(DummyNode(), DummyModule())
- f.set_entry('foo', BuildInfo('foo'))
- f.set_entry('bar', BuildInfo('bar'))
+ bi_foo = BuildInfo('foo')
+ bi_bar = BuildInfo('bar')
+ f.set_entry('foo', bi_foo)
+ f.set_entry('bar', bi_bar)
SCons.SConsign.write()
+ assert bi_foo.c_to_s, bi_foo.c_to_s
+ assert bi_bar.c_to_s, bi_bar.c_to_s
+
assert fake_dbm.sync_count == 1, fake_dbm.sync_count
diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py
index 2a9680e..d746dfa 100644
--- a/src/engine/SCons/Sig/__init__.py
+++ b/src/engine/SCons/Sig/__init__.py
@@ -47,6 +47,10 @@ class SConsignEntry:
bsig = None
csig = None
implicit = None
+ def convert_to_sconsign(self):
+ pass
+ def convert_from_sconsign(self, dir, name):
+ pass
class Calculator:
"""