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__ = 'raymes@google.com (Raymes Khoury)' 13 14import argparse 15import os 16import sys 17 18from cros_utils import command_executer 19from cros_utils import logger 20from cros_utils import misc 21 22 23def Usage(parser, message): 24 print('ERROR: %s' % message) 25 parser.print_help() 26 sys.exit(0) 27 28 29def Main(argv): 30 """Build Chrome browser.""" 31 32 cmd_executer = command_executer.GetCommandExecuter() 33 34 parser = argparse.ArgumentParser() 35 parser.add_argument( 36 '--chromeos_root', 37 dest='chromeos_root', 38 help='Target directory for ChromeOS installation.') 39 parser.add_argument('--version', dest='version') 40 parser.add_argument( 41 '--clean', 42 dest='clean', 43 default=False, 44 action='store_true', 45 help=('Clean the /var/cache/chromeos-chrome/' 46 'chrome-src/src/out_$board dir')) 47 parser.add_argument( 48 '--env', dest='env', default='', help='Use the following env') 49 parser.add_argument( 50 '--ebuild_version', 51 dest='ebuild_version', 52 help='Use this ebuild instead of the default one.') 53 parser.add_argument( 54 '--cflags', 55 dest='cflags', 56 default='', 57 help='CFLAGS for the ChromeOS packages') 58 parser.add_argument( 59 '--cxxflags', 60 dest='cxxflags', 61 default='', 62 help='CXXFLAGS for the ChromeOS packages') 63 parser.add_argument( 64 '--ldflags', 65 dest='ldflags', 66 default='', 67 help='LDFLAGS for the ChromeOS packages') 68 parser.add_argument( 69 '--board', dest='board', help='ChromeOS target board, e.g. x86-generic') 70 parser.add_argument( 71 '--no_build_image', 72 dest='no_build_image', 73 default=False, 74 action='store_true', 75 help=('Skip build image after building browser.' 76 'Defaults to False.')) 77 parser.add_argument( 78 '--label', 79 dest='label', 80 help='Optional label to apply to the ChromeOS image.') 81 parser.add_argument( 82 '--build_image_args', 83 default='', 84 dest='build_image_args', 85 help='Optional arguments to build_image.') 86 parser.add_argument( 87 '--cros_workon', 88 dest='cros_workon', 89 help='Build using external source tree.') 90 parser.add_argument( 91 '--dev', 92 dest='dev', 93 default=False, 94 action='store_true', 95 help=('Build a dev (eg. writable/large) image. ' 96 'Defaults to False.')) 97 parser.add_argument( 98 '--debug', 99 dest='debug', 100 default=False, 101 action='store_true', 102 help=('Build chrome browser using debug mode. ' 103 'This option implies --dev. Defaults to false.')) 104 parser.add_argument( 105 '--verbose', 106 dest='verbose', 107 default=False, 108 action='store_true', 109 help='Build with verbose information.') 110 111 options = parser.parse_args(argv) 112 113 if options.chromeos_root is None: 114 Usage(parser, '--chromeos_root must be set') 115 116 if options.board is None: 117 Usage(parser, '--board must be set') 118 119 if options.version is None: 120 logger.GetLogger().LogOutput('No Chrome version given so ' 121 'using the default checked in version.') 122 chrome_version = '' 123 else: 124 chrome_version = 'CHROME_VERSION=%s' % options.version 125 126 if options.dev and options.no_build_image: 127 logger.GetLogger().LogOutput( 128 "\"--dev\" is meaningless if \"--no_build_image\" is given.") 129 130 if options.debug: 131 options.dev = True 132 133 options.chromeos_root = misc.CanonicalizePath(options.chromeos_root) 134 135 unmask_env = 'ACCEPT_KEYWORDS=~*' 136 if options.ebuild_version: 137 ebuild_version = '=%s' % options.ebuild_version 138 options.env = '%s %s' % (options.env, unmask_env) 139 else: 140 ebuild_version = 'chromeos-chrome' 141 142 if options.cros_workon and not ( 143 os.path.isdir(options.cros_workon) and os.path.exists( 144 os.path.join(options.cros_workon, 'src/chromeos/BUILD.gn'))): 145 Usage(parser, '--cros_workon must be a valid chromium browser checkout.') 146 147 if options.verbose: 148 options.env = misc.MergeEnvStringWithDict( 149 options.env, {'USE': 'chrome_internal verbose'}) 150 else: 151 options.env = misc.MergeEnvStringWithDict(options.env, 152 {'USE': 'chrome_internal'}) 153 if options.debug: 154 options.env = misc.MergeEnvStringWithDict(options.env, 155 {'BUILDTYPE': 'Debug'}) 156 157 if options.clean: 158 misc.RemoveChromeBrowserObjectFiles(options.chromeos_root, options.board) 159 160 chrome_origin = 'SERVER_SOURCE' 161 if options.cros_workon: 162 chrome_origin = 'LOCAL_SOURCE' 163 command = 'cros_workon --board={0} start chromeos-chrome'.format( 164 options.board) 165 ret = cmd_executer.ChrootRunCommandWOutput(options.chromeos_root, command) 166 167 # cros_workon start returns non-zero if chromeos-chrome is already a 168 # cros_workon package. 169 if ret[0] and ret[2].find( 170 'WARNING : Already working on chromeos-base/chromeos-chrome') == -1: 171 logger.GetLogger().LogFatal('cros_workon chromeos-chrome failed.') 172 173 # Return value is non-zero means we do find the "Already working on..." 174 # message, keep the information, so later on we do not revert the 175 # cros_workon status. 176 cros_workon_keep = (ret[0] != 0) 177 178 # Emerge the browser 179 emerge_browser_command = ('CHROME_ORIGIN={0} {1} ' 180 'CFLAGS="$(portageq-{2} envvar CFLAGS) {3}" ' 181 'LDFLAGS="$(portageq-{2} envvar LDFLAGS) {4}" ' 182 'CXXFLAGS="$(portageq-{2} envvar CXXFLAGS) {5}" ' 183 '{6} emerge-{2} --buildpkg {7}').format( 184 chrome_origin, chrome_version, options.board, 185 options.cflags, options.ldflags, 186 options.cxxflags, options.env, ebuild_version) 187 188 cros_sdk_options = '' 189 if options.cros_workon: 190 cros_sdk_options = '--chrome_root={0}'.format(options.cros_workon) 191 192 ret = cmd_executer.ChrootRunCommand( 193 options.chromeos_root, 194 emerge_browser_command, 195 cros_sdk_options=cros_sdk_options) 196 197 logger.GetLogger().LogFatalIf(ret, 'build_packages failed') 198 199 if options.cros_workon and not cros_workon_keep: 200 command = 'cros_workon --board={0} stop chromeos-chrome'.format( 201 options.board) 202 ret = cmd_executer.ChrootRunCommand(options.chromeos_root, command) 203 # cros_workon failed, not a fatal one, just report it. 204 if ret: 205 print('cros_workon stop chromeos-chrome failed.') 206 207 if options.no_build_image: 208 return ret 209 210 # Finally build the image 211 ret = cmd_executer.ChrootRunCommand(options.chromeos_root, 212 '{0} {1} {2} {3}'.format( 213 unmask_env, options.env, 214 misc.GetBuildImageCommand( 215 options.board, dev=options.dev), 216 options.build_image_args)) 217 218 logger.GetLogger().LogFatalIf(ret, 'build_image failed') 219 220 flags_file_name = 'chrome_flags.txt' 221 flags_file_path = '{0}/src/build/images/{1}/latest/{2}'.format( 222 options.chromeos_root, options.board, flags_file_name) 223 flags_file = open(flags_file_path, 'wb') 224 flags_file.write('CFLAGS={0}\n'.format(options.cflags)) 225 flags_file.write('CXXFLAGS={0}\n'.format(options.cxxflags)) 226 flags_file.write('LDFLAGS={0}\n'.format(options.ldflags)) 227 flags_file.close() 228 229 if options.label: 230 image_dir_path = '{0}/src/build/images/{1}/latest'.format( 231 options.chromeos_root, options.board) 232 real_image_dir_path = os.path.realpath(image_dir_path) 233 command = 'ln -sf -T {0} {1}/{2}'.format( 234 os.path.basename(real_image_dir_path),\ 235 os.path.dirname(real_image_dir_path),\ 236 options.label) 237 238 ret = cmd_executer.RunCommand(command) 239 logger.GetLogger().LogFatalIf( 240 ret, 'Failed to apply symlink label %s' % options.label) 241 242 return ret 243 244 245if __name__ == '__main__': 246 retval = Main(sys.argv[1:]) 247 sys.exit(retval) 248