2
0
mirror of https://gitlab.com/ita1024/waf.git synced 2025-01-27 10:40:02 +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 # 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 Store some values on the buildcontext mapping file paths to
stat values and md5 values (timestamp + md5) stat values and md5 values (timestamp + md5)
this way the md5 hashes are computed only when timestamp change (can be faster) 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 from waflib import Utils, Build, Context
STRONGEST = True STRONGEST = True
Context.DBFILE += '_md5tstamp'
Build.hashes_md5_tstamp = {} try:
Build.SAVED_ATTRS.append('hashes_md5_tstamp') Build.BuildContext.store_real
def store(self): except AttributeError:
# 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): Context.DBFILE += '_md5tstamp'
# 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
def h_file(filename): Build.hashes_md5_tstamp = {}
st = os.stat(filename) Build.SAVED_ATTRS.append('hashes_md5_tstamp')
if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file') 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: def restore(self):
if Build.hashes_md5_tstamp[filename][0] == str(st.st_mtime): # we need a module variable for h_file below
return Build.hashes_md5_tstamp[filename][1] self.restore_real()
m = Utils.md5()
if STRONGEST:
f = open(filename, 'rb')
read = 1
try: try:
while read: Build.hashes_md5_tstamp = self.hashes_md5_tstamp or {}
read = f.read(100000) except Exception as e:
m.update(read) Build.hashes_md5_tstamp = {}
finally: Build.BuildContext.restore_real = Build.BuildContext.restore
f.close() Build.BuildContext.restore = restore
else:
m.update(str(st.st_mtime))
m.update(str(st.st_size))
m.update(filename)
# ensure that the cache is overwritten def h_file(filename):
Build.hashes_md5_tstamp[filename] = (str(st.st_mtime), m.digest()) st = os.stat(filename)
return m.digest() if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file')
Utils.h_file = h_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 Windows-specific optimizations
This module can help reducing the overhead of listing files on windows (more than 10000 files).
""" """
import os import os
@ -11,37 +13,9 @@ except: import pickle as cPickle
from waflib import Utils, Build, Context, Node, Logs from waflib import Utils, Build, Context, Node, Logs
if Utils.is_win32: if Utils.is_win32:
from waflib.extras import md5_tstamp
import ctypes, ctypes.wintypes 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 FindFirstFile = ctypes.windll.kernel32.FindFirstFileW
FindNextFile = ctypes.windll.kernel32.FindNextFileW FindNextFile = ctypes.windll.kernel32.FindNextFileW
FindClose = ctypes.windll.kernel32.FindClose FindClose = ctypes.windll.kernel32.FindClose