|
ATLAS Offline Software
|
|
def | read_package_list (package_file) |
|
def | externals_name (lib) |
|
def | lrstrip (s, prefix, postfix) |
|
def | traverse (graph, root, reverse=False, maxdepth=None, nodegetter=lambda n:n) |
|
def | subgraph (graph, sources, reverse=False, maxdepth=None, nodegetter=lambda n :n.attr.get('label')) |
|
def | add_legend (graph) |
|
def | copy_graph (source, dest) |
|
def | create_dep_graph (target, deps, pydeps, args) |
|
def | print_dep_graph (graph, args, package_paths={}) |
|
def | run (args) |
|
def | main (args) |
|
◆ add_legend()
def python.scripts.cmake_depends.add_legend |
( |
|
graph | ) |
|
Add legend to graph
Definition at line 99 of file cmake_depends.py.
100 """Add legend to graph"""
101 graph.add_subgraph(name=
'clusterLegend', label=
'Legend')
102 l = graph.subgraphs()[-1]
104 l.add_node(n, shape=
'point', style=
'invis')
105 l.add_edge(
'a',
'b', label=
'C++', constraint=
False)
106 l.add_edge(
'c',
'd', label=
'Python', style=py_style, constraint=
False)
◆ copy_graph()
def python.scripts.cmake_depends.copy_graph |
( |
|
source, |
|
|
|
dest |
|
) |
| |
Copy graph nodes and edges from source to dest including attributes
Definition at line 109 of file cmake_depends.py.
110 """Copy graph nodes and edges from source to dest including attributes"""
111 for e
in source.edges_iter():
112 dest.add_edge(e, **e.attr)
113 for n
in source.nodes_iter():
114 dest.add_node(n, **n.attr)
◆ create_dep_graph()
def python.scripts.cmake_depends.create_dep_graph |
( |
|
target, |
|
|
|
deps, |
|
|
|
pydeps, |
|
|
|
args |
|
) |
| |
Create and return dependency graph.
@param target name of target
@param deps AthGraph cmake dependencies
@param pydeps python dependencies
@param args command line arguments
Definition at line 171 of file cmake_depends.py.
172 """Create and return dependency graph.
174 @param target name of target
175 @param deps AthGraph cmake dependencies
176 @param pydeps python dependencies
177 @param args command line arguments
181 if not args.all
and deps.ignore_target(node):
return None
182 if args.externals
or not node.attr[
'external']:
183 a =
'label' if args.target
else 'package'
186 target = target.split(
'/')[-1]
189 depth = args.recursive
190 if not args.target
and not args.clients
and args.recursive
is not None:
195 r = re.compile(target)
196 targets = [getnode(n)
for n
in deps.graph.nodes_iter()
if r.match(n.attr[
'label'])]
198 targets += [n
for n
in pydeps.nodes_iter()
if r.match(n)]
209 if deps.get_node(l).attr[
'external']
and not args.externals:
210 raise RuntimeError(f
"{l} is an external target. Run with -e/--externals.")
214 if args.clients
and not args.target:
215 sources.extend([b
for a,b
in traverse(deps.graph, deps.get_node(l), maxdepth=1)])
217 sources.extend([deps.get_node(l)])
219 raise RuntimeError(f
"Target with name {l} does not exist.")
222 g =
subgraph(deps.graph, sources, reverse=args.clients,
223 maxdepth=depth, nodegetter=getnode)
225 graph = pygraphviz.AGraph(name=target, directed=
True, strict=
False)
226 graph.add_edges_from(g)
231 pysources = [pydeps.get_node(t)
for t
in targets
if pydeps.has_node(t)]
232 g =
subgraph(pydeps, pysources, reverse=args.clients,
233 maxdepth=args.recursive, nodegetter=
lambda n : n.name)
235 graph.add_edges_from(g, style=py_style)
238 for n
in graph.nodes_iter():
239 if all(e.attr[
'style']==py_style
for e
in graph.edges_iter(n)):
240 n.attr[
'style'] = py_style
◆ externals_name()
def python.scripts.cmake_depends.externals_name |
( |
|
lib | ) |
|
Return a short name for an external library
Definition at line 32 of file cmake_depends.py.
33 """Return a short name for an external library"""
36 lcg =
next(d
for d
in dirs
if d.startswith(
'LCG_'))
37 return '%s::%s' % (dirs[dirs.index(lcg)+1], dirs[-1])
38 elif lib.startswith(
'Gaudi'):
39 return 'Gaudi::%s' % lib
41 return os.path.basename(lib)
◆ lrstrip()
def python.scripts.cmake_depends.lrstrip |
( |
|
s, |
|
|
|
prefix, |
|
|
|
postfix |
|
) |
| |
Strip `prefix` and `postfix` from string `s`
Definition at line 44 of file cmake_depends.py.
44 def lrstrip(s, prefix, postfix):
45 """Strip `prefix` and `postfix` from string `s`"""
46 if s.startswith(prefix): s = s[len(prefix):]
47 if s.endswith(postfix): s = s[:-len(postfix)]
◆ main()
def python.scripts.cmake_depends.main |
( |
|
args | ) |
|
◆ print_dep_graph()
def python.scripts.cmake_depends.print_dep_graph |
( |
|
graph, |
|
|
|
args, |
|
|
|
package_paths = {} |
|
) |
| |
Output final graph
Definition at line 245 of file cmake_depends.py.
246 """Output final graph"""
249 if args.batch
or not args.dot:
250 f =
open(graph.name+
'.txt',
'w')
if args.batch
else sys.stdout
251 nodes = [e[0]
for e
in graph.in_edges_iter()]
if args.clients \
252 else [e[1]
for e
in graph.out_edges_iter()]
256 suffix =
':py' if p.attr[
'style']==py_style
else ''
257 output.append(
'%s%s' % (package_paths.get(p,p), suffix))
261 if args.batch
or args.dot:
262 f =
open(graph.name+
'.dot',
'w')
if args.batch
else sys.stdout
271 @acmdlib.command(name=
'cmake.depends',
274 @acmdlib.argument(
'names', nargs=
'+', metavar=
'NAME',
275 help=
'package/target name or regular expression')
277 @acmdlib.argument(
'-t',
'--target', action=
'store_true',
278 help=
'treat NAME as target instead of package name')
280 @acmdlib.argument(
'-c',
'--clients', action=
'store_true',
281 help=
'show clients (instead of dependencies)')
283 @acmdlib.argument(
'-e',
'--externals', action=
'store_true',
284 help=
'include external dependencies')
286 @acmdlib.argument(
'-l',
'--long', action=
'store_true',
287 help=
'show full package names (only for txt output)')
289 @acmdlib.argument(
'-r',
'--recursive', nargs=
'?', metavar=
'DEPTH',
290 type=int, default=1, const=
None,
291 help=
'recursively resolve dependencies up to DEPTH (default: unlimited)')
293 @acmdlib.argument(
'--py', action=
'store_true',
294 help=f
'add Python dependencies (marked with ":py" in printout, {py_style} in graph)')
296 @acmdlib.argument(
'--regex', action=
'store_true',
297 help=
'treat NAME as regular expression')
299 @acmdlib.argument(
'--all', action=
'store_true',
300 help=
'do not apply any target filter (e.g. custom targets)')
302 @acmdlib.argument(
'-d',
'--dot', action=
'store_true',
303 help=
'print DOT graph')
305 @acmdlib.argument(
'--legend', action=
'store_true',
306 help=
'add legend to graph')
308 @acmdlib.argument(
'--batch', nargs=
'?', metavar=
'N', type=int, const=1,
309 help=
'Batch mode using N jobs (default: 1). Create dot and txt dependencies '
310 'for all NAMEs and store them in separate files.')
314 @acmdlib.argument(
'--cmakedot', help=argparse.SUPPRESS)
315 @acmdlib.argument(
'--pydot', help=argparse.SUPPRESS)
◆ read_package_list()
def python.scripts.cmake_depends.read_package_list |
( |
|
package_file | ) |
|
Read packages.txt as a source for the full package path
Definition at line 23 of file cmake_depends.py.
24 """Read packages.txt as a source for the full package path"""
26 with open(package_file)
as f:
27 packages = [line.rstrip()
for line
in f
if not line.startswith(
'#')]
29 return dict([(p.split(
'/')[-1],p)
for p
in packages])
◆ run()
def python.scripts.cmake_depends.run |
( |
|
args | ) |
|
Inspect cmake build dependencies
Definition at line 318 of file cmake_depends.py.
319 """Inspect cmake build dependencies"""
322 if not args.cmakedot:
324 args.cmakedot = os.path.join(os.environ[
'AtlasArea'],
'InstallArea',
325 os.environ[
'BINARY_TAG'],
'packages.dot')
327 main.parser.error(
"Cannot find 'packages.dot'. Setup a release or use --cmakedot.")
333 main.parser.error(
"Python dependencies not possible in target mode.")
335 args.pydot = args.pydot
or args.cmakedot.replace(
'.dot',
'.py.dot')
337 pydeps = pygraphviz.AGraph(args.pydot)
339 main.parser.error(f
"Cannot read '{args.pydot}'. Setup a release or use --pydot.")
345 package_paths =
read_package_list(os.path.join(os.environ[
'AtlasArea'],
'InstallArea',
346 os.environ[
'BINARY_TAG'],
'packages.txt'))
348 main.parser.error(
"Cannot read 'packages.txt'. Setup a release or run without -l/--long.")
351 deps = AthGraph(args.cmakedot)
355 subgraphs = [
create_dep_graph(target, deps, pydeps, args)
for target
in args.names]
357 graph = pygraphviz.AGraph(name=
'AthGraph', directed=
True, strict=
False)
359 graph.add_subgraph(name=g.get_name())
368 import multiprocessing
374 pool = multiprocessing.Pool(args.batch)
375 pool.map(doit, args.names)
◆ subgraph()
def python.scripts.cmake_depends.subgraph |
( |
|
graph, |
|
|
|
sources, |
|
|
|
reverse = False , |
|
|
|
maxdepth = None , |
|
|
|
nodegetter = lambda n : n.attr.get('label') |
|
) |
| |
Extract subgraph created by traversing from one or more sources.
Parameters are the same as in `traverse`. Return list of edge tuples.
Definition at line 85 of file cmake_depends.py.
85 def subgraph(graph, sources, reverse=False, maxdepth=None, nodegetter=lambda n : n.attr.get(
'label')):
86 """Extract subgraph created by traversing from one or more sources.
87 Parameters are the same as in `traverse`. Return list of edge tuples.
91 for a,b
in traverse(graph, root, reverse=reverse, maxdepth=maxdepth, nodegetter=nodegetter):
93 if reverse: edges.add((b,a))
94 else: edges.add((a,b))
◆ traverse()
def python.scripts.cmake_depends.traverse |
( |
|
graph, |
|
|
|
root, |
|
|
|
reverse = False , |
|
|
|
maxdepth = None , |
|
|
|
nodegetter = lambda n:n |
|
) |
| |
Depth-limited BFS edge traversal of graph starting at root.
@param graph graph
@param root start node for traversal
@param reverse traverse graph in reverse
@param maxdepth maximum traversal depth (1 = only direct neighbors)
@param nodegetter functor returning node names
@return edge tuple (parent,node)
Inspired by https://github.com/networkx/networkx/tree/master/networkx/algorithms/traversal
Definition at line 51 of file cmake_depends.py.
51 def traverse(graph, root, reverse=False, maxdepth=None, nodegetter=lambda n:n):
52 """Depth-limited BFS edge traversal of graph starting at root.
55 @param root start node for traversal
56 @param reverse traverse graph in reverse
57 @param maxdepth maximum traversal depth (1 = only direct neighbors)
58 @param nodegetter functor returning node names
59 @return edge tuple (parent,node)
61 Inspired by https://github.com/networkx/networkx/tree/master/networkx/algorithms/traversal
65 queue = deque([(root,root,0)])
66 neighbors = graph.iterpred
if reverse
else graph.itersucc
68 parent,node,level = queue.popleft()
70 if node
not in visited_nodes:
71 visited_nodes.add(node)
74 if maxdepth
is None or level < maxdepth:
75 queue.extend((node,n,level+1)
for n
in neighbors(node))
78 queue.extend((node,n,level+1)
for n
in neighbors(node)
if n
in visited_nodes)
80 if (parent,node)
not in visited_edges:
81 visited_edges.add((parent,node))
82 yield nodegetter(parent), nodegetter(node)
◆ py_style
python.scripts.cmake_depends.py_style |
def create_dep_graph(target, deps, pydeps, args)
def copy_graph(source, dest)
def traverse(graph, root, reverse=False, maxdepth=None, nodegetter=lambda n:n)
int run(int argc, char *argv[])
def print_dep_graph(graph, args, package_paths={})
def read_package_list(package_file)
def subgraph(graph, sources, reverse=False, maxdepth=None, nodegetter=lambda n :n.attr.get('label'))
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
std::string join(const std::vector< std::string > &v, const char c=',')
def lrstrip(s, prefix, postfix)
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)