16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved.
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)# found in the LICENSE file.
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)"""Classes and functions for building Chrome.
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)This includes functions for running commands to build, as well as
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)specific rules about which targets to build.
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)"""
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import os
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import subprocess
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import sys
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)import bisect_utils
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ORIGINAL_ENV = {}
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class Builder(object):
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """Subclasses of the Builder class are used by the bisect script to build
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  relevant targets.
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def __init__(self, opts):
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Performs setup for building with target build system.
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Args:
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      opts: Options parsed from command line.
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Raises:
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      RuntimeError: Some condition necessary for building was not met.
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if bisect_utils.IsWindowsHost():
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if not opts.build_preference:
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        opts.build_preference = 'msvs'
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if opts.build_preference == 'msvs':
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        if not os.getenv('VS100COMNTOOLS'):
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          raise RuntimeError(
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              'Path to visual studio could not be determined.')
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      else:
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        # Need to re-escape goma dir, see crbug.com/394990.
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if opts.goma_dir:
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          opts.goma_dir = opts.goma_dir.encode('string_escape')
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        SetBuildSystemDefault(opts.build_preference, opts.use_goma,
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                              opts.goma_dir)
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    else:
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if not opts.build_preference:
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        if 'ninja' in os.getenv('GYP_GENERATORS', default=''):
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          opts.build_preference = 'ninja'
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        else:
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          opts.build_preference = 'make'
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      SetBuildSystemDefault(opts.build_preference, opts.use_goma, opts.goma_dir)
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if not SetupPlatformBuildEnvironment(opts):
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      raise RuntimeError('Failed to set platform environment.')
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  @staticmethod
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def FromOpts(opts):
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Constructs and returns a Builder object.
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Args:
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      opts: Options parsed from the command-line.
656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """
666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    builder = None
676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if opts.target_platform == 'cros':
686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      builder = CrosBuilder(opts)
696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    elif opts.target_platform == 'android':
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      builder = AndroidBuilder(opts)
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    elif opts.target_platform == 'android-chrome':
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      builder = AndroidChromeBuilder(opts)
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    else:
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      builder = DesktopBuilder(opts)
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return builder
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def Build(self, depot, opts):
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Runs a command to build Chrome."""
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    raise NotImplementedError()
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)def GetBuildOutputDirectory(opts, src_dir=None):
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """Returns the path to the build directory, relative to the checkout root.
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Assumes that the current working directory is the checkout root.
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Args:
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    opts: Command-line options.
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    src_dir: Path to chromium/src directory.
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Returns:
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    A path to the directory to use as build output directory.
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Raises:
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    NotImplementedError: The platform according to sys.platform is unexpected.
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  src_dir = src_dir or 'src'
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if opts.build_preference == 'ninja' or bisect_utils.IsLinuxHost():
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return os.path.join(src_dir, 'out')
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if bisect_utils.IsMacHost():
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return os.path.join(src_dir, 'xcodebuild')
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if bisect_utils.IsWindowsHost():
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return os.path.join(src_dir, 'build')
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  raise NotImplementedError('Unexpected platform %s' % sys.platform)
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class DesktopBuilder(Builder):
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """DesktopBuilder is used to build Chromium on Linux, Mac, or Windows."""
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def __init__(self, opts):
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    super(DesktopBuilder, self).__init__(opts)
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def Build(self, depot, opts):
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Builds chromium_builder_perf target using options passed into the script.
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Args:
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      depot: Name of current depot being bisected.
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      opts: The options parsed from the command line.
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Returns:
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      True if build was successful.
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    targets = ['chromium_builder_perf']
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    threads = None
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if opts.use_goma:
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      threads = 64
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    build_success = False
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if opts.build_preference == 'make':
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      build_success = BuildWithMake(threads, targets, opts.target_build_type)
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    elif opts.build_preference == 'ninja':
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      build_success = BuildWithNinja(threads, targets, opts.target_build_type)
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    elif opts.build_preference == 'msvs':
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      assert bisect_utils.IsWindowsHost(), 'msvs is only supported on Windows.'
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      build_success = BuildWithVisualStudio(targets, opts.target_build_type)
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    else:
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      assert False, 'No build system defined.'
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return build_success
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class AndroidBuilder(Builder):
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """AndroidBuilder is used to build on android."""
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def __init__(self, opts):
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    super(AndroidBuilder, self).__init__(opts)
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  # TODO(qyearsley): Make this a class method and verify that it works with
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  # a unit test.
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  # pylint: disable=R0201
1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def _GetTargets(self):
1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Returns a list of build targets."""
1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return ['chrome_shell_apk', 'cc_perftests_apk', 'android_tools']
1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def Build(self, depot, opts):
1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Builds the android content shell and other necessary tools.
1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Args:
1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        depot: Current depot being bisected.
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        opts: The options parsed from the command line.
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Returns:
1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        True if build was successful.
1646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """
1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    threads = None
1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if opts.use_goma:
1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      threads = 64
1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    build_success = False
1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if opts.build_preference == 'ninja':
1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      build_success = BuildWithNinja(
1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          threads, self._GetTargets(), opts.target_build_type)
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    else:
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      assert False, 'No build system defined.'
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return build_success
1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class AndroidChromeBuilder(AndroidBuilder):
1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """AndroidChromeBuilder is used to build "android-chrome".
1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  This is slightly different from AndroidBuilder.
1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """
1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def __init__(self, opts):
1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    super(AndroidChromeBuilder, self).__init__(opts)
1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  # TODO(qyearsley): Make this a class method and verify that it works with
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  # a unit test.
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  # pylint: disable=R0201
1916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def _GetTargets(self):
1926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Returns a list of build targets."""
1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return AndroidBuilder._GetTargets(self) + ['chrome_apk']
1946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class CrosBuilder(Builder):
1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """CrosBuilder is used to build and image ChromeOS/Chromium.
1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  WARNING(qyearsley, 2014-08-15): This hasn't been tested recently.
2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def __init__(self, opts):
2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    super(CrosBuilder, self).__init__(opts)
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  @staticmethod
2066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def ImageToTarget(opts):
2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Installs latest image to target specified by opts.cros_remote_ip.
2086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Args:
2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      opts: Program options containing cros_board and cros_remote_ip.
2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Returns:
2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      True if successful.
2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """
2156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    try:
2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      # Keys will most likely be set to 0640 after wiping the chroot.
2176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      os.chmod(bisect_utils.CROS_SCRIPT_KEY_PATH, 0600)
2186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      os.chmod(bisect_utils.CROS_TEST_KEY_PATH, 0600)
2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      cmd = [bisect_utils.CROS_SDK_PATH, '--', './bin/cros_image_to_target.py',
2206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             '--remote=%s' % opts.cros_remote_ip,
2216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)             '--board=%s' % opts.cros_board, '--test', '--verbose']
2226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return_code = bisect_utils.RunProcess(cmd)
2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return not return_code
2256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    except OSError:
2266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      return False
2276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  @staticmethod
2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def BuildPackages(opts, depot):
2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Builds packages for cros.
2316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Args:
2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      opts: Program options containing cros_board.
2346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      depot: The depot being bisected.
2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Returns:
2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      True if successful.
2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """
2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cmd = [bisect_utils.CROS_SDK_PATH]
2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if depot != 'cros':
2426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      path_to_chrome = os.path.join(os.getcwd(), '..')
2436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      cmd += ['--chrome_root=%s' % path_to_chrome]
2446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cmd += ['--']
2466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if depot != 'cros':
2486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      cmd += ['CHROME_ORIGIN=LOCAL_SOURCE']
2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cmd += ['BUILDTYPE=%s' % opts.target_build_type, './build_packages',
2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        '--board=%s' % opts.cros_board]
2526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return_code = bisect_utils.RunProcess(cmd)
2536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return not return_code
2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  @staticmethod
2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def BuildImage(opts, depot):
2586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Builds test image for cros.
2596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Args:
2616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      opts: Program options containing cros_board.
2626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      depot: The depot being bisected.
2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Returns:
2656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      True if successful.
2666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """
2676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cmd = [bisect_utils.CROS_SDK_PATH]
2686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if depot != 'cros':
2706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      path_to_chrome = os.path.join(os.getcwd(), '..')
2716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      cmd += ['--chrome_root=%s' % path_to_chrome]
2726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cmd += ['--']
2746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if depot != 'cros':
2766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      cmd += ['CHROME_ORIGIN=LOCAL_SOURCE']
2776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cmd += ['BUILDTYPE=%s' % opts.target_build_type, '--', './build_image',
2796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        '--board=%s' % opts.cros_board, 'test']
2806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return_code = bisect_utils.RunProcess(cmd)
2826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return not return_code
2846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def Build(self, depot, opts):
2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """Builds targets using options passed into the script.
2876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Args:
2896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        depot: Current depot being bisected.
2906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        opts: The options parsed from the command line.
2916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    Returns:
2936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        True if build was successful.
2946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    """
2956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if self.BuildPackages(opts, depot):
2966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if self.BuildImage(opts, depot):
2976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return self.ImageToTarget(opts)
2986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return False
2996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)def SetBuildSystemDefault(build_system, use_goma, goma_dir):
3026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """Sets up any environment variables needed to build with the specified build
3036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  system.
3046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Args:
3066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    build_system: A string specifying build system. Currently only 'ninja' or
3076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        'make' are supported.
3086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """
3096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if build_system == 'ninja':
3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    gyp_var = os.getenv('GYP_GENERATORS', default='')
3116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if not gyp_var or not 'ninja' in gyp_var:
3136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if gyp_var:
3146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        os.environ['GYP_GENERATORS'] = gyp_var + ',ninja'
3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      else:
3166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        os.environ['GYP_GENERATORS'] = 'ninja'
3176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if bisect_utils.IsWindowsHost():
3196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        os.environ['GYP_DEFINES'] = 'component=shared_library '\
3206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            'incremental_chrome_dll=1 disable_nacl=1 fastbuild=1 '\
3216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            'chromium_win_pch=0'
3226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  elif build_system == 'make':
3246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    os.environ['GYP_GENERATORS'] = 'make'
3256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else:
3266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    raise RuntimeError('%s build not supported.' % build_system)
3276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if use_goma:
3296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    os.environ['GYP_DEFINES'] = '%s %s' % (os.getenv('GYP_DEFINES', default=''),
3306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                           'use_goma=1')
3316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if goma_dir:
3326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      os.environ['GYP_DEFINES'] += ' gomadir=%s' % goma_dir
3336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)def SetupPlatformBuildEnvironment(opts):
3366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """Performs any platform-specific setup.
3376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Args:
3396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    opts: The options parsed from the command line through parse_args().
3406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Returns:
3426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    True if successful.
3436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """
3446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if 'android' in opts.target_platform:
3456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CopyAndSaveOriginalEnvironmentVars()
3466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return SetupAndroidBuildEnvironment(opts)
3476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  elif opts.target_platform == 'cros':
3486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return bisect_utils.SetupCrosRepo()
3496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return True
3506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)def BuildWithMake(threads, targets, build_type='Release'):
3536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """Runs a make command with the given targets.
3546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Args:
3566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    threads: The number of threads to use. None means unspecified/unlimited.
3576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    targets: List of make targets.
3586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    build_type: Release or Debug.
3596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Returns:
3616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    True if the command had a 0 exit code, False otherwise.
3626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """
3636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  cmd = ['make', 'BUILDTYPE=%s' % build_type]
3646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if threads:
3656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cmd.append('-j%d' % threads)
3666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  cmd += targets
3676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return_code = bisect_utils.RunProcess(cmd)
3686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return not return_code
3696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)def BuildWithNinja(threads, targets, build_type='Release'):
3726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """Runs a ninja command with the given targets."""
3736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  cmd = ['ninja', '-C', os.path.join('out', build_type)]
3746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if threads:
3756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cmd.append('-j%d' % threads)
3766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  cmd += targets
3776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return_code = bisect_utils.RunProcess(cmd)
3786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return not return_code
3796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)def BuildWithVisualStudio(targets, build_type='Release'):
3826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """Runs a command to build the given targets with Visual Studio."""
3836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  path_to_devenv = os.path.abspath(
3846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      os.path.join(os.environ['VS100COMNTOOLS'], '..', 'IDE', 'devenv.com'))
3856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  path_to_sln = os.path.join(os.getcwd(), 'chrome', 'chrome.sln')
3866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  cmd = [path_to_devenv, '/build', build_type, path_to_sln]
3876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for t in targets:
3886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    cmd.extend(['/Project', t])
3896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return_code = bisect_utils.RunProcess(cmd)
3906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return not return_code
3916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)def CopyAndSaveOriginalEnvironmentVars():
3946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """Makes a copy of the current environment variables.
3956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Before making a copy of the environment variables and setting a global
3976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  variable, this function unsets a certain set of environment variables.
3986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """
3996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  # TODO: Waiting on crbug.com/255689, will remove this after.
4006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  vars_to_remove = [
4016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      'CHROME_SRC',
4026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      'CHROMIUM_GYP_FILE',
4036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      'GYP_CROSSCOMPILE',
4046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      'GYP_DEFINES',
4056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      'GYP_GENERATORS',
4066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      'GYP_GENERATOR_FLAGS',
4076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      'OBJCOPY',
4086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ]
4096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for key in os.environ:
4106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if 'ANDROID' in key:
4116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      vars_to_remove.append(key)
4126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for key in vars_to_remove:
4136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if os.environ.has_key(key):
4146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      del os.environ[key]
4156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  global ORIGINAL_ENV
4176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ORIGINAL_ENV = os.environ.copy()
4186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)def SetupAndroidBuildEnvironment(opts, path_to_src=None):
4216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """Sets up the android build environment.
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Args:
4246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    opts: The options parsed from the command line through parse_args().
4256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    path_to_src: Path to the src checkout.
4266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Returns:
4286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    True if successful.
4296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  """
4306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  # Revert the environment variables back to default before setting them up
4316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  # with envsetup.sh.
4326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  env_vars = os.environ.copy()
4336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for k, _ in env_vars.iteritems():
4346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    del os.environ[k]
4356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for k, v in ORIGINAL_ENV.iteritems():
4366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    os.environ[k] = v
4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  envsetup_path = os.path.join('build', 'android', 'envsetup.sh')
4396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  proc = subprocess.Popen(['bash', '-c', 'source %s && env' % envsetup_path],
4406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                          stdout=subprocess.PIPE,
4416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                          stderr=subprocess.PIPE,
4426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                          cwd=path_to_src)
4436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  out, _ = proc.communicate()
4446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for line in out.splitlines():
4466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    k, _, v = line.partition('=')
4476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    os.environ[k] = v
4486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  # envsetup.sh no longer sets OS=android in GYP_DEFINES environment variable.
4506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  # (See http://crrev.com/170273005). So, we set this variable explicitly here
4516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  # in order to build Chrome on Android.
4526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if 'GYP_DEFINES' not in os.environ:
4536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    os.environ['GYP_DEFINES'] = 'OS=android'
4546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  else:
4556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    os.environ['GYP_DEFINES'] += ' OS=android'
4566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if opts.use_goma:
4586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    os.environ['GYP_DEFINES'] += ' use_goma=1'
4596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return not proc.returncode
460