summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Node/FS.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/SCons/Node/FS.py')
-rw-r--r--src/engine/SCons/Node/FS.py147
1 files changed, 83 insertions, 64 deletions
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index c728ece..3b4e77f 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -482,7 +482,18 @@ class Base(SCons.Node.Node):
return self.rfile().exists()
def getmtime(self):
- return self.stat()[stat.ST_MTIME]
+ st = self.stat()
+ if st:
+ return self.stat()[stat.ST_MTIME]
+ else:
+ return None
+
+ def getsize(self):
+ st = self.stat()
+ if st:
+ return self.stat()[stat.ST_SIZE]
+ else:
+ return None
def isdir(self):
st = self.stat()
@@ -686,6 +697,8 @@ class LocalFS:
return os.path.exists(path)
def getmtime(self, path):
return os.path.getmtime(path)
+ def getsize(self, path):
+ return os.path.getsize(path)
def isdir(self, path):
return os.path.isdir(path)
def isfile(self, path):
@@ -1464,17 +1477,21 @@ class RootDir(Dir):
def src_builder(self):
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.
+class NodeInfo(SCons.Node.NodeInfo):
+ # The bsig attributes needs to stay here, if it's initialized in
+ # __init__() then the assignment seems to overwrite any values
+ # unpickled from .sconsign files.
bsig = None
+ def __cmp__(self, other):
+ return cmp(self.bsig, other.bsig)
+ def update(self, node):
+ self.timestamp = node.get_timestamp()
+ self.size = node.getsize()
+
+class BuildInfo(SCons.Node.BuildInfo):
def __init__(self, node):
+ SCons.Node.BuildInfo.__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
@@ -1568,8 +1585,7 @@ class File(Base):
# in one build (SConstruct file) is a source in a different build.
# See test/chained-build.py for the use case.
entry = self.get_stored_info()
- for key, val in obj.__dict__.items():
- entry.__dict__[key] = val
+ entry.merge(obj)
self.dir.sconsign().set_entry(self.name, entry)
def get_stored_info(self):
@@ -1579,17 +1595,17 @@ class File(Base):
except (KeyError, OSError):
return self.new_binfo()
else:
- if isinstance(stored, BuildInfo):
- return stored
- # The stored build information isn't a BuildInfo object.
- # This probably means it's an old SConsignEntry from SCons
- # 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 = self.new_binfo()
- for key, val in stored.__dict__.items():
- setattr(binfo, key, val)
- return binfo
+ if not hasattr(stored, 'ninfo'):
+ # Transition: The .sconsign file entry has no NodeInfo
+ # object, which means it's a slightly older BuildInfo.
+ # Copy over the relevant attributes.
+ ninfo = stored.ninfo = self.new_ninfo()
+ for attr in ninfo.__dict__.keys():
+ try:
+ setattr(ninfo, attr, getattr(stored, attr))
+ except AttributeError:
+ pass
+ return stored
def get_stored_implicit(self):
binfo = self.get_stored_info()
@@ -1765,20 +1781,19 @@ class File(Base):
self.do_duplicate(src)
return Base.exists(self)
+ #
+ # SIGNATURE SUBSYSTEM
+ #
+
def new_binfo(self):
return BuildInfo(self)
- def del_cinfo(self):
- try:
- del self.binfo.csig
- except AttributeError:
- pass
- try:
- del self.binfo.timestamp
- except AttributeError:
- pass
+ def new_ninfo(self):
+ ninfo = NodeInfo()
+ ninfo.update(self)
+ return ninfo
- def calc_csig(self, calc=None):
+ def get_csig(self, calc=None):
"""
Generate a node's content signature, the digested signature
of its content.
@@ -1787,45 +1802,44 @@ class File(Base):
cache - alternate node to use for the signature cache
returns - the content signature
"""
- if calc is None:
- calc = self.calculator()
-
try:
- return self.binfo.csig
+ return self.binfo.ninfo.csig
except AttributeError:
pass
-
- if calc.max_drift >= 0:
- old = self.get_stored_info()
- else:
- old = self.new_binfo()
- try:
- mtime = self.get_timestamp()
- except OSError:
- mtime = 0
- raise SCons.Errors.UserError, "no such %s" % self
+ if calc is None:
+ calc = self.calculator()
- try:
- if (old.timestamp and old.csig and old.timestamp == mtime):
- # use the signature stored in the .sconsign file
- csig = old.csig
- else:
- csig = calc.module.signature(self)
- except AttributeError:
- csig = calc.module.signature(self)
+ mtime = self.get_timestamp()
- if calc.max_drift >= 0 and (time.time() - mtime) > calc.max_drift:
+ use_stored = calc.max_drift >= 0 and \
+ (time.time() - mtime) > calc.max_drift
+
+ csig = None
+ if use_stored:
+ old = self.get_stored_info().ninfo
try:
- binfo = self.binfo
+ if old.timestamp and old.csig and old.timestamp == mtime:
+ csig = old.csig
except AttributeError:
- binfo = self.binfo = self.new_binfo()
- binfo.csig = csig
- binfo.timestamp = mtime
+ pass
+ if csig is None:
+ csig = calc.module.signature(self)
+
+ binfo = self.get_binfo()
+ ninfo = binfo.ninfo
+ ninfo.csig = csig
+ ninfo.update(self)
+
+ if use_stored:
self.store_info(binfo)
return csig
+ #
+ #
+ #
+
def current(self, calc=None):
self.binfo = self.gen_binfo(calc)
return self._cur2()
@@ -1839,17 +1853,19 @@ class File(Base):
if r != self:
# ...but there is one in a Repository...
old = r.get_stored_info()
- if old == self.binfo:
+ new = self.get_binfo()
+ if new == old:
# ...and it's even up-to-date...
if self._local:
# ...and they'd like a local copy.
LocalCopy(self, r, None)
- self.store_info(self.binfo)
+ self.store_info(new)
return 1
return None
else:
old = self.get_stored_info()
- return (self.binfo == old)
+ new = self.get_binfo()
+ return (new == old)
def rfile(self):
"__cacheable__"
@@ -1870,12 +1886,15 @@ class File(Base):
def cachepath(self):
if not self.fs.CachePath:
return None, None
- if self.binfo.bsig is None:
+ ninfo = self.get_binfo().ninfo
+ if not hasattr(ninfo, 'bsig'):
+ raise SCons.Errors.InternalError, "cachepath(%s) found no bsig" % self.path
+ elif ninfo.bsig is None:
raise SCons.Errors.InternalError, "cachepath(%s) found a bsig of None" % self.path
# Add the path to the cache signature, because multiple
# targets built by the same action will all have the same
# build signature, and we have to differentiate them somehow.
- cache_sig = SCons.Sig.MD5.collect([self.binfo.bsig, self.path])
+ cache_sig = SCons.Sig.MD5.collect([ninfo.bsig, self.path])
subdir = string.upper(cache_sig[0])
dir = os.path.join(self.fs.CachePath, subdir)
return dir, os.path.join(dir, cache_sig)