Index: tools/gn/bin/gyp_flag_compare.py |
diff --git a/tools/gn/bin/gyp_flag_compare.py b/tools/gn/bin/gyp_flag_compare.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..790685af0eef0a9ad5e6f1615f69cf8cf8e13ebc |
--- /dev/null |
+++ b/tools/gn/bin/gyp_flag_compare.py |
@@ -0,0 +1,127 @@ |
+#!/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
|
+# Copyright 2014 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+"""Given the output of -t commands from a ninja build for a gyp and GN generated |
+build, report on differences between the command lines.""" |
+ |
+ |
+import os |
+import sys |
+ |
+ |
+def FindAndRemoveArgWithValue(command_line, argname): |
+ """Given a command line as a list, remove and return the value of an option |
+ 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.
|
+ location = command_line.index(argname) |
+ value = command_line[location + 1] |
+ command_line[location:location + 2] = [] |
+ return value |
+ |
+ |
+def MergeSpacedArgs(command_line, argname): |
+ """Combine an argument |argname| with its value separated by a space. |
+ Modifies |command_line| in place.""" |
+ i = 0 |
+ while i < len(command_line): |
+ if command_line[i] == argname: |
+ 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.
|
+ i += 1 |
+ |
+ |
+def GetFlags(lines): |
+ """Turn a list of command lines into a semi-structured dict.""" |
+ flags_by_output = {} |
+ for line in lines: |
+ # TODO(scottmg): Hacky way of getting only cc for now. |
+ if 'clang' not in line: |
+ continue |
+ |
+ # TODO(scottmg): Proper escapes. |
+ command_line = line.strip().split()[1:] |
+ |
+ output_name = FindAndRemoveArgWithValue(command_line, '-o') |
+ dep_name = FindAndRemoveArgWithValue(command_line, '-MF') |
+ |
+ MergeSpacedArgs(command_line, '-Xclang') |
+ |
+ defines = [x for x in command_line if x.startswith('-D')] |
+ include_dirs = [x for x in command_line if x.startswith('-I')] |
+ dash_f = [x for x in command_line if x.startswith('-f')] |
+ warnings = [x for x in command_line if x.startswith('-W')] |
+ cc_file = [x for x in command_line if x.endswith('.cc') or x.endswith('.c')] |
+ assert len(cc_file) == 1 |
+ others = [x for x in command_line if x not in defines and \ |
+ x not in include_dirs and \ |
+ x not in dash_f and \ |
+ x not in warnings and \ |
+ x not in cc_file] |
+ flags_by_output[cc_file[0]] = { |
+ 'output': output_name, |
+ 'depname': dep_name, |
+ 'defines': sorted(defines), |
+ 'include_dirs': sorted(include_dirs), # TODO(scottmg): This is wrong. |
+ 'dash_f': sorted(dash_f), |
+ 'warnings': sorted(warnings), |
+ 'other': sorted(others), |
+ } |
+ return flags_by_output |
+ |
+ |
+def CompareLists(gyp, gn, name, dont_care=[]): |
+ """Output any differences between to lists, ignoring anything in |
+ |dont_care|.""" |
+ if gyp[name] != gn[name]: |
+ print ' %s differ:' % name |
+ gyp_set = set(gyp[name]) - set(dont_care) |
+ gn_set = set(gn[name]) - set(dont_care) |
+ print ' In gyp, but not in GN:\n %s' % '\n '.join( |
+ sorted(gyp_set - gn_set)) |
+ print ' In GN, but not in gyp:\n %s' % '\n '.join( |
+ sorted(gn_set - gyp_set)) |
+ 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
|
+ return 0 |
+ |
+ |
+def main(): |
+ if len(sys.argv) != 3: |
+ print 'usage: %s gyp_commands.txt gn_commands.txt' % __file__ |
+ return 1 |
+ 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.
|
+ gn = open(sys.argv[2], 'rb').readlines() |
+ all_gyp_flags = GetFlags(gyp) |
+ all_gn_flags = GetFlags(gn) |
+ gyp_files = set(all_gyp_flags.keys()) |
+ gn_files = set(all_gn_flags.keys()) |
+ diffs = 0 |
awong
2014/09/03 20:25:35
True and False?
scottmg
2014/09/03 20:42:29
Done.
|
+ if gyp_files != gn_files: |
+ print 'Different set of sources files:' |
+ print ' In gyp, not in GN:\n %s' % '\n '.join( |
+ sorted(gyp_files - gn_files)) |
+ print ' In GN, not in gyp:\n %s' % '\n '.join( |
+ sorted(gn_files - gyp_files)) |
+ print '\nNote that flags will only be compared for files in both sets.\n' |
+ diffs |= 1 |
+ file_list = gyp_files & gn_files |
+ for filename in sorted(file_list): |
+ gyp_flags = all_gyp_flags[filename] |
+ gn_flags = all_gn_flags[filename] |
+ print filename |
+ diffs |= CompareLists(gyp_flags, gn_flags, 'dash_f') |
+ diffs |= CompareLists(gyp_flags, gn_flags, 'defines', dont_care=[ |
+ '-DENABLE_PRE_SYNC_BACKUP', |
+ '-DENABLE_WEBRTC=1', |
+ '-DUSE_LIBJPEG_TURBO=1', |
+ '-DUSE_PANGO=1', |
+ '-DUSE_SYMBOLIZE', |
+ ]) |
+ diffs |= CompareLists(gyp_flags, gn_flags, 'include_dirs') |
+ diffs |= CompareLists(gyp_flags, gn_flags, 'warnings') |
+ diffs |= CompareLists(gyp_flags, gn_flags, 'other') |
+ return diffs |
+ |
+ |
+if __name__ == '__main__': |
+ sys.exit(main()) |