113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#!/usr/bin/env python
213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch# Copyright 2016 the V8 project authors. All rights reserved.
413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch# Copyright 2014 The Chromium Authors. All rights reserved.
513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch# Use of this source code is governed by a BSD-style license that can be
613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch# found in the LICENSE file.
713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch"""Given the output of -t commands from a ninja build for a gyp and GN generated
913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochbuild, report on differences between the command lines."""
1013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochimport os
1313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochimport shlex
1413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochimport subprocess
1513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochimport sys
1613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch# Must be in v8/.
1913e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
2013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochos.chdir(BASE_DIR)
2113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
2213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
2313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochg_total_differences = 0
2413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
2513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
2613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochdef FindAndRemoveArgWithValue(command_line, argname):
2713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  """Given a command line as a list, remove and return the value of an option
2813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  that takes a value as a separate entry.
2913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
3013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Modifies |command_line| in place.
3113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  """
3213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if argname not in command_line:
3313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return ''
3413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  location = command_line.index(argname)
3513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  value = command_line[location + 1]
3613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  command_line[location:location + 2] = []
3713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return value
3813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
3913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
4013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochdef MergeSpacedArgs(command_line, argname):
4113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  """Combine all arguments |argname| with their values, separated by a space."""
4213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  i = 0
4313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  result = []
4413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  while i < len(command_line):
4513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    arg = command_line[i]
4613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if arg == argname:
4713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      result.append(arg + ' ' + command_line[i + 1])
4813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      i += 1
4913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    else:
5013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      result.append(arg)
5113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    i += 1
5213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return result
5313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
5513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochdef NormalizeSymbolArguments(command_line):
5613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  """Normalize -g arguments.
5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
5813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  If there's no -g args, it's equivalent to -g0. -g2 is equivalent to -g.
5913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Modifies |command_line| in place.
6013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  """
6113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  # Strip -g0 if there's no symbols.
6213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  have_some_symbols = False
6313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for x in command_line:
6413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if x.startswith('-g') and x != '-g0':
6513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      have_some_symbols = True
6613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if not have_some_symbols and '-g0' in command_line:
6713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    command_line.remove('-g0')
6813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
6913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  # Rename -g2 to -g.
7013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if '-g2' in command_line:
7113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    command_line[command_line.index('-g2')] = '-g'
7213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
7313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
7413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochdef GetFlags(lines, build_dir):
7513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  """Turn a list of command lines into a semi-structured dict."""
7613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  is_win = sys.platform == 'win32'
7713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  flags_by_output = {}
7813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for line in lines:
7913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    command_line = shlex.split(line.strip(), posix=not is_win)[1:]
8013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
8113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    output_name = FindAndRemoveArgWithValue(command_line, '-o')
8213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    dep_name = FindAndRemoveArgWithValue(command_line, '-MF')
8313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
8413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    NormalizeSymbolArguments(command_line)
8513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
8613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    command_line = MergeSpacedArgs(command_line, '-Xclang')
8713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
8813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    cc_file = [x for x in command_line if x.endswith('.cc') or
8913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                          x.endswith('.c') or
9013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                          x.endswith('.cpp')]
9113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if len(cc_file) != 1:
9213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      print 'Skipping %s' % command_line
9313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      continue
9413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    assert len(cc_file) == 1
9513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
9613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if is_win:
9713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      rsp_file = [x for x in command_line if x.endswith('.rsp')]
9813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      assert len(rsp_file) <= 1
9913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if rsp_file:
10013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        rsp_file = os.path.join(build_dir, rsp_file[0][1:])
10113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        with open(rsp_file, "r") as open_rsp_file:
10213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          command_line = shlex.split(open_rsp_file, posix=False)
10313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
10413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    defines = [x for x in command_line if x.startswith('-D')]
10513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    include_dirs = [x for x in command_line if x.startswith('-I')]
10613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    dash_f = [x for x in command_line if x.startswith('-f')]
10713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    warnings = \
10813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        [x for x in command_line if x.startswith('/wd' if is_win else '-W')]
10913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    others = [x for x in command_line if x not in defines and \
11013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                         x not in include_dirs and \
11113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                         x not in dash_f and \
11213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                         x not in warnings and \
11313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                         x not in cc_file]
11413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
11513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    for index, value in enumerate(include_dirs):
11613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if value == '-Igen':
11713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        continue
11813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      path = value[2:]
11913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if not os.path.isabs(path):
12013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        path = os.path.join(build_dir, path)
12113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      include_dirs[index] = '-I' + os.path.normpath(path)
12213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
12313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    # GYP supports paths above the source root like <(DEPTH)/../foo while such
12413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    # paths are unsupported by gn. But gn allows to use system-absolute paths
12513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    # instead (paths that start with single '/'). Normalize all paths.
12613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    cc_file = [os.path.normpath(os.path.join(build_dir, cc_file[0]))]
12713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
12813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    # Filter for libFindBadConstructs.so having a relative path in one and
12913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    # absolute path in the other.
13013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    others_filtered = []
13113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    for x in others:
13213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if x.startswith('-Xclang ') and x.endswith('libFindBadConstructs.so'):
13313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        others_filtered.append(
13413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            '-Xclang ' +
13513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            os.path.join(os.getcwd(),
13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                         os.path.normpath(
13713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                             os.path.join('out/gn_flags', x.split(' ', 1)[1]))))
13813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      elif x.startswith('-B'):
13913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        others_filtered.append(
14013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            '-B' +
14113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch            os.path.join(os.getcwd(),
14213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                         os.path.normpath(os.path.join('out/gn_flags', x[2:]))))
14313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      else:
14413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        others_filtered.append(x)
14513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    others = others_filtered
14613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
14713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    flags_by_output[cc_file[0]] = {
14813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      'output': output_name,
14913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      'depname': dep_name,
15013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      'defines': sorted(defines),
15113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      'include_dirs': sorted(include_dirs),  # TODO(scottmg): This is wrong.
15213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      'dash_f': sorted(dash_f),
15313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      'warnings': sorted(warnings),
15413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      'other': sorted(others),
15513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
15613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return flags_by_output
15713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
15813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
15913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochdef CompareLists(gyp, gn, name, dont_care_gyp=None, dont_care_gn=None):
16013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  """Return a report of any differences between gyp and gn lists, ignoring
16113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  anything in |dont_care_{gyp|gn}| respectively."""
16213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  global g_total_differences
16313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if not dont_care_gyp:
16413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    dont_care_gyp = []
16513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if not dont_care_gn:
16613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    dont_care_gn = []
16713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  output = ''
16813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if gyp[name] != gn[name]:
16913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    gyp_set = set(gyp[name])
17013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    gn_set = set(gn[name])
17113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    missing_in_gyp = gyp_set - gn_set
17213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    missing_in_gn = gn_set - gyp_set
17313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    missing_in_gyp -= set(dont_care_gyp)
17413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    missing_in_gn -= set(dont_care_gn)
17513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if missing_in_gyp or missing_in_gn:
17613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      output += '  %s differ:\n' % name
17713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if missing_in_gyp:
17813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      output += '    In gyp, but not in GN:\n      %s' % '\n      '.join(
17913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          sorted(missing_in_gyp)) + '\n'
18013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      g_total_differences += len(missing_in_gyp)
18113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if missing_in_gn:
18213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      output += '    In GN, but not in gyp:\n      %s' % '\n      '.join(
18313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          sorted(missing_in_gn)) + '\n\n'
18413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      g_total_differences += len(missing_in_gn)
18513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return output
18613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
18713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
18813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochdef Run(command_line):
18913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  """Run |command_line| as a subprocess and return stdout. Raises on error."""
190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  try:
191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return subprocess.check_output(command_line, shell=True)
192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  except subprocess.CalledProcessError as e:
193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    # Rescue the output we got until the exception happened.
194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    print '#### Stdout: ####################################################'
195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    print e.output
196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    print '#################################################################'
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    raise
19813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
19913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
20013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochdef main():
20113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if len(sys.argv) < 4:
20213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    print ('usage: %s gn_outdir gyp_outdir gn_target '
20313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           '[gyp_target1, gyp_target2, ...]' % __file__)
20413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return 1
20513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
20613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if len(sys.argv) == 4:
20713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    sys.argv.append(sys.argv[3])
20813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  gn_out_dir = sys.argv[1]
20913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  print >> sys.stderr, 'Expecting gn outdir in %s...' % gn_out_dir
21013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  gn = Run('ninja -C %s -t commands %s' % (gn_out_dir, sys.argv[3]))
21113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if sys.platform == 'win32':
21213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    # On Windows flags are stored in .rsp files which are created during build.
21313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    print >> sys.stderr, 'Building in %s...' % gn_out_dir
21413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Run('ninja -C %s -d keeprsp %s' % (gn_out_dir, sys.argv[3]))
21513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
21613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  gyp_out_dir = sys.argv[2]
21713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  print >> sys.stderr, 'Expecting gyp outdir in %s...' % gyp_out_dir
21813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  gyp = Run('ninja -C %s -t commands %s' % (gyp_out_dir, " ".join(sys.argv[4:])))
21913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if sys.platform == 'win32':
22013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    # On Windows flags are stored in .rsp files which are created during build.
22113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    print >> sys.stderr, 'Building in %s...' % gyp_out_dir
22213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Run('ninja -C %s -d keeprsp %s' % (gyp_out_dir, " ".join(sys.argv[4:])))
22313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
22413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  all_gyp_flags = GetFlags(gyp.splitlines(),
22513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                           os.path.join(os.getcwd(), gyp_out_dir))
22613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  all_gn_flags = GetFlags(gn.splitlines(),
22713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                          os.path.join(os.getcwd(), gn_out_dir))
22813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  gyp_files = set(all_gyp_flags.keys())
22913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  gn_files = set(all_gn_flags.keys())
23013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  different_source_list = gyp_files != gn_files
23113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if different_source_list:
23213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    print 'Different set of sources files:'
23313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    print '  In gyp, not in GN:\n    %s' % '\n    '.join(
23413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        sorted(gyp_files - gn_files))
23513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    print '  In GN, not in gyp:\n    %s' % '\n    '.join(
23613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        sorted(gn_files - gyp_files))
23713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    print '\nNote that flags will only be compared for files in both sets.\n'
23813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  file_list = gyp_files & gn_files
23913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  files_with_given_differences = {}
24013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for filename in sorted(file_list):
24113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    gyp_flags = all_gyp_flags[filename]
24213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    gn_flags = all_gn_flags[filename]
24313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    differences = CompareLists(gyp_flags, gn_flags, 'dash_f')
24413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    differences += CompareLists(gyp_flags, gn_flags, 'defines')
24513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    differences += CompareLists(gyp_flags, gn_flags, 'include_dirs',
24613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                ['-I%s' % os.path.dirname(BASE_DIR)])
24713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    differences += CompareLists(gyp_flags, gn_flags, 'warnings',
24813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        # More conservative warnings in GN we consider to be OK.
24913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        dont_care_gyp=[
25013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '/wd4091',  # 'keyword' : ignored on left of 'type' when no variable
25113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                      # is declared.
25213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '/wd4456',  # Declaration hides previous local declaration.
25313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '/wd4457',  # Declaration hides function parameter.
25413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '/wd4458',  # Declaration hides class member.
25513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '/wd4459',  # Declaration hides global declaration.
25613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '/wd4702',  # Unreachable code.
25713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '/wd4800',  # Forcing value to bool 'true' or 'false'.
25813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '/wd4838',  # Conversion from 'type' to 'type' requires a narrowing
25913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                      # conversion.
26013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        ] if sys.platform == 'win32' else None,
26113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        dont_care_gn=[
26213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '-Wendif-labels',
26313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '-Wextra',
26413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          '-Wsign-compare',
26513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        ] if not sys.platform == 'win32' else None)
26613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    differences += CompareLists(gyp_flags, gn_flags, 'other')
26713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if differences:
26813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      files_with_given_differences.setdefault(differences, []).append(filename)
26913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
27013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for diff, files in files_with_given_differences.iteritems():
27113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    print '\n'.join(sorted(files))
27213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    print diff
27313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
27413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  print 'Total differences:', g_total_differences
27513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  # TODO(scottmg): Return failure on difference once we're closer to identical.
27613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return 0
27713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
27813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
27913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochif __name__ == '__main__':
28013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  sys.exit(main())
281