From c2646d2380e644ea2a424fd8f6a917dc095e5bd0 Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Sat, 21 May 2016 11:58:47 +0200 Subject: [PATCH] Provide md5_tstamp by default and make it easier to add more persistent BuildContext dicts --- waflib/Build.py | 4 +++ waflib/Node.py | 5 ++- waflib/Tools/md5_tstamp.py | 43 +++++++++++++++++++++++ waflib/extras/md5_tstamp.py | 68 ------------------------------------- 4 files changed, 51 insertions(+), 69 deletions(-) create mode 100644 waflib/Tools/md5_tstamp.py delete mode 100644 waflib/extras/md5_tstamp.py diff --git a/waflib/Build.py b/waflib/Build.py index 923a312e..26209684 100644 --- a/waflib/Build.py +++ b/waflib/Build.py @@ -128,6 +128,10 @@ class BuildContext(Context.Context): Map group names to the group lists. See :py:meth:`waflib.Build.BuildContext.add_group` """ + for v in SAVED_ATTRS: + if not hasattr(self, v): + setattr(self, v, {}) + def get_variant_dir(self): """Getter for the variant_dir attribute""" if not self.variant: diff --git a/waflib/Node.py b/waflib/Node.py index e51e002e..2a8c147f 100644 --- a/waflib/Node.py +++ b/waflib/Node.py @@ -792,6 +792,9 @@ class Node(object): "Build path without the file name" return self.parent.bldpath() + def h_file(self): + return Utils.h_file(self.abspath()) + def get_bld_sig(self): """ Node signature. If there is a build directory or and the file is there, @@ -808,7 +811,7 @@ class Node(object): except KeyError: p = self.abspath() try: - ret = cache[self] = Utils.h_file(p) + ret = cache[self] = self.h_file() except EnvironmentError: if self.isdir(): # allow folders as build nodes, do not use the creation time diff --git a/waflib/Tools/md5_tstamp.py b/waflib/Tools/md5_tstamp.py new file mode 100644 index 00000000..e6a06e9a --- /dev/null +++ b/waflib/Tools/md5_tstamp.py @@ -0,0 +1,43 @@ +#! /usr/bin/env python +# encoding: utf-8 + +""" +This module assumes that only one build context is running at a given time, which +is not the case if you want to execute configuration tests in parallel. + +Store some values on the buildcontext mapping file paths to +stat values and md5 values (timestamp + md5) +this way the md5 hashes are computed only when timestamp change (can be faster) +There is usually little or no gain from enabling this, but it can be used to enable +the second level cache with timestamps (WAFCACHE) + +You may have to run distclean or to remove the build directory before enabling/disabling +this hashing scheme +""" + +import os, stat +from waflib import Utils, Build, Node + +STRONGEST = True + +Build.SAVED_ATTRS.append('hashes_md5_tstamp') +def h_file(self): + filename = self.abspath() + st = os.stat(filename) + + cache = self.ctx.hashes_md5_tstamp + if filename in cache and cache[filename][0] == st.st_mtime: + return cache[filename][1] + + global STRONGEST + if STRONGEST: + ret = Utils.h_file(filename) + else: + if stat.S_ISDIR(st[stat.ST_MODE]): + raise IOError('Not a file') + ret = Utils.md5(str((st.st_mtime, st.st_size)).encode()).digest() + + cache[filename] = (st.st_mtime, ret) + return ret +Node.Node.h_file = h_file + diff --git a/waflib/extras/md5_tstamp.py b/waflib/extras/md5_tstamp.py deleted file mode 100644 index b806bc68..00000000 --- a/waflib/extras/md5_tstamp.py +++ /dev/null @@ -1,68 +0,0 @@ -#! /usr/bin/env python -# encoding: utf-8 - -""" -This module assumes that only one build context is running at a given time, which -is not the case if you want to execute configuration tests in parallel. - -Store some values on the buildcontext mapping file paths to -stat values and md5 values (timestamp + md5) -this way the md5 hashes are computed only when timestamp change (can be faster) -There is usually little or no gain from enabling this, but it can be used to enable -the second level cache with timestamps (WAFCACHE) - -You may have to run distclean or to remove the build directory before enabling/disabling -this hashing scheme -""" - -import os, stat -from waflib import Utils, Build, Context - -STRONGEST = True - -try: - Build.BuildContext.store_real -except AttributeError: - - Context.DBFILE += '_md5tstamp' - - Build.hashes_md5_tstamp = {} - Build.SAVED_ATTRS.append('hashes_md5_tstamp') - def store(self): - # save the hash cache as part of the default pickle file - self.hashes_md5_tstamp = Build.hashes_md5_tstamp - self.store_real() - Build.BuildContext.store_real = Build.BuildContext.store - Build.BuildContext.store = store - - def restore(self): - # we need a module variable for h_file below - self.restore_real() - try: - Build.hashes_md5_tstamp = self.hashes_md5_tstamp or {} - except AttributeError: - Build.hashes_md5_tstamp = {} - Build.BuildContext.restore_real = Build.BuildContext.restore - Build.BuildContext.restore = restore - - def h_file(filename): - st = os.stat(filename) - if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file') - - if filename in Build.hashes_md5_tstamp: - if Build.hashes_md5_tstamp[filename][0] == str(st.st_mtime): - return Build.hashes_md5_tstamp[filename][1] - if STRONGEST: - ret = Utils.h_file_no_md5(filename) - Build.hashes_md5_tstamp[filename] = (str(st.st_mtime), ret) - return ret - else: - m = Utils.md5() - m.update(str(st.st_mtime)) - m.update(str(st.st_size)) - m.update(filename) - Build.hashes_md5_tstamp[filename] = (str(st.st_mtime), m.digest()) - return m.digest() - Utils.h_file_no_md5 = Utils.h_file - Utils.h_file = h_file -