blob: 3a6a17e1be54231b4d6a26af24269cc0349d7b7a [file] [log] [blame]
Zhizhou Yang81d651f2020-02-10 16:51:20 -08001#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
raymes5154d7f2013-02-15 04:35:37 +00003#
George Burgess IV2124be52022-04-21 10:27:37 -07004# Copyright 2020 The ChromiumOS Authors. All rights reserved.
Zhizhou Yang81d651f2020-02-10 16:51:20 -08005# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
7
raymes5154d7f2013-02-15 04:35:37 +00008"""Script to checkout the ChromeOS source.
9
10This script sets up the ChromeOS source in the given directory, matching a
11particular release of ChromeOS.
12"""
13
Caroline Tice88272d42016-01-13 09:48:29 -080014from __future__ import print_function
15
George Burgess IV74bd3802022-09-02 16:59:27 -070016
17__author__ = (
18 "asharif@google.com (Ahmad Sharif) "
19 "llozano@google.com (Luis Lozano) "
20 "raymes@google.com (Raymes Khoury) "
21 "shenhan@google.com (Han Shen)"
22)
raymes5154d7f2013-02-15 04:35:37 +000023
Caroline Tice88272d42016-01-13 09:48:29 -080024import argparse
raymes5154d7f2013-02-15 04:35:37 +000025import os
26import sys
kbaclawski20082a02013-02-16 02:12:57 +000027
Caroline Tice88272d42016-01-13 09:48:29 -080028from cros_utils import command_executer
29from cros_utils import logger
30from cros_utils import misc
raymes5154d7f2013-02-15 04:35:37 +000031
asharife3668f12013-02-15 04:46:29 +000032
raymes5154d7f2013-02-15 04:35:37 +000033def Usage(parser, message):
George Burgess IV74bd3802022-09-02 16:59:27 -070034 print("ERROR: %s" % message)
35 parser.print_help()
36 sys.exit(0)
raymes5154d7f2013-02-15 04:35:37 +000037
asharife3668f12013-02-15 04:46:29 +000038
bjanakiraman6496e5f2013-02-15 04:50:58 +000039def Main(argv):
George Burgess IV74bd3802022-09-02 16:59:27 -070040 """Build ChromeOS."""
41 # Common initializations
42 cmd_executer = command_executer.GetCommandExecuter()
raymes5154d7f2013-02-15 04:35:37 +000043
George Burgess IV74bd3802022-09-02 16:59:27 -070044 parser = argparse.ArgumentParser()
45 parser.add_argument(
46 "--chromeos_root",
47 dest="chromeos_root",
48 help="Target directory for ChromeOS installation.",
49 )
50 parser.add_argument(
51 "--clobber_chroot",
52 dest="clobber_chroot",
53 action="store_true",
54 help="Delete the chroot and start fresh",
55 default=False,
56 )
57 parser.add_argument(
58 "--clobber_board",
59 dest="clobber_board",
60 action="store_true",
61 help="Delete the board and start fresh",
62 default=False,
63 )
64 parser.add_argument(
65 "--rebuild",
66 dest="rebuild",
67 action="store_true",
68 help="Rebuild all board packages except the toolchain.",
69 default=False,
70 )
71 parser.add_argument(
72 "--cflags",
73 dest="cflags",
74 default="",
75 help="CFLAGS for the ChromeOS packages",
76 )
77 parser.add_argument(
78 "--cxxflags",
79 dest="cxxflags",
80 default="",
81 help="CXXFLAGS for the ChromeOS packages",
82 )
83 parser.add_argument(
84 "--ldflags",
85 dest="ldflags",
86 default="",
87 help="LDFLAGS for the ChromeOS packages",
88 )
89 parser.add_argument(
90 "--board", dest="board", help="ChromeOS target board, e.g. x86-generic"
91 )
92 parser.add_argument(
93 "--package", dest="package", help="The package needs to be built"
94 )
95 parser.add_argument(
96 "--label",
97 dest="label",
98 help="Optional label symlink to point to build dir.",
99 )
100 parser.add_argument(
101 "--dev",
102 dest="dev",
103 default=False,
104 action="store_true",
105 help=(
106 "Make the final image in dev mode (eg writable, "
107 "more space on image). Defaults to False."
108 ),
109 )
110 parser.add_argument(
111 "--debug",
112 dest="debug",
113 default=False,
114 action="store_true",
115 help=(
116 'Optional. Build chrome browser with "-g -O0". '
Zhizhou Yang81d651f2020-02-10 16:51:20 -0800117 "Notice, this also turns on '--dev'. "
George Burgess IV74bd3802022-09-02 16:59:27 -0700118 "Defaults to False."
119 ),
120 )
121 parser.add_argument(
122 "--env", dest="env", default="", help="Env to pass to build_packages."
123 )
124 parser.add_argument(
125 "--vanilla",
126 dest="vanilla",
127 default=False,
128 action="store_true",
129 help="Use default ChromeOS toolchain.",
130 )
131 parser.add_argument(
132 "--vanilla_image",
133 dest="vanilla_image",
134 default=False,
135 action="store_true",
136 help=(
137 "Use prebuild packages for building the image. "
138 "It also implies the --vanilla option is set."
139 ),
140 )
raymes5154d7f2013-02-15 04:35:37 +0000141
George Burgess IV74bd3802022-09-02 16:59:27 -0700142 options = parser.parse_args(argv[1:])
raymes5154d7f2013-02-15 04:35:37 +0000143
George Burgess IV74bd3802022-09-02 16:59:27 -0700144 if options.chromeos_root is None:
145 Usage(parser, "--chromeos_root must be set")
146 options.chromeos_root = os.path.expanduser(options.chromeos_root)
147 scripts_dir = os.path.join(options.chromeos_root, "src", "scripts")
148 if not os.path.isdir(scripts_dir):
149 Usage(
150 parser,
151 "--chromeos_root must be set up first. Use setup_chromeos.py",
152 )
raymes5154d7f2013-02-15 04:35:37 +0000153
George Burgess IV74bd3802022-09-02 16:59:27 -0700154 if options.board is None:
155 Usage(parser, "--board must be set")
raymes5154d7f2013-02-15 04:35:37 +0000156
George Burgess IV74bd3802022-09-02 16:59:27 -0700157 if options.debug:
158 options.dev = True
shenhan48738582013-02-19 22:45:41 +0000159
George Burgess IV74bd3802022-09-02 16:59:27 -0700160 build_packages_env = options.env
161 if build_packages_env.find("EXTRA_BOARD_FLAGS=") != -1:
162 logger.GetLogger().LogFatal(
163 (
164 'Passing "EXTRA_BOARD_FLAGS" in "--env" is not supported. '
165 "This flags is used internally by this script. "
166 "Contact the author for more detail."
167 )
168 )
shenhan48738582013-02-19 22:45:41 +0000169
George Burgess IV74bd3802022-09-02 16:59:27 -0700170 if options.rebuild:
171 build_packages_env += " EXTRA_BOARD_FLAGS=-e"
172 # EXTRA_BOARD_FLAGS=-e should clean up the object files for the chrome
173 # browser but it doesn't. So do it here.
174 misc.RemoveChromeBrowserObjectFiles(
175 options.chromeos_root, options.board
176 )
asharif80b47dc2013-02-15 06:31:19 +0000177
George Burgess IV74bd3802022-09-02 16:59:27 -0700178 # Build with afdo_use by default.
179 # To change the default use --env="USE=-afdo_use".
180 build_packages_env = misc.MergeEnvStringWithDict(
181 build_packages_env, {"USE": "chrome_internal afdo_use -cros-debug"}
182 )
asharif01e29a52013-02-15 04:56:41 +0000183
George Burgess IV74bd3802022-09-02 16:59:27 -0700184 build_packages_command = misc.GetBuildPackagesCommand(
185 board=options.board, usepkg=options.vanilla_image, debug=options.debug
186 )
yunlian5acba6e2013-02-19 22:34:37 +0000187
George Burgess IV74bd3802022-09-02 16:59:27 -0700188 if options.package:
189 build_packages_command += " {0}".format(options.package)
yunlian5acba6e2013-02-19 22:34:37 +0000190
George Burgess IV74bd3802022-09-02 16:59:27 -0700191 build_image_command = misc.GetBuildImageCommand(options.board, options.dev)
asharifca8c5ef2013-02-15 04:57:02 +0000192
George Burgess IV74bd3802022-09-02 16:59:27 -0700193 if options.vanilla or options.vanilla_image:
194 command = misc.GetSetupBoardCommand(
195 options.board,
196 usepkg=options.vanilla_image,
197 force=options.clobber_board,
198 )
199 command += "; " + build_packages_env + " " + build_packages_command
200 command += "&& " + build_packages_env + " " + build_image_command
201 ret = cmd_executer.ChrootRunCommand(options.chromeos_root, command)
202 return ret
asharifb1752c82013-02-15 04:56:37 +0000203
George Burgess IV74bd3802022-09-02 16:59:27 -0700204 # Setup board
205 if (
206 not os.path.isdir(
207 options.chromeos_root + "/chroot/build/" + options.board
208 )
209 or options.clobber_board
210 ):
211 # Run build_tc.py from binary package
212 ret = cmd_executer.ChrootRunCommand(
213 options.chromeos_root,
214 misc.GetSetupBoardCommand(
215 options.board, force=options.clobber_board
216 ),
217 )
218 logger.GetLogger().LogFatalIf(ret, "setup_board failed")
219 else:
220 logger.GetLogger().LogOutput(
221 "Did not setup_board " "because it already exists"
222 )
223
224 if options.debug:
225 # Perform 2-step build_packages to build a debug chrome browser.
226
227 # Firstly, build everything that chromeos-chrome depends on normally.
228 if options.rebuild:
229 # Give warning about "--rebuild" and "--debug". Under this combination,
230 # only dependencies of "chromeos-chrome" get rebuilt.
231 logger.GetLogger().LogWarning(
232 '--rebuild" does not correctly re-build every package when '
233 '"--debug" is enabled. '
234 )
235
236 # Replace EXTRA_BOARD_FLAGS=-e with "-e --onlydeps"
237 build_packages_env = build_packages_env.replace(
238 "EXTRA_BOARD_FLAGS=-e", 'EXTRA_BOARD_FLAGS="-e --onlydeps"'
239 )
240 else:
241 build_packages_env += " EXTRA_BOARD_FLAGS=--onlydeps"
242
243 ret = cmd_executer.ChrootRunCommand(
244 options.chromeos_root,
245 'CFLAGS="$(portageq-%s envvar CFLAGS) %s" '
246 'CXXFLAGS="$(portageq-%s envvar CXXFLAGS) %s" '
247 'LDFLAGS="$(portageq-%s envvar LDFLAGS) %s" '
248 "CHROME_ORIGIN=SERVER_SOURCE "
249 "%s "
250 "%s --skip_chroot_upgrade"
251 "chromeos-chrome"
252 % (
253 options.board,
254 options.cflags,
255 options.board,
256 options.cxxflags,
257 options.board,
258 options.ldflags,
259 build_packages_env,
260 build_packages_command,
261 ),
262 )
263
264 logger.GetLogger().LogFatalIf(
265 ret,
266 "build_packages failed while trying to build chromeos-chrome deps.",
267 )
268
269 # Secondly, build chromeos-chrome using debug mode.
270 # Replace '--onlydeps' with '--nodeps'.
271 if options.rebuild:
272 build_packages_env = build_packages_env.replace(
273 'EXTRA_BOARD_FLAGS="-e --onlydeps"',
274 "EXTRA_BOARD_FLAGS=--nodeps",
275 )
276 else:
277 build_packages_env = build_packages_env.replace(
278 "EXTRA_BOARD_FLAGS=--onlydeps", "EXTRA_BOARD_FLAGS=--nodeps"
279 )
280 ret = cmd_executer.ChrootRunCommand(
281 options.chromeos_root,
282 'CFLAGS="$(portageq-%s envvar CFLAGS) %s" '
283 'CXXFLAGS="$(portageq-%s envvar CXXFLAGS) %s" '
284 'LDFLAGS="$(portageq-%s envvar LDFLAGS) %s" '
285 "CHROME_ORIGIN=SERVER_SOURCE BUILDTYPE=Debug "
286 "%s "
287 "%s --skip_chroot_upgrade"
288 "chromeos-chrome"
289 % (
290 options.board,
291 options.cflags,
292 options.board,
293 options.cxxflags,
294 options.board,
295 options.ldflags,
296 build_packages_env,
297 build_packages_command,
298 ),
299 )
300 logger.GetLogger().LogFatalIf(
301 ret,
302 "build_packages failed while trying to build debug chromeos-chrome.",
303 )
304
305 # Now, we have built chromeos-chrome and all dependencies.
306 # Finally, remove '-e' from EXTRA_BOARD_FLAGS,
307 # otherwise, chromeos-chrome gets rebuilt.
308 build_packages_env = build_packages_env.replace(
309 "EXTRA_BOARD_FLAGS=--nodeps", ""
310 )
311
312 # Up to now, we have a debug built chromos-chrome browser.
313 # Fall through to build the rest of the world.
314
315 # Build packages
Zhizhou Yang81d651f2020-02-10 16:51:20 -0800316 ret = cmd_executer.ChrootRunCommand(
317 options.chromeos_root,
George Burgess IV74bd3802022-09-02 16:59:27 -0700318 'CFLAGS="$(portageq-%s envvar CFLAGS) %s" '
Zhizhou Yang81d651f2020-02-10 16:51:20 -0800319 'CXXFLAGS="$(portageq-%s envvar CXXFLAGS) %s" '
320 'LDFLAGS="$(portageq-%s envvar LDFLAGS) %s" '
George Burgess IV74bd3802022-09-02 16:59:27 -0700321 "CHROME_ORIGIN=SERVER_SOURCE "
322 "%s "
323 "%s --skip_chroot_upgrade"
324 % (
325 options.board,
326 options.cflags,
327 options.board,
328 options.cxxflags,
329 options.board,
330 options.ldflags,
331 build_packages_env,
332 build_packages_command,
333 ),
334 )
shenhan48738582013-02-19 22:45:41 +0000335
George Burgess IV74bd3802022-09-02 16:59:27 -0700336 logger.GetLogger().LogFatalIf(ret, "build_packages failed")
337 if options.package:
338 return 0
339 # Build image
shenhan48738582013-02-19 22:45:41 +0000340 ret = cmd_executer.ChrootRunCommand(
George Burgess IV74bd3802022-09-02 16:59:27 -0700341 options.chromeos_root, build_packages_env + " " + build_image_command
342 )
shenhan48738582013-02-19 22:45:41 +0000343
George Burgess IV74bd3802022-09-02 16:59:27 -0700344 logger.GetLogger().LogFatalIf(ret, "build_image failed")
shenhan48738582013-02-19 22:45:41 +0000345
George Burgess IV74bd3802022-09-02 16:59:27 -0700346 flags_file_name = "flags.txt"
347 flags_file_path = "%s/src/build/images/%s/latest/%s" % (
348 options.chromeos_root,
349 options.board,
350 flags_file_name,
351 )
352 with open(flags_file_path, "w", encoding="utf-8") as flags_file:
353 flags_file.write("CFLAGS=%s\n" % options.cflags)
354 flags_file.write("CXXFLAGS=%s\n" % options.cxxflags)
355 flags_file.write("LDFLAGS=%s\n" % options.ldflags)
shenhan48738582013-02-19 22:45:41 +0000356
George Burgess IV74bd3802022-09-02 16:59:27 -0700357 if options.label:
358 image_dir_path = "%s/src/build/images/%s/latest" % (
359 options.chromeos_root,
360 options.board,
361 )
362 real_image_dir_path = os.path.realpath(image_dir_path)
363 command = "ln -sf -T %s %s/%s" % (
364 os.path.basename(real_image_dir_path),
365 os.path.dirname(real_image_dir_path),
366 options.label,
367 )
raymesbfb57992013-02-15 04:35:45 +0000368
George Burgess IV74bd3802022-09-02 16:59:27 -0700369 ret = cmd_executer.RunCommand(command)
370 logger.GetLogger().LogFatalIf(
371 ret, "Failed to apply symlink label %s" % options.label
372 )
raymesbfb57992013-02-15 04:35:45 +0000373
George Burgess IV74bd3802022-09-02 16:59:27 -0700374 return ret
raymes5154d7f2013-02-15 04:35:37 +0000375
Luis Lozanof2a3ef42015-12-15 13:49:30 -0800376
George Burgess IV74bd3802022-09-02 16:59:27 -0700377if __name__ == "__main__":
378 retval = Main(sys.argv)
379 sys.exit(retval)