1#!/usr/bin/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('--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 278if __name__ == '__main__': 279 retval = Main(sys.argv) 280 sys.exit(retval) 281