2
0
mirror of https://gitlab.com/ita1024/waf.git synced 2025-01-26 18:20:22 +01:00

make sure the md5_tstamp module can be imported multiple times without causing problems

This commit is contained in:
Thomas Nagy 2012-04-02 01:36:52 +02:00
parent d8b2bbc363
commit 181438a9ba
2 changed files with 53 additions and 71 deletions

View File

@ -2,6 +2,9 @@
# 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)
@ -18,52 +21,57 @@ except: import pickle as cPickle
from waflib import Utils, Build, Context
STRONGEST = True
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
try:
Build.BuildContext.store_real
except AttributeError:
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 Exception as e:
Build.hashes_md5_tstamp = {}
Build.BuildContext.restore_real = Build.BuildContext.restore
Build.BuildContext.restore = restore
Context.DBFILE += '_md5tstamp'
def h_file(filename):
st = os.stat(filename)
if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
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
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]
m = Utils.md5()
if STRONGEST:
f = open(filename, 'rb')
read = 1
def restore(self):
# we need a module variable for h_file below
self.restore_real()
try:
while read:
read = f.read(100000)
m.update(read)
finally:
f.close()
else:
m.update(str(st.st_mtime))
m.update(str(st.st_size))
m.update(filename)
Build.hashes_md5_tstamp = self.hashes_md5_tstamp or {}
except Exception as e:
Build.hashes_md5_tstamp = {}
Build.BuildContext.restore_real = Build.BuildContext.restore
Build.BuildContext.restore = restore
# ensure that the cache is overwritten
Build.hashes_md5_tstamp[filename] = (str(st.st_mtime), m.digest())
return m.digest()
Utils.h_file = h_file
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]
m = Utils.md5()
if STRONGEST:
f = open(filename, 'rb')
read = 1
try:
while read:
read = f.read(100000)
m.update(read)
finally:
f.close()
else:
m.update(str(st.st_mtime))
m.update(str(st.st_size))
m.update(filename)
# ensure that the cache is overwritten
Build.hashes_md5_tstamp[filename] = (str(st.st_mtime), m.digest())
return m.digest()
Utils.h_file = h_file

View File

@ -3,6 +3,8 @@
"""
Windows-specific optimizations
This module can help reducing the overhead of listing files on windows (more than 10000 files).
"""
import os
@ -11,37 +13,9 @@ except: import pickle as cPickle
from waflib import Utils, Build, Context, Node, Logs
if Utils.is_win32:
from waflib.extras import md5_tstamp
import ctypes, ctypes.wintypes
Context.DBFILE += '_md5tstamp'
try:
Build.BuildContext.store_real
except AttributeError:
pass
else:
raise ValueError('win32opts has been loaded twice (or the incompatible md5_tstamp tool was loaded before)')
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 Exception as e:
Build.hashes_md5_tstamp = {}
Build.BuildContext.restore_real = Build.BuildContext.restore
Build.BuildContext.restore = restore
FindFirstFile = ctypes.windll.kernel32.FindFirstFileW
FindNextFile = ctypes.windll.kernel32.FindNextFileW
FindClose = ctypes.windll.kernel32.FindClose