Home | History | Annotate | Download | only in build
      1 #!/usr/bin/env python
      2 
      3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 # This script is wrapper for Chromium that adds some support for how GYP
      8 # is invoked by Chromium beyond what can be done in the gclient hooks.
      9 
     10 import glob
     11 import gyp_helper
     12 import os
     13 import shlex
     14 import subprocess
     15 import sys
     16 
     17 script_dir = os.path.dirname(os.path.realpath(__file__))
     18 chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir))
     19 
     20 sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib'))
     21 import gyp
     22 
     23 # Add paths so that pymod_do_main(...) can import files.
     24 sys.path.insert(1, os.path.join(chrome_src, 'tools', 'generate_shim_headers'))
     25 sys.path.insert(1, os.path.join(chrome_src, 'tools', 'grit'))
     26 sys.path.insert(1, os.path.join(chrome_src, 'chrome', 'tools', 'build'))
     27 sys.path.insert(1, os.path.join(chrome_src, 'native_client', 'build'))
     28 sys.path.insert(1, os.path.join(chrome_src, 'remoting', 'tools', 'build'))
     29 sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit',
     30     'Source', 'core', 'scripts'))
     31 # TODO(adamk): Remove this line once core.gyp is no longer a directory
     32 sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit',
     33     'Source', 'core', 'core.gyp', 'scripts'))
     34 
     35 
     36 # On Windows, Psyco shortens warm runs of build/gyp_chromium by about
     37 # 20 seconds on a z600 machine with 12 GB of RAM, from 90 down to 70
     38 # seconds.  Conversely, memory usage of build/gyp_chromium with Psyco
     39 # maxes out at about 158 MB vs. 132 MB without it.
     40 #
     41 # Psyco uses native libraries, so we need to load a different
     42 # installation depending on which OS we are running under. It has not
     43 # been tested whether using Psyco on our Mac and Linux builds is worth
     44 # it (the GYP running time is a lot shorter, so the JIT startup cost
     45 # may not be worth it).
     46 if sys.platform == 'win32':
     47   try:
     48     sys.path.insert(0, os.path.join(chrome_src, 'third_party', 'psyco_win32'))
     49     import psyco
     50   except:
     51     psyco = None
     52 else:
     53   psyco = None
     54 
     55 def additional_include_files(args=[]):
     56   """
     57   Returns a list of additional (.gypi) files to include, without
     58   duplicating ones that are already specified on the command line.
     59   """
     60   # Determine the include files specified on the command line.
     61   # This doesn't cover all the different option formats you can use,
     62   # but it's mainly intended to avoid duplicating flags on the automatic
     63   # makefile regeneration which only uses this format.
     64   specified_includes = set()
     65   for arg in args:
     66     if arg.startswith('-I') and len(arg) > 2:
     67       specified_includes.add(os.path.realpath(arg[2:]))
     68 
     69   result = []
     70   def AddInclude(path):
     71     if os.path.realpath(path) not in specified_includes:
     72       result.append(path)
     73 
     74   # Always include common.gypi.
     75   AddInclude(os.path.join(script_dir, 'common.gypi'))
     76 
     77   # Optionally add supplemental .gypi files if present.
     78   supplements = glob.glob(os.path.join(chrome_src, '*', 'supplement.gypi'))
     79   for supplement in supplements:
     80     AddInclude(supplement)
     81 
     82   return result
     83 
     84 if __name__ == '__main__':
     85   args = sys.argv[1:]
     86 
     87   # Use the Psyco JIT if available.
     88   if psyco:
     89     psyco.profile()
     90     print "Enabled Psyco JIT."
     91 
     92   # Fall back on hermetic python if we happen to get run under cygwin.
     93   # TODO(bradnelson): take this out once this issue is fixed:
     94   #    http://code.google.com/p/gyp/issues/detail?id=177
     95   if sys.platform == 'cygwin':
     96     python_dir = os.path.join(chrome_src, 'third_party', 'python_26')
     97     env = os.environ.copy()
     98     env['PATH'] = python_dir + os.pathsep + env.get('PATH', '')
     99     p = subprocess.Popen(
    100        [os.path.join(python_dir, 'python.exe')] + sys.argv,
    101        env=env, shell=False)
    102     p.communicate()
    103     sys.exit(p.returncode)
    104 
    105   gyp_helper.apply_chromium_gyp_env()
    106 
    107   # This could give false positives since it doesn't actually do real option
    108   # parsing.  Oh well.
    109   gyp_file_specified = False
    110   for arg in args:
    111     if arg.endswith('.gyp'):
    112       gyp_file_specified = True
    113       break
    114 
    115   # If we didn't get a file, check an env var, and then fall back to
    116   # assuming 'all.gyp' from the same directory as the script.
    117   if not gyp_file_specified:
    118     gyp_file = os.environ.get('CHROMIUM_GYP_FILE')
    119     if gyp_file:
    120       # Note that CHROMIUM_GYP_FILE values can't have backslashes as
    121       # path separators even on Windows due to the use of shlex.split().
    122       args.extend(shlex.split(gyp_file))
    123     else:
    124       args.append(os.path.join(script_dir, 'all.gyp'))
    125 
    126   args.extend(['-I' + i for i in additional_include_files(args)])
    127 
    128   # There shouldn't be a circular dependency relationship between .gyp files,
    129   # but in Chromium's .gyp files, on non-Mac platforms, circular relationships
    130   # currently exist.  The check for circular dependencies is currently
    131   # bypassed on other platforms, but is left enabled on the Mac, where a
    132   # violation of the rule causes Xcode to misbehave badly.
    133   # TODO(mark): Find and kill remaining circular dependencies, and remove this
    134   # option.  http://crbug.com/35878.
    135   # TODO(tc): Fix circular dependencies in ChromiumOS then add linux2 to the
    136   # list.
    137   if sys.platform not in ('darwin',):
    138     args.append('--no-circular-check')
    139 
    140   # Default to ninja on linux, but only if no generator has explicitly been set.
    141   # . -f / --format has precedence over the env var, no need to check for it
    142   # . set the env var only if it hasn't been set yet
    143   # . chromium.gyp_env has been applied to os.environ at this point already
    144   if sys.platform.startswith('linux') and not os.environ.get('GYP_GENERATORS'):
    145     os.environ['GYP_GENERATORS'] = 'ninja'
    146 
    147   # If CHROMIUM_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check
    148   # to enfore syntax checking.
    149   syntax_check = os.environ.get('CHROMIUM_GYP_SYNTAX_CHECK')
    150   if syntax_check and int(syntax_check):
    151     args.append('--check')
    152 
    153   print 'Updating projects from gyp files...'
    154   sys.stdout.flush()
    155 
    156   # Off we go...
    157   sys.exit(gyp.main(args))
    158