Home | History | Annotate | Download | only in toolchain-utils
      1 #!/usr/bin/env python2
      2 #
      3 # Copyright 2010 Google Inc. All Rights Reserved.
      4 """Script to checkout the ChromeOS source.
      5 
      6 This script sets up the ChromeOS source in the given directory, matching a
      7 particular release of ChromeOS.
      8 """
      9 
     10 from __future__ import print_function
     11 
     12 __author__ = 'raymes (at] google.com (Raymes Khoury)'
     13 
     14 import argparse
     15 import os
     16 import sys
     17 
     18 from cros_utils import command_executer
     19 from cros_utils import logger
     20 from cros_utils import misc
     21 
     22 
     23 def Usage(parser, message):
     24   print('ERROR: %s' % message)
     25   parser.print_help()
     26   sys.exit(0)
     27 
     28 
     29 def Main(argv):
     30   """Build Chrome browser."""
     31 
     32   cmd_executer = command_executer.GetCommandExecuter()
     33 
     34   parser = argparse.ArgumentParser()
     35   parser.add_argument(
     36       '--chromeos_root',
     37       dest='chromeos_root',
     38       help='Target directory for ChromeOS installation.')
     39   parser.add_argument('--version', dest='version')
     40   parser.add_argument(
     41       '--clean',
     42       dest='clean',
     43       default=False,
     44       action='store_true',
     45       help=('Clean the /var/cache/chromeos-chrome/'
     46             'chrome-src/src/out_$board dir'))
     47   parser.add_argument(
     48       '--env', dest='env', default='', help='Use the following env')
     49   parser.add_argument(
     50       '--ebuild_version',
     51       dest='ebuild_version',
     52       help='Use this ebuild instead of the default one.')
     53   parser.add_argument(
     54       '--cflags',
     55       dest='cflags',
     56       default='',
     57       help='CFLAGS for the ChromeOS packages')
     58   parser.add_argument(
     59       '--cxxflags',
     60       dest='cxxflags',
     61       default='',
     62       help='CXXFLAGS for the ChromeOS packages')
     63   parser.add_argument(
     64       '--ldflags',
     65       dest='ldflags',
     66       default='',
     67       help='LDFLAGS for the ChromeOS packages')
     68   parser.add_argument(
     69       '--board', dest='board', help='ChromeOS target board, e.g. x86-generic')
     70   parser.add_argument(
     71       '--no_build_image',
     72       dest='no_build_image',
     73       default=False,
     74       action='store_true',
     75       help=('Skip build image after building browser.'
     76             'Defaults to False.'))
     77   parser.add_argument(
     78       '--label',
     79       dest='label',
     80       help='Optional label to apply to the ChromeOS image.')
     81   parser.add_argument(
     82       '--build_image_args',
     83       default='',
     84       dest='build_image_args',
     85       help='Optional arguments to build_image.')
     86   parser.add_argument(
     87       '--cros_workon',
     88       dest='cros_workon',
     89       help='Build using external source tree.')
     90   parser.add_argument(
     91       '--dev',
     92       dest='dev',
     93       default=False,
     94       action='store_true',
     95       help=('Build a dev (eg. writable/large) image. '
     96             'Defaults to False.'))
     97   parser.add_argument(
     98       '--debug',
     99       dest='debug',
    100       default=False,
    101       action='store_true',
    102       help=('Build chrome browser using debug mode. '
    103             'This option implies --dev. Defaults to false.'))
    104   parser.add_argument(
    105       '--verbose',
    106       dest='verbose',
    107       default=False,
    108       action='store_true',
    109       help='Build with verbose information.')
    110 
    111   options = parser.parse_args(argv)
    112 
    113   if options.chromeos_root is None:
    114     Usage(parser, '--chromeos_root must be set')
    115 
    116   if options.board is None:
    117     Usage(parser, '--board must be set')
    118 
    119   if options.version is None:
    120     logger.GetLogger().LogOutput('No Chrome version given so '
    121                                  'using the default checked in version.')
    122     chrome_version = ''
    123   else:
    124     chrome_version = 'CHROME_VERSION=%s' % options.version
    125 
    126   if options.dev and options.no_build_image:
    127     logger.GetLogger().LogOutput(
    128         "\"--dev\" is meaningless if \"--no_build_image\" is given.")
    129 
    130   if options.debug:
    131     options.dev = True
    132 
    133   options.chromeos_root = misc.CanonicalizePath(options.chromeos_root)
    134 
    135   unmask_env = 'ACCEPT_KEYWORDS=~*'
    136   if options.ebuild_version:
    137     ebuild_version = '=%s' % options.ebuild_version
    138     options.env = '%s %s' % (options.env, unmask_env)
    139   else:
    140     ebuild_version = 'chromeos-chrome'
    141 
    142   if options.cros_workon and not (
    143       os.path.isdir(options.cros_workon) and os.path.exists(
    144           os.path.join(options.cros_workon, 'src/chromeos/BUILD.gn'))):
    145     Usage(parser, '--cros_workon must be a valid chromium browser checkout.')
    146 
    147   if options.verbose:
    148     options.env = misc.MergeEnvStringWithDict(
    149         options.env, {'USE': 'chrome_internal verbose'})
    150   else:
    151     options.env = misc.MergeEnvStringWithDict(options.env,
    152                                               {'USE': 'chrome_internal'})
    153   if options.debug:
    154     options.env = misc.MergeEnvStringWithDict(options.env,
    155                                               {'BUILDTYPE': 'Debug'})
    156 
    157   if options.clean:
    158     misc.RemoveChromeBrowserObjectFiles(options.chromeos_root, options.board)
    159 
    160   chrome_origin = 'SERVER_SOURCE'
    161   if options.cros_workon:
    162     chrome_origin = 'LOCAL_SOURCE'
    163     command = 'cros_workon --board={0} start chromeos-chrome'.format(
    164         options.board)
    165     ret = cmd_executer.ChrootRunCommandWOutput(options.chromeos_root, command)
    166 
    167     # cros_workon start returns non-zero if chromeos-chrome is already a
    168     # cros_workon package.
    169     if ret[0] and ret[2].find(
    170         'WARNING : Already working on chromeos-base/chromeos-chrome') == -1:
    171       logger.GetLogger().LogFatal('cros_workon chromeos-chrome failed.')
    172 
    173     # Return value is non-zero means we do find the "Already working on..."
    174     # message, keep the information, so later on we do not revert the
    175     # cros_workon status.
    176     cros_workon_keep = (ret[0] != 0)
    177 
    178   # Emerge the browser
    179   emerge_browser_command = ('CHROME_ORIGIN={0} {1} '
    180                             'CFLAGS="$(portageq-{2} envvar CFLAGS) {3}" '
    181                             'LDFLAGS="$(portageq-{2} envvar LDFLAGS) {4}" '
    182                             'CXXFLAGS="$(portageq-{2} envvar CXXFLAGS) {5}" '
    183                             '{6} emerge-{2} --buildpkg {7}').format(
    184                                 chrome_origin, chrome_version, options.board,
    185                                 options.cflags, options.ldflags,
    186                                 options.cxxflags, options.env, ebuild_version)
    187 
    188   cros_sdk_options = ''
    189   if options.cros_workon:
    190     cros_sdk_options = '--chrome_root={0}'.format(options.cros_workon)
    191 
    192   ret = cmd_executer.ChrootRunCommand(
    193       options.chromeos_root,
    194       emerge_browser_command,
    195       cros_sdk_options=cros_sdk_options)
    196 
    197   logger.GetLogger().LogFatalIf(ret, 'build_packages failed')
    198 
    199   if options.cros_workon and not cros_workon_keep:
    200     command = 'cros_workon --board={0} stop chromeos-chrome'.format(
    201         options.board)
    202     ret = cmd_executer.ChrootRunCommand(options.chromeos_root, command)
    203     # cros_workon failed, not a fatal one, just report it.
    204     if ret:
    205       print('cros_workon stop chromeos-chrome failed.')
    206 
    207   if options.no_build_image:
    208     return ret
    209 
    210   # Finally build the image
    211   ret = cmd_executer.ChrootRunCommand(options.chromeos_root,
    212                                       '{0} {1} {2} {3}'.format(
    213                                           unmask_env, options.env,
    214                                           misc.GetBuildImageCommand(
    215                                               options.board, dev=options.dev),
    216                                           options.build_image_args))
    217 
    218   logger.GetLogger().LogFatalIf(ret, 'build_image failed')
    219 
    220   flags_file_name = 'chrome_flags.txt'
    221   flags_file_path = '{0}/src/build/images/{1}/latest/{2}'.format(
    222       options.chromeos_root, options.board, flags_file_name)
    223   flags_file = open(flags_file_path, 'wb')
    224   flags_file.write('CFLAGS={0}\n'.format(options.cflags))
    225   flags_file.write('CXXFLAGS={0}\n'.format(options.cxxflags))
    226   flags_file.write('LDFLAGS={0}\n'.format(options.ldflags))
    227   flags_file.close()
    228 
    229   if options.label:
    230     image_dir_path = '{0}/src/build/images/{1}/latest'.format(
    231         options.chromeos_root, options.board)
    232     real_image_dir_path = os.path.realpath(image_dir_path)
    233     command = 'ln -sf -T {0} {1}/{2}'.format(
    234         os.path.basename(real_image_dir_path),\
    235         os.path.dirname(real_image_dir_path),\
    236         options.label)
    237 
    238     ret = cmd_executer.RunCommand(command)
    239     logger.GetLogger().LogFatalIf(
    240         ret, 'Failed to apply symlink label %s' % options.label)
    241 
    242   return ret
    243 
    244 
    245 if __name__ == '__main__':
    246   retval = Main(sys.argv[1:])
    247   sys.exit(retval)
    248