Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / build / gyp_chromium
index d05204b..26028dc 100755 (executable)
 import glob
 import gyp_helper
 import os
-import pipes
+import re
 import shlex
 import subprocess
 import string
 import sys
+import vs_toolchain
 
 script_dir = os.path.dirname(os.path.realpath(__file__))
 chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir))
@@ -38,8 +39,6 @@ sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'liblouis'))
 sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit',
     'Source', 'build', 'scripts'))
 
-import find_depot_tools
-
 # On Windows, Psyco shortens warm runs of build/gyp_chromium by about
 # 20 seconds on a z600 machine with 12 GB of RAM, from 90 down to 70
 # seconds.  Conversely, memory usage of build/gyp_chromium with Psyco
@@ -66,39 +65,45 @@ def GetSupplementalFiles():
   return glob.glob(os.path.join(chrome_src, '*', 'supplement.gypi'))
 
 
-def FormatKeyForGN(key):
-  """Returns the given GYP key reformatted for GN.
-
-  GYP dictionary keys can be almost anything, but in GN they are identifiers
-  and must follow the same rules. This reformats such keys to be valid GN
-  identifiers."""
-  return ''.join([c if c in string.ascii_letters else '_' for c in key])
-
-
-def EscapeStringForGN(s):
-  """Converts a string to a GN string literal."""
-  # Escape $ characters which have special meaning to GN.
-  return '"' + s.replace('$', '\\$').replace('"', '\\"') + '"'
-
-
 def ProcessGypDefinesItems(items):
   """Converts a list of strings to a list of key-value pairs."""
   result = []
   for item in items:
     tokens = item.split('=', 1)
     # Some GYP variables have hyphens, which we don't support.
-    key = FormatKeyForGN(tokens[0])
     if len(tokens) == 2:
-      result += [(key, tokens[1])]
+      result += [(tokens[0], tokens[1])]
     else:
       # No value supplied, treat it as a boolean and set it. Note that we
       # use the string '1' here so we have a consistent definition whether
       # you do 'foo=1' or 'foo'.
-      result += [(key, '1')]
+      result += [(tokens[0], '1')]
   return result
 
-def GetGypVarsForGN(supplemental_files):
-  """Returns a dictionary of all GYP vars that we will be passing to GN."""
+
+def GetGypVars(supplemental_files):
+  """Returns a dictionary of all GYP vars."""
+  # Find the .gyp directory in the user's home directory.
+  home_dot_gyp = os.environ.get('GYP_CONFIG_DIR', None)
+  if home_dot_gyp:
+    home_dot_gyp = os.path.expanduser(home_dot_gyp)
+  if not home_dot_gyp:
+    home_vars = ['HOME']
+    if sys.platform in ('cygwin', 'win32'):
+      home_vars.append('USERPROFILE')
+    for home_var in home_vars:
+      home = os.getenv(home_var)
+      if home != None:
+        home_dot_gyp = os.path.join(home, '.gyp')
+        if not os.path.exists(home_dot_gyp):
+          home_dot_gyp = None
+        else:
+          break
+
+  if home_dot_gyp:
+    include_gypi = os.path.join(home_dot_gyp, "include.gypi")
+    if os.path.exists(include_gypi):
+      supplemental_files += [include_gypi]
 
   # GYP defines from the supplemental.gypi files.
   supp_items = []
@@ -111,7 +116,7 @@ def GetGypVarsForGN(supplemental_files):
         raise
       variables = file_data.get('variables', [])
       for v in variables:
