diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/engine/SCons/Node/FS.py | 32 | ||||
-rw-r--r-- | src/engine/SCons/Script/Main.py | 3 | ||||
-rw-r--r-- | src/engine/SCons/Script/SConsOptions.py | 13 | ||||
-rw-r--r-- | src/engine/SCons/Util.py | 17 |
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. |