OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/env python | |
awong
2014/09/03 20:25:35
Add a newline?
scottmg
2014/09/03 20:42:29
Done. M-A always wants it removed, so now I'm all
| |
2 # Copyright 2014 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. | |
5 | |
6 """Given the output of -t commands from a ninja build for a gyp and GN generated | |
7 build, report on differences between the command lines.""" | |
8 | |
9 | |
10 import os | |
11 import sys | |
12 | |
13 | |
14 def FindAndRemoveArgWithValue(command_line, argname): | |
15 """Given a command line as a list, remove and return the value of an option | |
16 that takes a value as a separate entry. Modifies |command_line| in place.""" | |
awong
2014/09/03 20:25:35
Follow docstring style?
https://google-styleguide
scottmg
2014/09/03 20:42:29
Done.
| |
17 location = command_line.index(argname) | |
18 value = command_line[location + 1] | |
19 command_line[location:location + 2] = [] | |
20 return value | |
21 | |
22 | |
23 def MergeSpacedArgs(command_line, argname): | |
24 """Combine an argument |argname| with its value separated by a space. | |
25 Modifies |command_line| in place.""" | |
26 i = 0 | |
27 while i < len(command_line): | |
28 if command_line[i] == argname: | |
29 command_line[i:i + 2] = [command_line[i] + ' ' + command_line[i + 1]] | |
awong
2014/09/03 20:25:35
Why not just create a new array and return? This l
scottmg
2014/09/03 20:42:29
Done.
| |
30 i += 1 | |
31 | |
32 | |
33 def GetFlags(lines): | |
34 """Turn a list of command lines into a semi-structured dict.""" | |
35 flags_by_output = {} | |
36 for line in lines: | |
37 # TODO(scottmg): Hacky way of getting only cc for now. | |
38 if 'clang' not in line: | |
39 continue | |
40 | |
41 # TODO(scottmg): Proper escapes. | |
42 command_line = line.strip().split()[1:] | |
43 | |
44 output_name = FindAndRemoveArgWithValue(command_line, '-o') | |
45 dep_name = FindAndRemoveArgWithValue(command_line, '-MF') | |
46 | |
47 MergeSpacedArgs(command_line, '-Xclang') | |
48 | |
49 defines = [x for x in command_line if x.startswith('-D')] | |
50 include_dirs = [x for x in command_line if x.startswith('-I')] | |
51 dash_f = [x for x in command_line if x.startswith('-f')] | |
52 warnings = [x for x in command_line if x.startswith('-W')] | |
53 cc_file = [x for x in command_line if x.endswith('.cc') or x.endswith('.c')] | |
54 assert len(cc_file) == 1 | |
55 others = [x for x in command_line if x not in defines and \ | |
56 x not in include_dirs and \ | |
57 x not in dash_f and \ | |
58 x not in warnings and \ | |
59 x not in cc_file] | |
60 flags_by_output[cc_file[0]] = { | |
61 'output': output_name, | |
62 'depname': dep_name, | |
63 'defines': sorted(defines), | |
64 'include_dirs': sorted(include_dirs), # TODO(scottmg): This is wrong. | |
65 'dash_f': sorted(dash_f), | |
66 'warnings': sorted(warnings), | |
67 'other': sorted(others), | |
68 } | |
69 return flags_by_output | |
70 | |
71 | |
72 def CompareLists(gyp, gn, name, dont_care=[]): | |
73 """Output any differences between to lists, ignoring anything in | |
74 |dont_care|.""" | |
75 if gyp[name] != gn[name]: | |
76 print ' %s differ:' % name | |
77 gyp_set = set(gyp[name]) - set(dont_care) | |
78 gn_set = set(gn[name]) - set(dont_care) | |
79 print ' In gyp, but not in GN:\n %s' % '\n '.join( | |
80 sorted(gyp_set - gn_set)) | |
81 print ' In GN, but not in gyp:\n %s' % '\n '.join( | |
82 sorted(gn_set - gyp_set)) | |
83 print | |
84 return 1 | |
awong
2014/09/03 20:25:35
Use True and False?
scottmg
2014/09/03 20:42:29
Done. (was just because it's used as a main() retu
| |
85 return 0 | |
86 | |
87 | |
88 def main(): | |
89 if len(sys.argv) != 3: | |
90 print 'usage: %s gyp_commands.txt gn_commands.txt' % __file__ | |
91 return 1 | |
92 gyp = open(sys.argv[1], 'rb').readlines() | |
awong
2014/09/03 20:25:35
Nit..with syntax is a little cleaner.
with open(.
scottmg
2014/09/03 20:42:29
Done.
| |
93 gn = open(sys.argv[2], 'rb').readlines() | |
94 all_gyp_flags = GetFlags(gyp) | |
95 all_gn_flags = GetFlags(gn) | |
96 gyp_files = set(all_gyp_flags.keys()) | |
97 gn_files = set(all_gn_flags.keys()) | |
98 diffs = 0 | |
awong
2014/09/03 20:25:35
True and False?
scottmg
2014/09/03 20:42:29
Done.
| |
99 if gyp_files != gn_files: | |
100 print 'Different set of sources files:' | |
101 print ' In gyp, not in GN:\n %s' % '\n '.join( | |
102 sorted(gyp_files - gn_files)) | |
103 print ' In GN, not in gyp:\n %s' % '\n '.join( | |
104 sorted(gn_files - gyp_files)) | |
105 print '\nNote that flags will only be compared for files in both sets.\n' | |
106 diffs |= 1 | |
107 file_list = gyp_files & gn_files | |
108 for filename in sorted(file_list): | |
109 gyp_flags = all_gyp_flags[filename] | |
110 gn_flags = all_gn_flags[filename] | |
111 print filename | |
112 diffs |= CompareLists(gyp_flags, gn_flags, 'dash_f') | |
113 diffs |= CompareLists(gyp_flags, gn_flags, 'defines', dont_care=[ | |
114 '-DENABLE_PRE_SYNC_BACKUP', | |
115 '-DENABLE_WEBRTC=1', | |
116 '-DUSE_LIBJPEG_TURBO=1', | |
117 '-DUSE_PANGO=1', | |
118 '-DUSE_SYMBOLIZE', | |
119 ]) | |
120 diffs |= CompareLists(gyp_flags, gn_flags, 'include_dirs') | |
121 diffs |= CompareLists(gyp_flags, gn_flags, 'warnings') | |
122 diffs |= CompareLists(gyp_flags, gn_flags, 'other') | |
123 return diffs | |
124 | |
125 | |
126 if __name__ == '__main__': | |
127 sys.exit(main()) | |
OLD | NEW |