summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2011-04-12 11:11:55 +1000
committerAndrew Tridgell <tridge@samba.org>2011-04-13 11:47:36 +1000
commit601835ee6db8952911216f8f7f02f5101dc3b269 (patch)
tree74c014d24093debaea61c2653ebd0ebcc4451053
parent4edc98eb9e18eff00bb5ce9bdcdffa5b11149dd4 (diff)
downloadsamba-601835ee6db8952911216f8f7f02f5101dc3b269.tar.gz
samba-601835ee6db8952911216f8f7f02f5101dc3b269.tar.bz2
samba-601835ee6db8952911216f8f7f02f5101dc3b269.zip
build: speed up SYMBOLCHECK code
this uses a nm and ldd cache to speed up the duplicate symbol checking code Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
-rw-r--r--buildtools/wafsamba/symbols.py47
1 files changed, 41 insertions, 6 deletions
diff --git a/buildtools/wafsamba/symbols.py b/buildtools/wafsamba/symbols.py
index 5059c60a45..280e160b07 100644
--- a/buildtools/wafsamba/symbols.py
+++ b/buildtools/wafsamba/symbols.py
@@ -21,12 +21,30 @@ from samba_utils import *
#
# LOCAL_CACHE(bld, 'TARGET_TYPE') : dictionary mapping subsystem name to target type
-def symbols_extract(objfiles, dynamic=False):
+
+def symbols_extract(bld, objfiles, dynamic=False):
'''extract symbols from objfile, returning a dictionary containing
the set of undefined and public symbols for each file'''
ret = {}
+ # see if we can get some results from the nm cache
+ if not bld.env.nm_cache:
+ bld.env.nm_cache = {}
+
+ objfiles = set(objfiles).copy()
+
+ remaining = set()
+ for obj in objfiles:
+ if obj in bld.env.nm_cache:
+ ret[obj] = bld.env.nm_cache[obj].copy()
+ else:
+ remaining.add(obj)
+ objfiles = remaining
+
+ if len(objfiles) == 0:
+ return ret
+
cmd = ["nm"]
if dynamic:
# needed for some .so files
@@ -60,6 +78,13 @@ def symbols_extract(objfiles, dynamic=False):
elif symbol_type in "U":
ret[filename]["UNDEFINED"].add(symbol)
+ # add to the cache
+ for obj in objfiles:
+ if obj in ret:
+ bld.env.nm_cache[obj] = ret[obj].copy()
+ else:
+ bld.env.nm_cache[obj] = { "PUBLIC": set(), "UNDEFINED" : set() }
+
return ret
@@ -73,6 +98,13 @@ def get_ldd_libs(bld, binname):
'''find the list of linked libraries for any binary or library
binname is the path to the binary/library on disk
'''
+
+ # see if we can get the result from the ldd cache
+ if not bld.env.ldd_cache:
+ bld.env.ldd_cache = {}
+ if binname in bld.env.ldd_cache:
+ return bld.env.ldd_cache[binname].copy()
+
ret = set()
lddpipe = subprocess.Popen(['ldd', binname], stdout=subprocess.PIPE).stdout
for line in lddpipe:
@@ -81,10 +113,13 @@ def get_ldd_libs(bld, binname):
if len(cols) < 3 or cols[1] != "=>" or cols[2] == '':
continue
ret.add(os.path.realpath(cols[2]))
+
+ bld.env.ldd_cache[binname] = ret.copy()
+
return ret
-def get_ldd_libs_recursive(bld, binname, seen=set()):
+def get_ldd_libs_recursive(bld, binname, seen):
'''find the recursive list of linked libraries for any binary or library
binname is the path to the binary/library on disk. seen is a set used
to prevent loops
@@ -143,7 +178,7 @@ def build_symbol_sets(bld, tgt_list):
objlist.append(objpath)
objmap[objpath] = t
- symbols = symbols_extract(objlist)
+ symbols = symbols_extract(bld, objlist)
for obj in objlist:
t = objmap[obj]
t.public_symbols = t.public_symbols.union(symbols[obj]["PUBLIC"])
@@ -236,7 +271,7 @@ def build_syslib_sets(bld, tgt_list):
syslib_paths.append(bld.env.libc_path)
objmap[bld.env.libc_path] = 'c'
- symbols = symbols_extract(syslib_paths, dynamic=True)
+ symbols = symbols_extract(bld, syslib_paths, dynamic=True)
# keep a map of syslib names to public symbols
bld.env.syslib_symbols = {}
@@ -503,9 +538,9 @@ def report_duplicate(bld, binname, sym, libs):
def symbols_dupcheck_binary(bld, binname):
'''check for duplicated symbols in one binary'''
- libs = get_ldd_libs_recursive(bld, binname)
+ libs = get_ldd_libs_recursive(bld, binname, set())
- symlist = symbols_extract(libs, dynamic=True)
+ symlist = symbols_extract(bld, libs, dynamic=True)
symmap = {}
for libpath in symlist: