Provide md5_tstamp by default and make it easier to add more persistent BuildContext dicts

This commit is contained in:
Thomas Nagy 2016-05-21 11:58:47 +02:00
parent f876392200
commit c2646d2380
No known key found for this signature in database
GPG Key ID: 67A565EDFDF90E64
4 changed files with 51 additions and 69 deletions

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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