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