summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/engine/SCons/Node/FS.py32
-rw-r--r--src/engine/SCons/Script/Main.py3
-rw-r--r--src/engine/SCons/Script/SConsOptions.py13
-rw-r--r--src/engine/SCons/Util.py17
4 files changed, 61 insertions, 4 deletions
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 02dcdbf..8301b15 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -2160,6 +2160,8 @@ class File(Base):
NodeInfo = FileNodeInfo
BuildInfo = FileBuildInfo
+ md5_chunksize = 64
+
def diskcheck_match(self):
diskcheck_match(self, self.isdir,
"Directory %s found where file expected.")
@@ -2233,6 +2235,23 @@ class File(Base):
raise
return r
+ def get_content_hash(self):
+ """
+ Compute and return the MD5 hash for this file.
+ """
+ if not self.rexists():
+ return SCons.Util.MD5signature('')
+ fname = self.rfile().abspath
+ try:
+ cs = SCons.Util.MD5filesignature(fname,
+ chunksize=SCons.Node.FS.File.md5_chunksize*1024)
+ except EnvironmentError, e:
+ if not e.filename:
+ e.filename = fname
+ raise
+ return cs
+
+
memoizer_counters.append(SCons.Memoize.CountValue('get_size'))
def get_size(self):
@@ -2697,7 +2716,10 @@ class File(Base):
if csig is None:
try:
- contents = self.get_contents()
+ if self.get_size() < SCons.Node.FS.File.md5_chunksize:
+ contents = self.get_contents()
+ else:
+ csig = self.get_content_hash()
except IOError:
# This can happen if there's actually a directory on-disk,
# which can be the case if they've disabled disk checks,
@@ -2705,7 +2727,8 @@ class File(Base):
# create a same-named directory by mistake.
csig = ''
else:
- csig = SCons.Util.MD5signature(contents)
+ if not csig:
+ csig = SCons.Util.MD5signature(contents)
ninfo.csig = csig
@@ -2833,8 +2856,8 @@ class File(Base):
cachedir, cachefile = self.get_build_env().get_CacheDir().cachepath(self)
if not self.exists() and cachefile and os.path.exists(cachefile):
- contents = open(cachefile, 'rb').read()
- self.cachedir_csig = SCons.Util.MD5signature(contents)
+ self.cachedir_csig = SCons.Util.MD5filesignature(cachefile, \
+ SCons.Node.FS.File.md5_chunksize * 1024)
else:
self.cachedir_csig = self.get_csig()
return self.cachedir_csig
@@ -2856,6 +2879,7 @@ class File(Base):
self.cachesig = SCons.Util.MD5collect(sigs)
return self.cachesig
+
default_fs = None
def get_default_fs():
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index 76b94e0..048dfdd 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -966,6 +966,9 @@ def _main(parser):
SCons.Job.explicit_stack_size = options.stack_size
+ if options.md5_chunksize:
+ SCons.Node.FS.File.md5_chunksize = options.md5_chunksize
+
platform = SCons.Platform.platform_module()
if options.interactive:
diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py
index 0e28fd2..d01ec04 100644
--- a/src/engine/SCons/Script/SConsOptions.py
+++ b/src/engine/SCons/Script/SConsOptions.py
@@ -126,6 +126,7 @@ class SConsValues(optparse.Values):
'help',
'implicit_cache',
'max_drift',
+ 'md5_chunksize',
'no_exec',
'num_jobs',
'random',
@@ -177,6 +178,11 @@ class SConsValues(optparse.Values):
value = int(value)
except ValueError:
raise SCons.Errors.UserError, "An integer is required: %s"%repr(value)
+ elif name == 'md5_chunksize':
+ try:
+ value = int(value)
+ except ValueError:
+ raise SCons.Errors.UserError, "An integer is required: %s"%repr(value)
elif name == 'warn':
if SCons.Util.is_String(value):
value = [value]
@@ -726,6 +732,13 @@ def Parser(version):
help="Set maximum system clock drift to N seconds.",
metavar="N")
+ op.add_option('--md5-chunksize',
+ nargs=1, type="int",
+ dest='md5_chunksize', default=SCons.Node.FS.File.md5_chunksize,
+ action="store",
+ help="Set chunk-size for MD5 signature computation to N kilobytes.",
+ metavar="N")
+
op.add_option('-n', '--no-exec', '--just-print', '--dry-run', '--recon',
dest='no_exec', default=False,
action="store_true",
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
index 3fdc14c..7ea3673 100644
--- a/src/engine/SCons/Util.py
+++ b/src/engine/SCons/Util.py
@@ -1496,6 +1496,12 @@ md5 = False
def MD5signature(s):
return str(s)
+def MD5filesignature(fname, chunksize=65536):
+ f = open(fname, "rb")
+ result = f.read()
+ f.close()
+ return result
+
try:
import hashlib
except ImportError:
@@ -1508,6 +1514,17 @@ else:
m.update(str(s))
return m.hexdigest()
+ def MD5filesignature(fname, chunksize=65536):
+ m = hashlib.md5()
+ f = open(fname, "rb")
+ while 1:
+ blck = f.read(chunksize)
+ if not blck:
+ break
+ m.update(str(blck))
+ f.close()
+ return m.hexdigest()
+
def MD5collect(signatures):
"""
Collects a list of signatures into an aggregate signature.