summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/SCons')
-rw-r--r--src/engine/SCons/Node/FS.py65
-rw-r--r--src/engine/SCons/Node/__init__.py84
-rw-r--r--src/engine/SCons/Sig/MD5.py6
3 files changed, 114 insertions, 41 deletions
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index ff4dfb5..c226504 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -378,9 +378,11 @@ class Entry(SCons.Node.Node):
return self._exists
def rexists(self):
- if not hasattr(self, '_rexists'):
+ try:
+ return self._rexists
+ except AttributeError:
self._rexists = self.rfile().exists()
- return self._rexists
+ return self._rexists
def get_parents(self):
parents = SCons.Node.Node.get_parents(self)
@@ -1112,25 +1114,28 @@ class File(Entry):
else:
return 0
- def calc_signature(self, calc, cache=None):
+ def calc_signature(self, calc):
"""
Select and calculate the appropriate build signature for a File.
self - the File node
calc - the signature calculation module
- cache - alternate node to use for the signature cache
returns - the signature
"""
-
- if self.is_derived():
- if SCons.Sig.build_signature:
- return calc.bsig(self.rfile(), self)
+ try:
+ return self._calculated_sig
+ except AttributeError:
+ if self.is_derived():
+ if SCons.Sig.build_signature:
+ sig = self.rfile().calc_bsig(calc, self)
+ else:
+ sig = self.rfile().calc_csig(calc, self)
+ elif not self.rexists():
+ sig = None
else:
- return calc.csig(self.rfile(), self)
- elif not self.rexists():
- return None
- else:
- return calc.csig(self.rfile(), self)
+ sig = self.rfile().calc_csig(calc, self)
+ self._calculated_sig = sig
+ return sig
def store_csig(self):
self.dir.sconsign().set_csig(self.name, self.get_csig())
@@ -1208,10 +1213,14 @@ class File(Entry):
# created the directory, depending on whether the -n
# option was used or not. Delete the _exists and
# _rexists attributes so they can be reevaluated.
- if hasattr(dirnode, '_exists'):
+ try:
delattr(dirnode, '_exists')
- if hasattr(dirnode, '_rexists'):
+ except AttributeError:
+ pass
+ try:
delattr(dirnode, '_rexists')
+ except AttributeError:
+ pass
except OSError:
pass
@@ -1253,10 +1262,14 @@ class File(Entry):
CachePush(self, None, None)
SCons.Node.Node.built(self)
self.found_includes = {}
- if hasattr(self, '_exists'):
+ try:
delattr(self, '_exists')
- if hasattr(self, '_rexists'):
+ except AttributeError:
+ pass
+ try:
delattr(self, '_rexists')
+ except AttributeError:
+ pass
def visited(self):
if self.fs.CachePath and self.fs.cache_force and os.path.exists(self.path):
@@ -1321,8 +1334,10 @@ class File(Entry):
except OSError, e:
raise SCons.Errors.BuildError(node = self,
errstr = e.strerror)
- if hasattr(self, '_exists'):
+ try:
delattr(self, '_exists')
+ except AttributeError:
+ pass
else:
try:
self._createDir()
@@ -1357,10 +1372,14 @@ class File(Entry):
# created the file, depending on whether the -n
# option was used or not. Delete the _exists and
# _rexists attributes so they can be reevaluated.
- if hasattr(self, '_exists'):
+ try:
delattr(self, '_exists')
- if hasattr(self, '_rexists'):
+ except AttributeError:
+ pass
+ try:
delattr(self, '_rexists')
+ except AttributeError:
+ pass
return Entry.exists(self)
def current(self, calc):
@@ -1384,14 +1403,16 @@ class File(Entry):
return calc.current(self, bsig)
def rfile(self):
- if not hasattr(self, '_rfile'):
+ try:
+ return self._rfile
+ except:
self._rfile = self
if not self.exists():
n = self.fs.Rsearch(self.path, clazz=File,
cwd=self.fs.Top)
if n:
self._rfile = n
- return self._rfile
+ return self._rfile
def rstr(self):
return str(self.rfile())
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index f2d77ce..43ae7c5 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -209,6 +209,14 @@ class Node:
self.set_state(None)
self.del_bsig()
self.del_csig()
+ try:
+ delattr(self, '_calculated_sig')
+ except AttributeError:
+ pass
+ try:
+ delattr(self, '_tempbsig')
+ except AttributeError:
+ pass
self.includes = None
self.found_includes = {}
self.implicit = None
@@ -383,37 +391,63 @@ class Node:
return
self.env = env
- def calc_signature(self, calc, cache=None):
+ def calc_signature(self, calc):
"""
Select and calculate the appropriate build signature for a node.
self - the node
calc - the signature calculation module
- cache - alternate node to use for the signature cache
returns - the signature
"""
-
- if self.has_builder():
- if SCons.Sig.build_signature:
- return calc.bsig(self, cache)
+ try:
+ return self._calculated_sig
+ except AttributeError:
+ if self.has_builder():
+ if SCons.Sig.build_signature:
+ sig = self.calc_bsig(calc)
+ else:
+ sig = self.calc_csig(calc)
+ elif not self.exists():
+ sig = None
else:
- return calc.csig(self, cache)
- elif not self.exists():
- return None
- else:
- return calc.csig(self, cache)
+ sig = self.calc_csig(calc)
+ self._calculated_sig = sig
+ return sig
+
+ def calc_bsig(self, calc, cache=None):
+ """Return the node's build signature, calculating it first
+ if necessary.
+
+ Note that we don't save it in the "real" build signature
+ attribute if we have to calculate it here; the "real" build
+ signature only gets updated after a file is actually built.
+ """
+ if cache is None: cache = self
+ try:
+ return cache.bsig
+ except AttributeError:
+ try:
+ return cache._tempbsig
+ except AttributeError:
+ cache._tempbsig = calc.bsig(self, cache)
+ return cache._tempbsig
def get_bsig(self):
"""Get the node's build signature (based on the signatures
of its dependency files and build information)."""
- if not hasattr(self, 'bsig'):
+ try:
+ return self.bsig
+ except AttributeError:
return None
- return self.bsig
def set_bsig(self, bsig):
"""Set the node's build signature (based on the signatures
of its dependency files and build information)."""
self.bsig = bsig
+ try:
+ delattr(self, '_tempbsig')
+ except AttributeError:
+ pass
def store_bsig(self):
"""Make the build signature permanent (that is, store it in the
@@ -422,14 +456,28 @@ class Node:
def del_bsig(self):
"""Delete the bsig from this node."""
- if hasattr(self, 'bsig'):
+ try:
delattr(self, 'bsig')
+ except AttributeError:
+ pass
def get_csig(self):
"""Get the signature of the node's content."""
- if not hasattr(self, 'csig'):
+ try:
+ return self.csig
+ except AttributeError:
return None
- return self.csig
+
+ def calc_csig(self, calc, cache=None):
+ """Return the node's content signature, calculating it first
+ if necessary.
+ """
+ if cache is None: cache = self
+ try:
+ return cache.csig
+ except AttributeError:
+ cache.csig = calc.csig(self, cache)
+ return cache.csig
def set_csig(self, csig):
"""Set the signature of the node's content."""
@@ -442,8 +490,10 @@ class Node:
def del_csig(self):
"""Delete the csig from this node."""
- if hasattr(self, 'csig'):
+ try:
delattr(self, 'csig')
+ except AttributeError:
+ pass
def get_prevsiginfo(self):
"""Fetch the previous signature information from the
diff --git a/src/engine/SCons/Sig/MD5.py b/src/engine/SCons/Sig/MD5.py
index 5239dab..c50dbb7 100644
--- a/src/engine/SCons/Sig/MD5.py
+++ b/src/engine/SCons/Sig/MD5.py
@@ -78,9 +78,11 @@ def collect(signatures):
def signature(obj):
"""Generate a signature for an object
"""
- if not hasattr(obj, 'get_contents'):
+ try:
+ contents = str(obj.get_contents())
+ except AttributeError:
raise AttributeError, "unable to fetch contents of '%s'" % str(obj)
- return hexdigest(md5.new(str(obj.get_contents())).digest())
+ return hexdigest(md5.new(contents).digest())
def to_string(signature):
"""Convert a signature to a string"""