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