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