12 adj = collections.defaultdict(list)
14 adj[edge[0]].
append(edge[1])
21 self.
adj = Graph._build_adjacency_list(self.
edges)
28 if u
not in discovered
and u
not in finished:
29 discovered, finished =
dfs_visit(G, u, discovered, finished)
34 return discovered, finished
41 print(f
"Cycle detected: found a back edge from {u} to {v}. It involves")
42 for i,d
in enumerate(discovered):
43 if i != len(discovered)-1:
56 return discovered, finished
61 proc = subprocess.Popen(comm, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=
True)
62 stdout, stderr = proc.communicate()
63 stdout = stdout.decode(encoding)
64 if stderr
is not None:
65 stderr= stderr.decode(encoding)
66 return proc.returncode, stdout, stderr
71 src_base = os.environ.get(
'CMSSW_RELEASE_BASE')
72 src_path = os.path.join(src_base,
"src")
73 comm =
"ls -d "+src_path+
"/*/*/interface" 77 for l
in c_out.split():
79 ret_val.append(
'/'.
join(sp[-3:-1]))
84 src_base = os.environ.get(
'CMSSW_RELEASE_BASE')
85 pack_path = os.path.join(src_base,
"src",pack,subdir)
86 if not os.path.exists(pack_path):
return []
88 for root, dirs, files
in os.walk(pack_path, topdown=
False):
92 ret_val.append(os.path.join(root,name))
97 lib_path = lib_info[1]
98 comm =
"ldd "+lib_path+
"| grep cms | grep -v \"/external\" | grep -v \"/lcg/\" | awk '{print $3}'" 101 for l
in c_out.split():
103 ret_val.append( (lib.split(
'/')[-1],lib))
110 comm=
"gcc -fpreprocessed -dD -E " 112 comm=
"nvcc --compiler-options -fpreprocessed -dD -E " 115 comm=comm+
" | grep \"#include\"" 117 for l
in c_out.split():
118 inc = l.strip().
split()[-1][1:-1]
120 incs[
'/'.
join(inc.split(
'/')[0:2])]=1
121 if package
is not None and package
in inc
and "interface" in inc:
122 pack_incs[os.path.join(
'/'.
join(file_list[0].
split(
'/')[0:-4]),inc)]=1
124 return list(incs.keys())
126 return list(incs.keys()),list(pack_incs.keys())
132 if __name__ ==
"__main__":
136 parser=argparse.ArgumentParser(description=
"CMSSW Cyclic dependency finder")
137 parser.add_argument(
"--omit_header_only",dest=
"omit_header_only",
138 action=
"store_false", default=
True,
139 help=
"Ignore cycles due to header only dependencies" 141 parser.add_argument(
"--status_bar",dest=
"status_bar",
142 action=
"store_true", default=
False,
143 help=
"Show progress bar when running" 146 args = parser.parse_args()
147 omit_header_only=args.omit_header_only
148 show_status_bar=args.status_bar
149 print(omit_header_only,show_status_bar)
150 if 'CMSSW_RELEASE_BASE' not in os.environ:
151 print(
"Execute within a cmssw environment")
160 iter_lib = tqdm.tqdm(lib_list)
165 source_list =
get_files(lib,
"src",[
".cc",
".cpp",
".cxx"])
171 source_incs_packages = list(cpp_incs_packages)
172 source_incs_packages.extend(x
for x
in cuda_incs_packages
if x
not in source_incs_packages)
173 self_headers = list(cpp_self_headers)
174 self_headers.extend(x
for x
in cuda_self_headers
if x
not in self_headers)
176 if not omit_header_only:
181 for dep
in header_incs_packages:
183 G.addEdge( (lib,dep) )
184 for dep
in source_incs_packages:
185 if dep != lib
and dep
not in header_incs_packages:
186 G.addEdge( (lib,dep) )
188 print(
"Building adjacency graph")
189 G.build_adjacency_list()
190 print(
"Looking for cycles")
def __init__(self, edges)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
def build_adjacency_list(self)
def split(sequence, size)
static std::string join(char **cmd)
def dfs_visit(G, u, discovered, finished)
def get_files(pack, subdir, file_types)
def _build_adjacency_list(edges)
def get_lib_deps(lib_info)
def get_include_packages(file_list, package=None, is_cuda=False)