15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This script is wrapper for Chromium that adds some support for how GYP
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# is invoked by Chromium beyond what can be done in the gclient hooks.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import glob
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import gyp_environment
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochimport re
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import shlex
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import subprocess
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import string
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)import vs_toolchain
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)script_dir = os.path.dirname(os.path.realpath(__file__))
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir))
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib'))
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import gyp
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)# Assume this file is in a one-level-deep subdirectory of the source root.
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Add paths so that pymod_do_main(...) can import files.
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccisys.path.insert(1, os.path.join(chrome_src, 'build', 'android', 'gyp'))
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)sys.path.insert(1, os.path.join(chrome_src, 'tools'))
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sys.path.insert(1, os.path.join(chrome_src, 'tools', 'generate_shim_headers'))
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sys.path.insert(1, os.path.join(chrome_src, 'tools', 'grit'))
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sys.path.insert(1, os.path.join(chrome_src, 'chrome', 'tools', 'build'))
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)sys.path.insert(1, os.path.join(chrome_src, 'chromecast', 'tools', 'build'))
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sys.path.insert(1, os.path.join(chrome_src, 'native_client', 'build'))
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)sys.path.insert(1, os.path.join(chrome_src, 'native_client_sdk', 'src',
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    'build_tools'))
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochsys.path.insert(1, os.path.join(chrome_src, 'remoting', 'tools', 'build'))
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'liblouis'))
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit',
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    'Source', 'build', 'scripts'))
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# On Windows, Psyco shortens warm runs of build/gyp_chromium by about
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 20 seconds on a z600 machine with 12 GB of RAM, from 90 down to 70
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# seconds.  Conversely, memory usage of build/gyp_chromium with Psyco
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# maxes out at about 158 MB vs. 132 MB without it.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Psyco uses native libraries, so we need to load a different
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# installation depending on which OS we are running under. It has not
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# been tested whether using Psyco on our Mac and Linux builds is worth
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# it (the GYP running time is a lot shorter, so the JIT startup cost
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# may not be worth it).
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if sys.platform == 'win32':
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  try:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sys.path.insert(0, os.path.join(chrome_src, 'third_party', 'psyco_win32'))
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    import psyco
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  except:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    psyco = None
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)else:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  psyco = None
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)def GetSupplementalFiles():
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  """Returns a list of the supplemental files that are included in all GYP
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  sources."""
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return glob.glob(os.path.join(chrome_src, '*', 'supplement.gypi'))
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def ProcessGypDefinesItems(items):
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  """Converts a list of strings to a list of key-value pairs."""
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  result = []
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for item in items:
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tokens = item.split('=', 1)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    # Some GYP variables have hyphens, which we don't support.
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if len(tokens) == 2:
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      result += [(tokens[0], tokens[1])]
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    else:
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      # No value supplied, treat it as a boolean and set it. Note that we
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      # use the string '1' here so we have a consistent definition whether
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      # you do 'foo=1' or 'foo'.
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      result += [(tokens[0], '1')]
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochdef GetGypVars(supplemental_files):
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  """Returns a dictionary of all GYP vars."""
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  # Find the .gyp directory in the user's home directory.
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  home_dot_gyp = os.environ.get('GYP_CONFIG_DIR', None)
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if home_dot_gyp:
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    home_dot_gyp = os.path.expanduser(home_dot_gyp)
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if not home_dot_gyp:
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    home_vars = ['HOME']
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if sys.platform in ('cygwin', 'win32'):
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      home_vars.append('USERPROFILE')
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for home_var in home_vars:
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      home = os.getenv(home_var)
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if home != None:
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        home_dot_gyp = os.path.join(home, '.gyp')
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        if not os.path.exists(home_dot_gyp):
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          home_dot_gyp = None
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        else:
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          break
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if home_dot_gyp:
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    include_gypi = os.path.join(home_dot_gyp, "include.gypi")
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if os.path.exists(include_gypi):
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      supplemental_files += [include_gypi]
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # GYP defines from the supplemental.gypi files.
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  supp_items = []
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for supplement in supplemental_files:
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    with open(supplement, 'r') as f:
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      try:
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        file_data = eval(f.read(), {'__builtins__': None}, None)
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      except SyntaxError, e:
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        e.filename = os.path.abspath(supplement)
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        raise
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      variables = file_data.get('variables', [])
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      for v in variables:
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        supp_items += [(v, str(variables[v]))]
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # GYP defines from the environment.
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  env_items = ProcessGypDefinesItems(
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      shlex.split(os.environ.get('GYP_DEFINES', '')))
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # GYP defines from the command line. We can't use optparse since we want
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # to ignore all arguments other than "-D".
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cmdline_input_items = []
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for i in range(len(sys.argv))[1:]:
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if sys.argv[i].startswith('-D'):
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if sys.argv[i] == '-D' and i + 1 < len(sys.argv):
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        cmdline_input_items += [sys.argv[i + 1]]
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      elif len(sys.argv[i]) > 2:
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        cmdline_input_items += [sys.argv[i][2:]]
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cmdline_items = ProcessGypDefinesItems(cmdline_input_items)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  vars_dict = dict(supp_items + env_items + cmdline_items)
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return vars_dict
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def GetOutputDirectory():
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  """Returns the output directory that GYP will use."""
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # GYP generator flags from the command line. We can't use optparse since we
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  # want to ignore all arguments other than "-G".
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  needle = '-Goutput_dir='
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cmdline_input_items = []
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for item in sys.argv[1:]:
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if item.startswith(needle):
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return item[len(needle):]
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  env_items = shlex.split(os.environ.get('GYP_GENERATOR_FLAGS', ''))
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  needle = 'output_dir='
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for item in env_items:
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if item.startswith(needle):
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return item[len(needle):]
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return "out"
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)def additional_include_files(supplemental_files, args=[]):
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Returns a list of additional (.gypi) files to include, without duplicating
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ones that are already specified on the command line. The list of supplemental
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  include files is passed in as an argument.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Determine the include files specified on the command line.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # This doesn't cover all the different option formats you can use,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # but it's mainly intended to avoid duplicating flags on the automatic
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # makefile regeneration which only uses this format.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  specified_includes = set()
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for arg in args:
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if arg.startswith('-I') and len(arg) > 2:
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      specified_includes.add(os.path.realpath(arg[2:]))
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  result = []
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def AddInclude(path):
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if os.path.realpath(path) not in specified_includes:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result.append(path)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Always include common.gypi.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddInclude(os.path.join(script_dir, 'common.gypi'))
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Optionally add supplemental .gypi files if present.
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for supplement in supplemental_files:
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddInclude(supplement)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  # Disabling garbage collection saves about 1 second out of 16 on a Linux
19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  # z620 workstation. Since this is a short-lived process it's not a problem to
19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  # leak a few cyclyc references in order to spare the CPU cycles for
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  # scanning the heap.
19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  import gc
19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  gc.disable()
19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  args = sys.argv[1:]
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  use_analyzer = len(args) and args[0] == '--analyzer'
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if use_analyzer:
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    args.pop(0)
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    os.environ['GYP_GENERATORS'] = 'analyzer'
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    args.append('-Gconfig_path=' + args.pop(0))
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    args.append('-Ganalyzer_output_path=' + args.pop(0))
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if int(os.environ.get('GYP_CHROMIUM_NO_ACTION', 0)):
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    print 'Skipping gyp_chromium due to GYP_CHROMIUM_NO_ACTION env var.'
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    sys.exit(0)
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Use the Psyco JIT if available.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if psyco:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    psyco.profile()
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    print "Enabled Psyco JIT."
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Fall back on hermetic python if we happen to get run under cygwin.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # TODO(bradnelson): take this out once this issue is fixed:
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  #    http://code.google.com/p/gyp/issues/detail?id=177
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if sys.platform == 'cygwin':
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    import find_depot_tools
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    depot_tools_path = find_depot_tools.add_depot_tools_to_path()
2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    python_dir = sorted(glob.glob(os.path.join(depot_tools_path,
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               'python2*_bin')))[-1]
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    env = os.environ.copy()
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    env['PATH'] = python_dir + os.pathsep + env.get('PATH', '')
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p = subprocess.Popen(
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       [os.path.join(python_dir, 'python.exe')] + sys.argv,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       env=env, shell=False)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    p.communicate()
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sys.exit(p.returncode)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # This could give false positives since it doesn't actually do real option
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # parsing.  Oh well.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gyp_file_specified = False
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for arg in args:
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if arg.endswith('.gyp'):
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gyp_file_specified = True
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  gyp_environment.SetEnvironment()
2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # If we didn't get a file, check an env var, and then fall back to
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # assuming 'all.gyp' from the same directory as the script.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if not gyp_file_specified:
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gyp_file = os.environ.get('CHROMIUM_GYP_FILE')
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if gyp_file:
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # Note that CHROMIUM_GYP_FILE values can't have backslashes as
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      # path separators even on Windows due to the use of shlex.split().
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      args.extend(shlex.split(gyp_file))
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else:
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      args.append(os.path.join(script_dir, 'all.gyp'))
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # There shouldn't be a circular dependency relationship between .gyp files,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # but in Chromium's .gyp files, on non-Mac platforms, circular relationships
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # currently exist.  The check for circular dependencies is currently
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # bypassed on other platforms, but is left enabled on the Mac, where a
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # violation of the rule causes Xcode to misbehave badly.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # TODO(mark): Find and kill remaining circular dependencies, and remove this
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # option.  http://crbug.com/35878.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # TODO(tc): Fix circular dependencies in ChromiumOS then add linux2 to the
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # list.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if sys.platform not in ('darwin',):
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    args.append('--no-circular-check')
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  # We explicitly don't support the make gyp generator (crbug.com/348686). Be
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  # nice and fail here, rather than choking in gyp.
2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if re.search(r'(^|,|\s)make($|,|\s)', os.environ.get('GYP_GENERATORS', '')):
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    print 'Error: make gyp generator not supported (check GYP_GENERATORS).'
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    sys.exit(1)
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # If CHROMIUM_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # to enfore syntax checking.
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  syntax_check = os.environ.get('CHROMIUM_GYP_SYNTAX_CHECK')
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if syntax_check and int(syntax_check):
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    args.append('--check')
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  supplemental_includes = GetSupplementalFiles()
279effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  gyp_vars_dict = GetGypVars(supplemental_includes)
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  # TODO(dmikurube): Remove these checks and messages after a while.
282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if ('linux_use_tcmalloc' in gyp_vars_dict or
283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      'android_use_tcmalloc' in gyp_vars_dict):
284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    print '*****************************************************************'
285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    print '"linux_use_tcmalloc" and "android_use_tcmalloc" are deprecated!'
286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    print '-----------------------------------------------------------------'
287010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    print 'You specify "linux_use_tcmalloc" or "android_use_tcmalloc" in'
288010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    print 'your GYP_DEFINES. Please switch them into "use_allocator" now.'
289010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    print 'See http://crbug.com/345554 for the details.'
290010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    print '*****************************************************************'
291010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  # Automatically turn on crosscompile support for platforms that need it.
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  # (The Chrome OS build sets CC_host / CC_target which implicitly enables
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  # this mode.)
295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if all(('ninja' in os.environ.get('GYP_GENERATORS', ''),
296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          gyp_vars_dict.get('OS') in ['android', 'ios'],
297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          'GYP_CROSSCOMPILE' not in os.environ)):
298a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    os.environ['GYP_CROSSCOMPILE'] = '1'
299e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if gyp_vars_dict.get('OS') == 'android':
300e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    args.append('--check')
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  args.extend(
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ['-I' + i for i in additional_include_files(supplemental_includes, args)])
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  args.extend(['-D', 'gyp_output_dir=' + GetOutputDirectory()])
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
307116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if not use_analyzer:
308116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    print 'Updating projects from gyp files...'
309116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    sys.stdout.flush()
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # Off we go...
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gyp_rc = gyp.main(args)
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
314116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if not use_analyzer:
3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    vs2013_runtime_dll_dirs = vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if vs2013_runtime_dll_dirs:
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      x64_runtime, x86_runtime = vs2013_runtime_dll_dirs
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      vs_toolchain.CopyVsRuntimeDlls(
31923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        os.path.join(chrome_src, GetOutputDirectory()),
32023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        (x86_runtime, x64_runtime))
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sys.exit(gyp_rc)
323