-        supp_items += [(FormatKeyForGN(v), str(variables[v]))]
+        supp_items += [(v, str(variables[v]))]
 
   # GYP defines from the environment.
   env_items = ProcessGypDefinesItems(
@@ -128,7 +133,9 @@ def GetGypVarsForGN(supplemental_files):
         cmdline_input_items += [sys.argv[i][2:]]
   cmdline_items = ProcessGypDefinesItems(cmdline_input_items)
 
-  return dict(supp_items + env_items + cmdline_items)
+  vars_dict = dict(supp_items + env_items + cmdline_items)
+  return vars_dict
+
 
 def GetOutputDirectory():
   """Returns the output directory that GYP will use."""
@@ -148,111 +155,6 @@ def GetOutputDirectory():
 
   return "out"
 
-def GetArgsStringForGN(supplemental_files):
-  """Returns the args to pass to GN.
-  Based on a subset of the GYP variables that have been rewritten a bit."""
-
-  # Find the .gyp directory in the user's home directory.
-  home_dot_gyp = os.environ.get('GYP_CONFIG_DIR', None)
-  if home_dot_gyp:
-    home_dot_gyp = os.path.expanduser(home_dot_gyp)
-  if not home_dot_gyp:
-    home_vars = ['HOME']
-    if sys.platform in ('cygwin', 'win32'):
-      home_vars.append('USERPROFILE')
-    for home_var in home_vars:
-      home = os.getenv(home_var)
-      if home != None:
-        home_dot_gyp = os.path.join(home, '.gyp')
-        if not os.path.exists(home_dot_gyp):
-          home_dot_gyp = None
-        else:
-          break
-
-  if home_dot_gyp:
-    include_gypi = os.path.join(home_dot_gyp, "include.gypi")
-    if os.path.exists(include_gypi):
-      supplemental_files += [include_gypi]
-
-  vars_dict = GetGypVarsForGN(supplemental_files)
-  gn_args = ''
-
-  # Note: These are the additional flags passed to various builds by builders
-  # on the main waterfall. We'll probably need to add these at some point:
-  #   mac_strip_release=1         http://crbug.com/330301
-  #   linux_dump_symbols=0        http://crbug.com/330300
-  #   host_os=linux  Probably can skip, GN knows the host OS.
-  #   order_text_section=<path>   http://crbug.com/330299
-  #   chromium_win_pch=0          http://crbug.com/297678
-  #   chromium_ios_signing=0      http://crbug.com/330302
-  #   linux_use_tcmalloc=0        http://crbug.com/330303
-  #   release_extra_flags=...     http://crbug.com/330305
-
-  # These tuples of (key, value, gn_arg_string) use the gn_arg_string for
-  # gn when the key is set to the given value in the GYP arguments.
-  remap_cases = [
-      ('android_webview_build', '1', 'is_android_webview_build=true'),
-      ('branding', 'Chrome', 'is_chrome_branded=true'),
-      ('build_for_tool', 'drmemory', 'disable_iterator_debugging=true'),
-      ('build_for_tool', 'tsan', 'disable_iterator_debugging=true'),
-      ('buildtype', 'Official', 'is_official_build=true'),
-      ('component', 'shared_library', 'is_component_build=true'),
-      ('clang', '1', 'is_clang=true'),
-      ('clang_use_chrome_plugins', '0', 'clang_use_chrome_plugins=false'),
-      ('disable_glibcxx_debug', '1', 'disable_iterator_debugging=true'),
-      ('target_arch', 'ia32', 'cpu_arch="x86"'),
-      ('target_arch', 'x64', 'cpu_arch="x64" force_win64=true'),
-      ('target_arch', 'arm', 'cpu_arch="arm"'),
-      ('target_arch', 'mipsel', 'cpu_arch="mipsel"'),
-      ('fastbuild', '0', 'symbol_level=2'),
-      ('fastbuild', '1', 'symbol_level=1'),
-      ('fastbuild', '2', 'symbol_level=0'),
-      ('OS', 'ios', 'os="ios"'),
-      ('OS', 'android', 'os="android"'),
-      ('chromeos', '1', 'os="chromeos"'),
-      ('use_aura', '1', 'use_aura=true'),
-      ('use_goma', '1', 'use_goma=true'),
-      ('asan', '1', 'is_asan=true'),
-      ('lsan', '1', 'is_lsan=true'),
-      ('msan', '1', 'is_msan=true'),
-      ('tsan', '1', 'is_tsan=true'),
-  ]
-  for i in remap_cases:
-    if i[0] in vars_dict and vars_dict[i[0]] == i[1]:
-      gn_args += ' ' + i[2]
-
-  # These string arguments get passed directly as GN strings.
-  for v in ['android_src', 'windows_sdk_path', 'arm_float_abi']:
-    if v in vars_dict:
-      gn_args += ' ' + v + '=' + EscapeStringForGN(vars_dict[v])
-
-  # gomadir is renamed goma_dir in the GN build.
-  if 'gomadir' in vars_dict:
-    gn_args += ' goma_dir=%s' % EscapeStringForGN(vars_dict['gomadir'])
-
-  # These arguments get passed directly as integers (avoiding the quoting and
-  # escaping of the string ones above).
-  for v in ['arm_version']:
-    if v in vars_dict:
-      gn_args += ' %s=%s' % (v, vars_dict[v])
-
-  # Some other flags come from GYP environment variables.
-  gyp_msvs_version = os.environ.get('GYP_MSVS_VERSION', '')
-  if gyp_msvs_version:
-    gn_args += ' visual_studio_version=' + EscapeStringForGN(gyp_msvs_version)
-  gyp_msvs_override_path = os.environ.get('GYP_MSVS_OVERRIDE_PATH', '')
-  if gyp_msvs_override_path:
-    gn_args += ' visual_studio_path=' + \
-        EscapeStringForGN(gyp_msvs_override_path)
-
-  # Set the GYP flag so BUILD files know they're being invoked in GYP mode.
-  gn_args += ' is_gyp=true'
-
-  gyp_outdir = GetOutputDirectory()
-  gn_args += ' gyp_output_dir=\"%s\"' % gyp_outdir
-
-  return gn_args.strip()
-
 
 def additional_include_files(supplemental_files, args=[]):
   """
@@ -284,38 +186,6 @@ def additional_include_files(supplemental_files, args=[]):
   return result
 
 
-def RunGN(supplemental_includes):
-  """Runs GN, returning True if it succeeded, printing an error and returning
-  false if not."""
-
-  # The binaries in platform-specific subdirectories in src/tools/gn/bin.
-  gnpath = SRC_DIR + '/tools/gn/bin/'
-  if sys.platform in ('cygwin', 'win32'):
-    gnpath += 'win/gn.exe'
-  elif sys.platform.startswith('linux'):
-    # On Linux we have 32-bit and 64-bit versions.
-    if subprocess.check_output(["getconf", "LONG_BIT"]).find("64") >= 0:
-      gnpath += 'linux/gn'
-    else:
-      gnpath += 'linux/gn32'
-  elif sys.platform == 'darwin':
-    gnpath += 'mac/gn'
-  else:
-    print 'Unknown platform for GN: ', sys.platform
-    return False
-
-  print 'Generating gyp files from GN...'
-
-  # Need to pass both the source root (the bots don't run this command from
-  # within the source tree) as well as set the is_gyp value so the BUILD files
-  # to know they're being run under GYP.
-  args = [gnpath, 'gyp', '-q',
-          '--root=' + chrome_src,
-          '--args=' + GetArgsStringForGN(supplemental_includes),
-          '--output=//' + GetOutputDirectory() + '/gn_build/']
-  return subprocess.call(args) == 0
-
-
 if __name__ == '__main__':
   args = sys.argv[1:]
 
@@ -332,6 +202,7 @@ if __name__ == '__main__':
   # TODO(bradnelson): take this out once this issue is fixed:
   #    http://code.google.com/p/gyp/issues/detail?id=177
   if sys.platform == 'cygwin':
+    import find_depot_tools
     depot_tools_path = find_depot_tools.add_depot_tools_to_path()
     python_dir = sorted(glob.glob(os.path.join(depot_tools_path,
                                                'python2*_bin')))[-1]
@@ -376,44 +247,26 @@ if __name__ == '__main__':
   if sys.platform not in ('darwin',):
     args.append('--no-circular-check')
 
+  # We explicitly don't support the make gyp generator (crbug.com/348686). Be
+  # nice and fail here, rather than choking in gyp.
+  if re.search(r'(^|,|\s)make($|,|\s)', os.environ.get('GYP_GENERATORS', '')):
+    print 'Error: make gyp generator not supported (check GYP_GENERATORS).'
+    sys.exit(1)
+
   # Default to ninja on linux and windows, but only if no generator has
   # explicitly been set.
   # Also default to ninja on mac, but only when not building chrome/ios.
   # . -f / --format has precedence over the env var, no need to check for it
   # . set the env var only if it hasn't been set yet
   # . chromium.gyp_env has been applied to os.environ at this point already
-  if sys.platform.startswith('linux') and not os.environ.get('GYP_GENERATORS'):
-    os.environ['GYP_GENERATORS'] = 'ninja'
-  if sys.platform.startswith('win') and not os.environ.get('GYP_GENERATORS'):
+  if sys.platform.startswith(('linux', 'win', 'freebsd')) and \
+      not os.environ.get('GYP_GENERATORS'):
     os.environ['GYP_GENERATORS'] = 'ninja'
   elif sys.platform == 'darwin' and not os.environ.get('GYP_GENERATORS') and \
       not 'OS=ios' in os.environ.get('GYP_DEFINES', []):
     os.environ['GYP_GENERATORS'] = 'ninja'
 
-  # If using ninja on windows, and the automatic toolchain has been installed
-  # by depot_tools, then use it.
-  if (sys.platform in ('win32', 'cygwin') and
-      os.environ.get('GYP_GENERATORS') == 'ninja'):
-    depot_tools_path = find_depot_tools.add_depot_tools_to_path()
-    toolchain = os.path.normpath(os.path.join(
-        depot_tools_path, 'win_toolchain', 'vs2013_files'))
-    if os.path.isdir(toolchain):
-      os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
-      os.environ['GYP_MSVS_VERSION'] = '2013'
-      # We need to make sure windows_sdk_path is set to the automated
-      # toolchain values in GYP_DEFINES, but don't want to override any other
-      # values there.
-      gyp_defines_dict = gyp.NameValueListToDict(gyp.ShlexEnv('GYP_DEFINES'))
-      win8sdk = os.path.join(toolchain, 'win8sdk')
-      gyp_defines_dict['windows_sdk_path'] = win8sdk
-      os.environ['WINDOWSSDKDIR'] = win8sdk
-      os.environ['GYP_DEFINES'] = ' '.join('%s=%s' % (k, pipes.quote(str(v)))
-          for k, v in gyp_defines_dict.iteritems())
-      # Include the VS runtime in the PATH in case it's not machine-installed.
-      runtime_path = ';'.join(os.path.normpath(os.path.join(toolchain, s))
-                              for s in ('sys64', 'sys32'))
-      os.environ['PATH'] = runtime_path + ';' + os.environ['PATH']
-      print('Using automatic toolchain in %s.' % toolchain)
+  vs2013_runtime_dll_dirs = vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
 
   # If CHROMIUM_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check
   # to enfore syntax checking.
@@ -422,8 +275,29 @@ if __name__ == '__main__':
     args.append('--check')
 
   supplemental_includes = GetSupplementalFiles()
-  if not RunGN(supplemental_includes):
-    sys.exit(1)
+  gyp_vars_dict = GetGypVars(supplemental_includes)
+
+  # TODO(dmikurube): Remove these checks and messages after a while.
+  if ('linux_use_tcmalloc' in gyp_vars_dict or
+      'android_use_tcmalloc' in gyp_vars_dict):
+    print '*****************************************************************'
+    print '"linux_use_tcmalloc" and "android_use_tcmalloc" are deprecated!'
+    print '-----------------------------------------------------------------'
+    print 'You specify "linux_use_tcmalloc" or "android_use_tcmalloc" in'
+    print 'your GYP_DEFINES. Please switch them into "use_allocator" now.'
+    print 'See http://crbug.com/345554 for the details.'
+    print '*****************************************************************'
+
+  # Automatically turn on crosscompile support for platforms that need it.
+  # (The Chrome OS build sets CC_host / CC_target which implicitly enables
+  # this mode.)
+  if all(('ninja' in os.environ.get('GYP_GENERATORS', ''),
+          gyp_vars_dict.get('OS') in ['android', 'ios'],
+          'GYP_CROSSCOMPILE' not in os.environ)):
+    os.environ['GYP_CROSSCOMPILE'] = '1'
+  if gyp_vars_dict.get('OS') == 'android':
+    args.append('--check')
+
   args.extend(
       ['-I' + i for i in additional_include_files(supplemental_includes, args)])
 
@@ -433,4 +307,19 @@ if __name__ == '__main__':
   sys.stdout.flush()
 
   # Off we go...
-  sys.exit(gyp.main(args))
+  gyp_rc = gyp.main(args)
+
+  # Check for landmines (reasons to clobber the build). This must be run here,
+  # rather than a separate runhooks step so that any environment modifications
+  # from above are picked up.
+  print 'Running build/landmines.py...'
+  subprocess.check_call(
+      [sys.executable, os.path.join(script_dir, 'landmines.py')])
+
+  if vs2013_runtime_dll_dirs:
+    x64_runtime, x86_runtime = vs2013_runtime_dll_dirs
+    vs_toolchain.CopyVsRuntimeDlls(
+        os.path.join(chrome_src, GetOutputDirectory()),
+        (x86_runtime, x64_runtime))
+
+  sys.exit(gyp_rc)