8 addr_re =
r"(?P<address>[0-9a-f]{1,16})?"
9 code_re =
r"(?P<code>[a-zA-Z])"
10 symbol_re =
r"(?P<symbol>[a-zA-Z0-9_.$@]+)"
11 symbol_demunged_re =
r"(?P<symbol>[a-zA-Z0-9_.$@:&()<>{}\[\]|^!%,~*+-=# ]+)"
12 symbols_re_skip = re.compile(
"(@@)")
13 nm_line_re = re.compile(
r"\s+".
join([addr_re, code_re, symbol_re]) +
"\s*$",
15 ldd_line_re = re.compile(
r"\s+(.*) => (.*) \(0x")
17 requires = collections.defaultdict(set)
18 provides = collections.defaultdict(set)
19 dependencies = collections.defaultdict(set)
20 libraries = collections.defaultdict(set)
23 lines = subprocess.check_output([
"nm",
"-g", fname])
24 for l
in lines.splitlines():
25 m = nm_line_re.match(l)
27 symbol = m.group(
'symbol')
28 if m.group(
'code') ==
'U':
29 requires[os.path.basename(fname)].add(symbol)
31 provides[symbol].
add(os.path.basename(fname))
34 lines = subprocess.check_output([
"ldd",fname])
35 for l
in lines.splitlines():
36 m = ldd_line_re.match(l)
39 libraries[os.path.basename(fname)].
add(os.path.basename(library.rstrip(
'\r\n')))
42 paths=os.environ[
'LD_LIBRARY_PATH'].
split(
':')
45 for dirpath, dirnames, filenames
in os.walk(p):
47 fpth=os.path.realpath(os.path.join(dirpath,f))
48 filetype = subprocess.check_output([
"file", fpth])
49 if filetype.find(
"dynamically linked") >= 0 :
53 for fname, symbols
in requires.items():
55 for library
in libraries[fname]:
57 if library
in provides[s] : deps.add(library)
58 dependencies[fname]=deps
59 print fname +
' : primary dependencies : ' +
', '.
join(sorted(dependencies[fname]))+
'\n'
63 if s
not in provides
and not symbols_re_skip.search(s) : unmet.add(s)
64 for u
in sorted(unmet):
65 dm = subprocess.check_output([
"c++filt",u])
66 demangled.add(dm.rstrip(
'\r\n'))
67 if demangled :
print fname +
': undefined : ' +
', '.
join(sorted(demangled))
71 for key,values
in dependencies.items():
73 for val
in values: G.add_edge(key,val)
75 for node
in nx.nodes_iter(G):
76 s = nx.dfs_successors(G,node)
79 for key,vals
in s.items() :
80 if key != node : deps.add(key)
83 print node +
': primary and secondary dependencies :' +
', '.
join(sorted(deps))
88 for key,values
in dependencies.items():
89 H.add_node(os.path.basename(key))
90 for val
in values: H.add_edge(os.path.basename(key),os.path.basename(val))
91 for node
in nx.nodes_iter(H):
92 T = nx.dfs_tree(H,node)
void add(const std::vector< const T * > &source, std::vector< const T * > &dest)
static std::string join(char **cmd)