2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Prints paths between gyp targets.
14 from collections
import deque
19 tools/gyp-explain.py [--dot] chrome_dll# gtest#
23 def GetPath(graph
, fro
, to
):
24 """Given a graph in (node -> list of successor nodes) dictionary format,
25 yields all paths from |fro| to |to|, starting with the shortest."""
26 # Storing full paths in the queue is a bit wasteful, but good enough for this.
27 q
= deque([(fro
, [])])
33 q
.append((d
, path
+ [t
]))
36 def MatchNode(graph
, substring
):
37 """Given a dictionary, returns the key that matches |substring| best. Exits
38 if there's not one single best match."""
41 if substring
in target
:
42 candidates
.append(target
)
45 print 'No targets match "%s"' % substring
47 if len(candidates
) > 1:
48 print 'More than one target matches "%s": %s' % (
49 substring
, ' '.join(candidates
))
54 def EscapeForDot(string
):
56 if string
.endswith(suffix
):
57 string
= string
[:-len(suffix
)]
58 string
= string
.replace('\\', '\\\\')
59 return '"' + string
+ '"'
62 def GenerateDot(fro
, to
, paths
):
63 """Generates an input file for graphviz's dot program."""
64 prefixes
= [os
.path
.commonprefix(path
) for path
in paths
]
65 prefix
= os
.path
.commonprefix(prefixes
)
66 print '// Build with "dot -Tpng -ooutput.png this_file.dot"'
67 # "strict" collapses common paths.
68 print 'strict digraph {'
70 print (' -> '.join(EscapeForDot(item
[len(prefix
):]) for item
in path
)), ';'
75 # Check that dump.json exists and that it's not too old.
76 dump_json_dirty
= False
78 st
= os
.stat('dump.json')
79 file_age_s
= time
.time() - st
.st_mtime
80 if file_age_s
> 2 * 60 * 60:
81 print 'dump.json is more than 2 hours old.'
82 dump_json_dirty
= True
84 print 'dump.json not found.'
85 dump_json_dirty
= True
89 print ' GYP_GENERATORS=dump_dependency_json build/gyp_chromium'
90 print 'first, then try again.'
93 g
= json
.load(open('dump.json'))
95 if len(argv
) not in (3, 4):
99 generate_dot
= argv
[1] == '--dot'
103 fro
= MatchNode(g
, argv
[1])
104 to
= MatchNode(g
, argv
[2])
106 paths
= list(GetPath(g
, fro
, to
))
109 GenerateDot(fro
, to
, paths
)
111 print 'These paths lead from %s to %s:' % (fro
, to
)
113 print ' -> '.join(path
)
115 print 'No paths found from %s to %s.' % (fro
, to
)
118 if __name__
== '__main__':