Home | History | Annotate | Download | only in toolchain-utils
      1 #!/usr/bin/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__ = ('asharif (at] google.com (Ahmad Sharif) '
     13               'llozano (at] google.com (Luis Lozano) '
     14               'raymes (at] google.com (Raymes Khoury) '
     15               'shenhan (at] google.com (Han Shen)')
     16 
     17 import argparse
     18 import os
     19 import sys
     20 
     21 from cros_utils import command_executer
     22 from cros_utils import logger
     23 from cros_utils import misc
     24 
     25 
     26 def Usage(parser, message):
     27   print('ERROR: %s' % message)
     28   parser.print_help()
     29   sys.exit(0)
     30 
     31 
     32 def Main(argv):
     33   """Build ChromeOS."""
     34   # Common initializations
     35   cmd_executer = command_executer.GetCommandExecuter()
     36 
     37   parser = argparse.ArgumentParser()
     38   parser.add_argument('--chromeos_root',
     39                       dest='chromeos_root',
     40                       help='Target directory for ChromeOS installation.')
     41   parser.add_argument('--clobber_chroot',
     42                       dest='clobber_chroot',
     43                       action='store_true',
     44                       help='Delete the chroot and start fresh',
     45                       default=False)
     46   parser.add_argument('--clobber_board',
     47                       dest='clobber_board',
     48                       action='store_true',
     49                       help='Delete the board and start fresh',
     50                       default=False)
     51   parser.add_argument('--rebuild',
     52                       dest='rebuild',
     53                       action='store_true',
     54                       help='Rebuild all board packages except the toolchain.',
     55                       default=False)
     56   parser.add_argument('--cflags',
     57                       dest='cflags',
     58                       default='',
     59                       help='CFLAGS for the ChromeOS packages')
     60   parser.add_argument('--cxxflags',
     61                       dest='cxxflags',
     62                       default='',
     63                       help='CXXFLAGS for the ChromeOS packages')
     64   parser.add_argument('--ldflags',
     65                       dest='ldflags',
     66                       default='',
     67                       help='LDFLAGS for the ChromeOS packages')
     68   parser.add_argument('--board',
     69                       dest='board',
     70                       help='ChromeOS target board, e.g. x86-generic')
     71   parser.add_argument('--package',
     72                       dest='package',
     73                       help='The package needs to be built')
     74   parser.add_argument('--label',
     75                       dest='label',
     76                       help='Optional label symlink to point to build dir.')
     77   parser.add_argument('--dev',
     78                       dest='dev',
     79                       default=False,
     80                       action='store_true',
     81                       help=('Make the final image in dev mode (eg writable, '
     82                             'more space on image). Defaults to False.'))
     83   parser.add_argument('--debug',
     84                       dest='debug',
     85                       default=False,
     86                       action='store_true',
     87                       help=("Optional. Build chrome browser with \"-g -O0\". "
     88                             "Notice, this also turns on \'--dev\'. "
     89                             'Defaults to False.'))
     90   parser.add_argument('--env',
     91                       dest='env',
     92                       default='',
     93                       help='Env to pass to build_packages.')
     94   parser.add_argument('--vanilla',
     95                       dest='vanilla',
     96                       default=False,
     97                       action='store_true',
     98                       help='Use default ChromeOS toolchain.')
     99   parser.add_argument('--vanilla_image',
    100                       dest='vanilla_image',
    101                       default=False,
    102                       action='store_true',
    103                       help=('Use prebuild packages for building the image. '
    104                             'It also implies the --vanilla option is set.'))
    105 
    106   options = parser.parse_args(argv[1:])
    107 
    108   if options.chromeos_root is None:
    109     Usage(parser, '--chromeos_root must be set')
    110   options.chromeos_root = os.path.expanduser(options.chromeos_root)
    111   scripts_dir = os.path.join(options.chromeos_root, 'src', 'scripts')
    112   if not os.path.isdir(scripts_dir):
    113     Usage(parser, '--chromeos_root must be set up first. Use setup_chromeos.py')
    114 
    115   if options.board is None:
    116     Usage(parser, '--board must be set')
    117 
    118   if options.debug:
    119     options.dev = True
    120 
    121   build_packages_env = options.env
    122   if build_packages_env.find('EXTRA_BOARD_FLAGS=') != -1:
    123     logger.GetLogger().LogFatal(
    124         ('Passing "EXTRA_BOARD_FLAGS" in "--env" is not supported. '
    125          'This flags is used internally by this script. '
    126          'Contact the author for more detail.'))
    127 
    128   if options.rebuild == True:
    129     build_packages_env += ' EXTRA_BOARD_FLAGS=-e'
    130     # EXTRA_BOARD_FLAGS=-e should clean up the object files for the chrome
    131     # browser but it doesn't. So do it here.
    132     misc.RemoveChromeBrowserObjectFiles(options.chromeos_root, options.board)
    133 
    134   # Build with afdo_use by default.
    135   # To change the default use --env="USE=-afdo_use".
    136   build_packages_env = misc.MergeEnvStringWithDict(
    137       build_packages_env, {'USE': 'chrome_internal afdo_use'})
    138 
    139   build_packages_command = misc.GetBuildPackagesCommand(
    140       board=options.board,
    141       usepkg=options.vanilla_image,
    142       debug=options.debug)
    143 
    144   if options.package:
    145     build_packages_command += ' {0}'.format(options.package)
    146 
    147   build_image_command = misc.GetBuildImageCommand(options.board, options.dev)
    148 
    149   if options.vanilla or options.vanilla_image:
    150     command = misc.GetSetupBoardCommand(options.board,
    151                                         usepkg=options.vanilla_image,
    152                                         force=options.clobber_board)
    153     command += '; ' + build_packages_env + ' ' + build_packages_command
    154     command += '&& ' + build_packages_env + ' ' + build_image_command
    155     ret = cmd_executer.ChrootRunCommand(options.chromeos_root, command)
    156     return ret
    157 
    158   # Setup board
    159   if not os.path.isdir(options.chromeos_root + '/chroot/build/' +
    160                        options.board) or options.clobber_board:
    161     # Run build_tc.py from binary package
    162     ret = cmd_executer.ChrootRunCommand(options.chromeos_root,
    163                                         misc.GetSetupBoardCommand(
    164                                             options.board,
    165                                             force=options.clobber_board))
    166     logger.GetLogger().LogFatalIf(ret, 'setup_board failed')
    167   else:
    168     logger.GetLogger().LogOutput('Did not setup_board '
    169                                  'because it already exists')
    170 
    171   if options.debug:
    172     # Perform 2-step build_packages to build a debug chrome browser.
    173 
    174     # Firstly, build everything that chromeos-chrome depends on normally.
    175     if options.rebuild == True:
    176       # Give warning about "--rebuild" and "--debug". Under this combination,
    177       # only dependencies of "chromeos-chrome" get rebuilt.
    178       logger.GetLogger().LogWarning(
    179           "\"--rebuild\" does not correctly re-build every package when "
    180           "\"--debug\" is enabled. ")
    181 
    182       # Replace EXTRA_BOARD_FLAGS=-e with "-e --onlydeps"
    183       build_packages_env = build_packages_env.replace(
    184           'EXTRA_BOARD_FLAGS=-e', 'EXTRA_BOARD_FLAGS=\"-e --onlydeps\"')
    185     else:
    186       build_packages_env += ' EXTRA_BOARD_FLAGS=--onlydeps'
    187 
    188     ret = cmd_executer.ChrootRunCommand(
    189         options.chromeos_root, "CFLAGS=\"$(portageq-%s envvar CFLAGS) %s\" "
    190         "CXXFLAGS=\"$(portageq-%s envvar CXXFLAGS) %s\" "
    191         "LDFLAGS=\"$(portageq-%s envvar LDFLAGS) %s\" "
    192         'CHROME_ORIGIN=SERVER_SOURCE '
    193         '%s '
    194         '%s --skip_chroot_upgrade'
    195         'chromeos-chrome' % (options.board, options.cflags, options.board,
    196                              options.cxxflags, options.board, options.ldflags,
    197                              build_packages_env, build_packages_command))
    198 
    199     logger.GetLogger().LogFatalIf(\
    200       ret, 'build_packages failed while trying to build chromeos-chrome deps.')
    201 
    202     # Secondly, build chromeos-chrome using debug mode.
    203     # Replace '--onlydeps' with '--nodeps'.
    204     if options.rebuild == True:
    205       build_packages_env = build_packages_env.replace(
    206           'EXTRA_BOARD_FLAGS=\"-e --onlydeps\"', 'EXTRA_BOARD_FLAGS=--nodeps')
    207     else:
    208       build_packages_env = build_packages_env.replace(
    209           'EXTRA_BOARD_FLAGS=--onlydeps', 'EXTRA_BOARD_FLAGS=--nodeps')
    210     ret = cmd_executer.ChrootRunCommand(
    211         options.chromeos_root, "CFLAGS=\"$(portageq-%s envvar CFLAGS) %s\" "
    212         "CXXFLAGS=\"$(portageq-%s envvar CXXFLAGS) %s\" "
    213         "LDFLAGS=\"$(portageq-%s envvar LDFLAGS) %s\" "
    214         'CHROME_ORIGIN=SERVER_SOURCE BUILDTYPE=Debug '
    215         '%s '
    216         '%s --skip_chroot_upgrade'
    217         'chromeos-chrome' % (options.board, options.cflags, options.board,
    218                              options.cxxflags, options.board, options.ldflags,
    219                              build_packages_env, build_packages_command))
    220     logger.GetLogger().LogFatalIf(
    221         ret,
    222         'build_packages failed while trying to build debug chromeos-chrome.')
    223 
    224     # Now, we have built chromeos-chrome and all dependencies.
    225     # Finally, remove '-e' from EXTRA_BOARD_FLAGS,
    226     # otherwise, chromeos-chrome gets rebuilt.
    227     build_packages_env = build_packages_env.replace(\
    228       'EXTRA_BOARD_FLAGS=--nodeps', '')
    229 
    230     # Up to now, we have a debug built chromos-chrome browser.
    231     # Fall through to build the rest of the world.
    232 
    233     # Build packages
    234   ret = cmd_executer.ChrootRunCommand(
    235       options.chromeos_root, "CFLAGS=\"$(portageq-%s envvar CFLAGS) %s\" "
    236       "CXXFLAGS=\"$(portageq-%s envvar CXXFLAGS) %s\" "
    237       "LDFLAGS=\"$(portageq-%s envvar LDFLAGS) %s\" "
    238       'CHROME_ORIGIN=SERVER_SOURCE '
    239       '%s '
    240       '%s --skip_chroot_upgrade' % (options.board, options.cflags,
    241                                     options.board, options.cxxflags,
    242                                     options.board, options.ldflags,
    243                                     build_packages_env, build_packages_command))
    244 
    245   logger.GetLogger().LogFatalIf(ret, 'build_packages failed')
    246   if options.package:
    247     return 0
    248   # Build image
    249   ret = cmd_executer.ChrootRunCommand(
    250       options.chromeos_root, build_packages_env + ' ' + build_image_command)
    251 
    252   logger.GetLogger().LogFatalIf(ret, 'build_image failed')
    253 
    254   flags_file_name = 'flags.txt'
    255   flags_file_path = ('%s/src/build/images/%s/latest/%s' %
    256                      (options.chromeos_root, options.board, flags_file_name))
    257   flags_file = open(flags_file_path, 'wb')
    258   flags_file.write('CFLAGS=%s\n' % options.cflags)
    259   flags_file.write('CXXFLAGS=%s\n' % options.cxxflags)
    260   flags_file.write('LDFLAGS=%s\n' % options.ldflags)
    261   flags_file.close()
    262 
    263   if options.label:
    264     image_dir_path = ('%s/src/build/images/%s/latest' % (options.chromeos_root,
    265                                                          options.board))
    266     real_image_dir_path = os.path.realpath(image_dir_path)
    267     command = ('ln -sf -T %s %s/%s' %
    268                (os.path.basename(real_image_dir_path),
    269                 os.path.dirname(real_image_dir_path), options.label))
    270 
    271     ret = cmd_executer.RunCommand(command)
    272     logger.GetLogger().LogFatalIf(ret, 'Failed to apply symlink label %s' %
    273                                   options.label)
    274 
    275   return ret
    276 
    277 
    278 if __name__ == '__main__':
    279   retval = Main(sys.argv)
    280   sys.exit(retval)
    281