blob: 31a31d5cd5dc4d619065b066cd175e76e713e51e [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2013 The ChromiumOS Authors
Simon Glass02741682013-05-26 07:07:58 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""crosfw - Chrome OS Firmware build/flash script.
6
7Builds a firmware image for any board and writes it to the board. The image
8can be pure upstream or include Chrome OS components (-V). Some device
9tree parameters can be provided, including silent console (-C) and secure
10boot (-S). Use -i for a faster incremental build. The image is written to
11the board by default using USB/em100 (or sdcard with -x). Use -b to specify
12the board to build. Options can be added to ~/.crosfwrc - see the script for
13details.
14
15It can also flash SPI by writing a 'magic flasher' U-Boot with a payload
16to the board.
17
Simon Glass02741682013-05-26 07:07:58 -070018The script is normally run from within the U-Boot directory which is
19.../src/third_party/u-boot/files
20
21Example 1: Build upstream image for coreboot and write to a 'link':
22
Simon Glass77cc6ea2023-02-12 08:04:43 -070023 crosfw link
Simon Glass02741682013-05-26 07:07:58 -070024
Simon Glass77cc6ea2023-02-12 08:04:43 -070025Example 2: Build verified boot image (V) for daisy/snow.
Simon Glass02741682013-05-26 07:07:58 -070026
Simon Glass77cc6ea2023-02-12 08:04:43 -070027 crosfw daisy -V
Simon Glass02741682013-05-26 07:07:58 -070028
Simon Glass77cc6ea2023-02-12 08:04:43 -070029You can force a reconfigure with -f and a full distclean with -F.
Simon Glass02741682013-05-26 07:07:58 -070030
Simon Glass77cc6ea2023-02-12 08:04:43 -070031To increase verbosity use the -v and --debug options.
Simon Glass02741682013-05-26 07:07:58 -070032
Simon Glass77cc6ea2023-02-12 08:04:43 -070033This script does not use an ebuild. It does a similar thing to the
Simon Glass02741682013-05-26 07:07:58 -070034chromeos-u-boot ebuild, and runs cros_bundle_firmware to produce various
35types of image, a little like the chromeos-bootimage ebuild.
36
37The purpose of this script is to make it easier and faster to perform
38common firmware build tasks without changing boards, manually updating
39device tree files or lots of USE flags and complexity in the ebuilds.
40
41This script has been tested with snow, link and peach_pit. It builds for
42peach_pit by default. Note that it will also build any upstream ARM
Simon Glass77cc6ea2023-02-12 08:04:43 -070043board - e.g. "snapper9260" will build an image for that board.
Simon Glass02741682013-05-26 07:07:58 -070044
45Mostly you can use the script inside and outside the chroot. The main
46limitation is that dut-control doesn't really work outside the chroot,
47so writing the image to the board over USB is not possible, nor can the
48board be automatically reset on x86 platforms.
49
50For an incremental build (faster), run with -i
51
52To get faster clean builds, install ccache, and create ~/.crosfwrc with
53this line:
54
Simon Glass6ddc7f12013-07-18 15:22:41 -060055 USE_CCACHE = True
Simon Glass02741682013-05-26 07:07:58 -070056
57(make sure ~/.ccache is not on NFS, or set CCACHE_DIR)
58
59Other options are the default board to build, and verbosity (0-4), e.g.:
60
Simon Glass6ddc7f12013-07-18 15:22:41 -060061 DEFAULT_BOARD = 'daisy'
62 VERBOSE = 1
Simon Glass02741682013-05-26 07:07:58 -070063
64It is possible to use multiple servo boards, each on its own port. Add
65these lines to your ~/.crosfwrc to set the servo port to use for each
66board:
67
68 SERVO_PORT['link'] = 8888
69 SERVO_PORT['daisy'] = 9999
70 SERVO_PORT['peach_pit'] = 7777
71
Simon Glassb89ae892013-07-18 15:23:35 -060072All builds appear in the <outdir>/<board> subdirectory and images are written
73to <outdir>/<uboard>/out, where <uboard> is the U-Boot name for the board (in
74the U-Boot boards.cfg file)
75
76The value for <outdir> defaults to /tmp/crosfw but can be configured in your
77~/.crosfwrc file, e.g.:"
78
79 OUT_DIR = '/tmp/u-boot'
Simon Glass02741682013-05-26 07:07:58 -070080
81For the -a option here are some useful options:
82
83--add-blob cros-splash /dev/null
84--gbb-flags -force-dev-switch-on
85--add-node-enable /spi@131b0000/cros-ecp@0 1
86--verify --full-erase
87--bootcmd "cros_test sha"
88--gbb-flags -force-dev-switch-on
Mike Frysinger0246c1f2021-12-14 01:17:17 -050089--bmpblk ~/chromiumos/src/third_party/u-boot/bmp.bin
Simon Glass02741682013-05-26 07:07:58 -070090
91For example: -a "--gbb-flags -force-dev-switch-on"
92
93Note the standard bmpblk is at:
Mike Frysinger0246c1f2021-12-14 01:17:17 -050094 ~/chromiumos/src/third_party/chromiumos-overlay/sys-boot/
95 chromeos-bootimage/files/bmpblk.bin
Simon Glass02741682013-05-26 07:07:58 -070096"""
97
98import glob
Chris McDonald59650c32021-07-20 15:29:28 -060099import logging
Simon Glass02741682013-05-26 07:07:58 -0700100import os
Simon Glassf78c9b52023-02-14 06:58:10 -0700101from pathlib import Path
Mike Frysinger66d32cd2019-12-17 14:55:29 -0500102import subprocess
Simon Glass02741682013-05-26 07:07:58 -0700103import sys
104
Simon Glass02741682013-05-26 07:07:58 -0700105from chromite.lib import commandline
Chris McDonald59650c32021-07-20 15:29:28 -0600106from chromite.lib import constants
Simon Glass02741682013-05-26 07:07:58 -0700107from chromite.lib import cros_build_lib
108from chromite.lib import osutils
109from chromite.lib import parallel
110
111
112arch = None
113board = None
114compiler = None
115default_board = None
Simon Glass02741682013-05-26 07:07:58 -0700116in_chroot = True
117
Alex Klein1699fab2022-09-08 08:46:06 -0600118kwargs = {
119 "print_cmd": False,
120 "check": False,
Simon Glassdee7d6b2023-02-10 11:35:18 -0700121 "encoding": "utf-8",
Alex Klein1699fab2022-09-08 08:46:06 -0600122}
Simon Glass02741682013-05-26 07:07:58 -0700123
Alex Klein1699fab2022-09-08 08:46:06 -0600124outdir = ""
Simon Glass02741682013-05-26 07:07:58 -0700125
Alex Klein1699fab2022-09-08 08:46:06 -0600126# If you have multiple boards connected on different servo ports, put lines
Simon Glass02741682013-05-26 07:07:58 -0700127# like 'SERVO_PORT{"peach_pit"} = 7777' in your ~/.crosfwrc
128SERVO_PORT = {}
129
Alex Klein1699fab2022-09-08 08:46:06 -0600130src_root = os.path.join(constants.SOURCE_ROOT, "src")
Simon Glass02741682013-05-26 07:07:58 -0700131in_chroot = cros_build_lib.IsInsideChroot()
132
Alex Klein1699fab2022-09-08 08:46:06 -0600133uboard = ""
Simon Glass02741682013-05-26 07:07:58 -0700134
Alex Klein1699fab2022-09-08 08:46:06 -0600135default_board = "peach_pit"
Simon Glass02741682013-05-26 07:07:58 -0700136use_ccache = False
Simon Glass02741682013-05-26 07:07:58 -0700137
138# Special cases for the U-Boot board config, the SOCs and default device tree
139# since the naming is not always consistent.
140# x86 has a lot of boards, but to U-Boot they are all the same
141UBOARDS = {
Alex Klein1699fab2022-09-08 08:46:06 -0600142 "daisy": "smdk5250",
143 "peach": "smdk5420",
Simon Glass02741682013-05-26 07:07:58 -0700144}
Alex Klein1699fab2022-09-08 08:46:06 -0600145for b in [
146 "alex",
147 "butterfly",
148 "emeraldlake2",
149 "link",
150 "lumpy",
151 "parrot",
152 "stout",
153 "stumpy",
154]:
155 UBOARDS[b] = "coreboot-x86"
156 UBOARDS["chromeos_%s" % b] = "chromeos_coreboot"
Simon Glass02741682013-05-26 07:07:58 -0700157
Alex Klein1699fab2022-09-08 08:46:06 -0600158OUT_DIR = "/tmp/crosfw"
Simon Glassb89ae892013-07-18 15:23:35 -0600159
Alex Klein1699fab2022-09-08 08:46:06 -0600160rc_file = os.path.expanduser("~/.crosfwrc")
Simon Glass02741682013-05-26 07:07:58 -0700161if os.path.exists(rc_file):
Mike Frysinger31fdddd2023-02-24 15:50:55 -0500162 with open(rc_file, "rb") as fp:
Alex Klein1699fab2022-09-08 08:46:06 -0600163 # pylint: disable=exec-used
164 exec(compile(fp.read(), rc_file, "exec"))
Simon Glass02741682013-05-26 07:07:58 -0700165
166
Simon Glass02741682013-05-26 07:07:58 -0700167def Dumper(flag, infile, outfile):
Alex Klein1699fab2022-09-08 08:46:06 -0600168 """Run objdump on an input file.
Simon Glass02741682013-05-26 07:07:58 -0700169
Alex Klein1699fab2022-09-08 08:46:06 -0600170 Args:
Trent Apted66736d82023-05-25 10:38:28 +1000171 flag: Flag to pass objdump (e.g. '-d').
172 infile: Input file to process.
173 outfile: Output file to write to.
Alex Klein1699fab2022-09-08 08:46:06 -0600174 """
175 result = cros_build_lib.run(
176 [CompilerTool("objdump"), flag, infile], stdout=outfile, **kwargs
177 )
178 if result.returncode:
179 sys.exit()
Simon Glass02741682013-05-26 07:07:58 -0700180
181
182def CompilerTool(tool):
Alex Klein1699fab2022-09-08 08:46:06 -0600183 """Returns the cross-compiler tool filename.
Simon Glass02741682013-05-26 07:07:58 -0700184
Alex Klein1699fab2022-09-08 08:46:06 -0600185 Args:
Trent Apted66736d82023-05-25 10:38:28 +1000186 tool: Tool name to return, e.g. 'size'.
Simon Glass02741682013-05-26 07:07:58 -0700187
Alex Klein1699fab2022-09-08 08:46:06 -0600188 Returns:
Trent Apted66736d82023-05-25 10:38:28 +1000189 Filename of requested tool.
Alex Klein1699fab2022-09-08 08:46:06 -0600190 """
191 return "%s%s" % (compiler, tool)
Simon Glass02741682013-05-26 07:07:58 -0700192
193
194def ParseCmdline(argv):
Alex Klein1699fab2022-09-08 08:46:06 -0600195 """Parse all command line options.
Simon Glass02741682013-05-26 07:07:58 -0700196
Alex Klein1699fab2022-09-08 08:46:06 -0600197 Args:
Trent Apted66736d82023-05-25 10:38:28 +1000198 argv: Arguments to parse.
Simon Glass02741682013-05-26 07:07:58 -0700199
Alex Klein1699fab2022-09-08 08:46:06 -0600200 Returns:
Trent Apted66736d82023-05-25 10:38:28 +1000201 The parsed options object
Alex Klein1699fab2022-09-08 08:46:06 -0600202 """
Simon Glass95a316d2023-02-10 11:31:47 -0700203 parser = commandline.ArgumentParser(
204 description=__doc__, default_log_level="notice"
205 )
Alex Klein1699fab2022-09-08 08:46:06 -0600206 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600207 "-B",
208 "--build",
209 action="store_false",
210 default=True,
211 help="Don't build U-Boot, just configure device tree",
212 )
213 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600214 "--dt",
Alex Klein1699fab2022-09-08 08:46:06 -0600215 help="Select name of device tree file to use",
216 )
217 parser.add_argument(
Simon Glasse94b4a42023-02-15 06:35:55 -0700218 "--dtb",
219 type="file_exists",
220 help="Select a binary .dtb, passed to the U-Boot build using EXT_DTB",
221 )
222 parser.add_argument(
Simon Glass77cc6ea2023-02-12 08:04:43 -0700223 "-f",
224 "--force-reconfig",
Alex Klein1699fab2022-09-08 08:46:06 -0600225 action="store_true",
226 default=False,
Simon Glass77cc6ea2023-02-12 08:04:43 -0700227 help="Reconfigure before building",
228 )
229 parser.add_argument(
230 "-F",
231 "--force-distclean",
232 action="store_true",
233 default=False,
234 help="Run distclean and reconfigure before building",
Alex Klein1699fab2022-09-08 08:46:06 -0600235 )
236 parser.add_argument(
Simon Glass73a2f482023-02-15 06:18:50 -0700237 "-j",
238 "--jobs",
239 type=int,
240 default=os.cpu_count(),
241 help="Select the number of CPUs to use (defaults to all)",
242 )
243 parser.add_argument(
Simon Glass37da44f2023-02-15 06:30:58 -0700244 "-I",
245 "--in-tree",
246 action="store_true",
247 default=False,
248 help="Build in-tree",
249 )
250 parser.add_argument(
Simon Glassd080aa72023-02-14 07:04:52 -0700251 "-L",
252 "--no-lto",
253 dest="lto",
254 action="store_false",
255 default=True,
256 help="Disable Link-time Optimisation (LTO) when building",
257 )
258 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600259 "-O",
260 "--objdump",
261 action="store_true",
262 default=False,
263 help="Write disassembly output",
264 )
265 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600266 "-t",
267 "--trace",
268 action="store_true",
269 default=False,
270 help="Enable trace support",
271 )
272 parser.add_argument(
Simon Glassa68488c2023-02-09 16:53:47 -0700273 "-T",
274 "--target",
275 nargs="?",
276 default="all",
277 help="Select target to build",
278 )
279 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600280 "-V",
281 "--verified",
282 action="store_true",
283 default=False,
284 help="Include Chrome OS verified boot components",
285 )
286 parser.add_argument(
Alex Klein1699fab2022-09-08 08:46:06 -0600287 "-z",
288 "--size",
289 action="store_true",
290 default=False,
291 help="Display U-Boot image size",
292 )
293 parser.add_argument(
Simon Glassa68488c2023-02-09 16:53:47 -0700294 "board",
295 type=str,
296 default=default_board,
297 help="Select board to build (daisy/peach_pit/link)",
Alex Klein1699fab2022-09-08 08:46:06 -0600298 )
299 return parser.parse_args(argv)
Simon Glass02741682013-05-26 07:07:58 -0700300
301
302def SetupBuild(options):
Alex Klein1699fab2022-09-08 08:46:06 -0600303 """Set up parameters needed for the build.
Simon Glass02741682013-05-26 07:07:58 -0700304
Alex Klein1699fab2022-09-08 08:46:06 -0600305 This checks the current environment and options and sets up various things
306 needed for the build, including 'base' which holds the base flags for
307 passing to the U-Boot Makefile.
Simon Glass02741682013-05-26 07:07:58 -0700308
Alex Klein1699fab2022-09-08 08:46:06 -0600309 Args:
Trent Apted66736d82023-05-25 10:38:28 +1000310 options: Command line options
Simon Glass02741682013-05-26 07:07:58 -0700311
Alex Klein1699fab2022-09-08 08:46:06 -0600312 Returns:
Trent Apted66736d82023-05-25 10:38:28 +1000313 Base flags to use for U-Boot, as a list.
Alex Klein1699fab2022-09-08 08:46:06 -0600314 """
315 # pylint: disable=global-statement
Simon Glass826b1df2023-03-02 05:46:45 -0700316 global arch, board, compiler, outdir, uboard
Simon Glass02741682013-05-26 07:07:58 -0700317
Simon Glass9674afc2023-02-10 11:21:30 -0700318 logging.info("Building for %s", options.board)
Simon Glass02741682013-05-26 07:07:58 -0700319
Alex Klein1699fab2022-09-08 08:46:06 -0600320 # Separate out board_variant string: "peach_pit" becomes "peach", "pit".
321 # But don't mess up upstream boards which use _ in their name.
322 parts = options.board.split("_")
323 if parts[0] in ["daisy", "peach"]:
324 board = parts[0]
Simon Glass02741682013-05-26 07:07:58 -0700325 else:
Alex Klein1699fab2022-09-08 08:46:06 -0600326 board = options.board
Simon Glass02741682013-05-26 07:07:58 -0700327
Alex Klein1699fab2022-09-08 08:46:06 -0600328 # To allow this to be run from 'cros_sdk'
329 if in_chroot:
330 os.chdir(os.path.join(src_root, "third_party", "u-boot", "files"))
Simon Glass02741682013-05-26 07:07:58 -0700331
Alex Klein1699fab2022-09-08 08:46:06 -0600332 base_board = board
Simon Glass02741682013-05-26 07:07:58 -0700333
Alex Klein1699fab2022-09-08 08:46:06 -0600334 if options.verified:
335 base_board = "chromeos_%s" % base_board
Simon Glass02741682013-05-26 07:07:58 -0700336
Alex Klein1699fab2022-09-08 08:46:06 -0600337 uboard = UBOARDS.get(base_board, base_board)
Simon Glass9674afc2023-02-10 11:21:30 -0700338 logging.info("U-Boot board is %s", uboard)
Simon Glass02741682013-05-26 07:07:58 -0700339
Alex Klein1699fab2022-09-08 08:46:06 -0600340 # Pull out some information from the U-Boot boards config file
Alex Klein1699fab2022-09-08 08:46:06 -0600341 (PRE_KBUILD, PRE_KCONFIG, KCONFIG) = range(3)
342 if os.path.exists("MAINTAINERS"):
343 board_format = PRE_KBUILD
344 else:
345 board_format = PRE_KCONFIG
Mike Frysinger31fdddd2023-02-24 15:50:55 -0500346 with open("boards.cfg", encoding="utf-8") as f:
Alex Klein1699fab2022-09-08 08:46:06 -0600347 for line in f:
348 if "genboardscfg" in line:
349 board_format = KCONFIG
350 if uboard in line:
351 if line[0] == "#":
352 continue
353 fields = line.split()
354 if not fields:
355 continue
Simon Glassa44a1f92023-02-09 16:31:34 -0700356 target = fields[6]
357 # Make sure this is the right target.
358 if target != uboard:
359 continue
Alex Klein1699fab2022-09-08 08:46:06 -0600360 arch = fields[1]
361 fields += [None, None, None]
Simon Glass826b1df2023-03-02 05:46:45 -0700362 if board_format in (PRE_KCONFIG, KCONFIG):
Alex Klein1699fab2022-09-08 08:46:06 -0600363 target = fields[0]
Alex Klein1699fab2022-09-08 08:46:06 -0600364 if not arch:
365 cros_build_lib.Die(
366 "Selected board '%s' not found in boards.cfg." % board
367 )
Simon Glass02741682013-05-26 07:07:58 -0700368
Alex Klein1699fab2022-09-08 08:46:06 -0600369 vboot = os.path.join("build", board, "usr")
Simon Glass4158d732023-02-17 11:38:31 -0700370 if arch == "sandbox":
371 compiler = ""
372 elif in_chroot:
Simon Glassa44a1f92023-02-09 16:31:34 -0700373 if arch == "x86":
374 compiler = "i686-cros-linux-gnu-"
375 elif arch == "arm":
Simon Glassa3456622023-03-02 05:46:45 -0700376 compiler = "armv7a-cros-linux-gnueabihf-"
Simon Glassa44a1f92023-02-09 16:31:34 -0700377 elif arch == "aarch64":
Simon Glassa3456622023-03-02 05:46:45 -0700378 compiler = "aarch64-cros-linux-gnu-"
Alex Klein1699fab2022-09-08 08:46:06 -0600379 else:
Simon Glassa44a1f92023-02-09 16:31:34 -0700380 result = cros_build_lib.run(
381 ["buildman", "-A", "--boards", options.board],
382 capture_output=True,
Simon Glassa44a1f92023-02-09 16:31:34 -0700383 **kwargs,
384 )
385 compiler = result.stdout.strip()
386 if not compiler:
387 cros_build_lib.Die("Selected arch '%s' not supported.", arch)
Simon Glass02741682013-05-26 07:07:58 -0700388
Alex Klein1699fab2022-09-08 08:46:06 -0600389 base = [
390 "make",
Simon Glass73a2f482023-02-15 06:18:50 -0700391 "-j%d" % options.jobs,
Alex Klein1699fab2022-09-08 08:46:06 -0600392 "CROSS_COMPILE=%s" % compiler,
393 "--no-print-directory",
394 "HOSTSTRIP=true",
Alex Klein1699fab2022-09-08 08:46:06 -0600395 "QEMU_ARCH=",
Simon Glass0c0617f2023-02-19 18:32:16 -0700396 "KCONFIG_NOSILENTUPDATE=1",
Alex Klein1699fab2022-09-08 08:46:06 -0600397 ]
Simon Glassf665da62023-02-15 06:40:51 -0700398 if options.dt:
399 base.append(f"DEVICE_TREE={options.dt}")
Simon Glass37da44f2023-02-15 06:30:58 -0700400 if not options.in_tree:
401 outdir = os.path.join(OUT_DIR, uboard)
402 base.append(f"O={outdir}")
Simon Glassd080aa72023-02-14 07:04:52 -0700403 if not options.lto:
404 base.append("NO_LTO=1")
Simon Glasse94b4a42023-02-15 06:35:55 -0700405 if options.dtb:
406 base.append(f"EXT_DTB={options.dtb}")
Simon Glassd080aa72023-02-14 07:04:52 -0700407
Simon Glass95a316d2023-02-10 11:31:47 -0700408 # Enable quiet output at INFO level, everything at DEBUG level
409 if logging.getLogger().getEffectiveLevel() <= logging.DEBUG:
Alex Klein1699fab2022-09-08 08:46:06 -0600410 base.append("V=1")
Simon Glass95a316d2023-02-10 11:31:47 -0700411 elif logging.getLogger().getEffectiveLevel() >= logging.NOTICE:
412 base.append("-s")
Simon Glass02741682013-05-26 07:07:58 -0700413
Alex Klein1699fab2022-09-08 08:46:06 -0600414 if options.verified:
415 base += [
416 "VBOOT=%s" % vboot,
417 "MAKEFLAGS_VBOOT=DEBUG=1",
418 "QUIET=1",
419 "CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS",
420 "VBOOT_SOURCE=%s/platform/vboot_reference" % src_root,
421 ]
422 base.append("VBOOT_DEBUG=1")
423
Alex Klein1699fab2022-09-08 08:46:06 -0600424 base.append("BUILD_ROM=1")
425 if options.trace:
426 base.append("FTRACE=1")
Alex Klein1699fab2022-09-08 08:46:06 -0600427
Simon Glass77cc6ea2023-02-12 08:04:43 -0700428 if not options.force_reconfig:
Alex Klein1699fab2022-09-08 08:46:06 -0600429 config_mk = "%s/include/autoconf.mk" % outdir
430 if not os.path.exists(config_mk):
Simon Glass77cc6ea2023-02-12 08:04:43 -0700431 logging.warning("No build found for %s - adding -f", board)
432 options.force_reconfig = True
Alex Klein1699fab2022-09-08 08:46:06 -0600433
434 config_mk = "include/autoconf.mk"
435 if os.path.exists(config_mk):
Simon Glass37da44f2023-02-15 06:30:58 -0700436 logging.warning("Warning: '%s' exists, try 'make mrproper'", config_mk)
Alex Klein1699fab2022-09-08 08:46:06 -0600437
Alex Klein1699fab2022-09-08 08:46:06 -0600438 return base
Simon Glass02741682013-05-26 07:07:58 -0700439
440
Simon Glassf78c9b52023-02-14 06:58:10 -0700441def CheckConfigChange() -> bool:
442 """See if we need to reconfigure due to config files changing
443
444 Checks if any defconfig or Kconfig file has changed in the source tree
445 since the last time U-Boot was configured for this build. For simplicity,
446 any defconfig change will trigger this, not just one for the board being
447 built, since the cost of a reconfigure is fairly small.
448
449 Returns:
450 True if any config file has changed since U-Boot was last configured
451 """
452 fname = os.path.join(outdir, ".config")
453 ref_time = os.path.getctime(fname)
454 for p in Path.cwd().glob("configs/*"):
455 if p.stat().st_ctime > ref_time:
456 logging.warning("config/ dir has changed - adding -f")
457 return True
458
459 for p in Path.cwd().glob("**/Kconfig*"):
460 if p.stat().st_ctime > ref_time:
461 logging.warning("Kconfig file(s) changed - adding -f")
462 return True
463
464 return False
465
466
Simon Glass02741682013-05-26 07:07:58 -0700467def RunBuild(options, base, target, queue):
Alex Klein1699fab2022-09-08 08:46:06 -0600468 """Run the U-Boot build.
Simon Glass02741682013-05-26 07:07:58 -0700469
Alex Klein1699fab2022-09-08 08:46:06 -0600470 Args:
Trent Apted66736d82023-05-25 10:38:28 +1000471 options: Command line options.
472 base: Base U-Boot flags.
473 target: Target to build.
474 queue: A parallel queue to add jobs to.
Alex Klein1699fab2022-09-08 08:46:06 -0600475 """
Simon Glass9674afc2023-02-10 11:21:30 -0700476 logging.info("U-Boot build flags: %s", " ".join(base))
Simon Glass02741682013-05-26 07:07:58 -0700477
Simon Glass77cc6ea2023-02-12 08:04:43 -0700478 if options.force_distclean:
479 options.force_reconfig = True
Alex Klein1699fab2022-09-08 08:46:06 -0600480 # Ignore any error from this, some older U-Boots fail on this.
Simon Glassdee7d6b2023-02-10 11:35:18 -0700481 cros_build_lib.run(base + ["distclean"], capture_output=True, **kwargs)
Simon Glass77cc6ea2023-02-12 08:04:43 -0700482
Simon Glassf78c9b52023-02-14 06:58:10 -0700483 if not options.force_reconfig:
484 options.force_reconfig = CheckConfigChange()
485
Simon Glass77cc6ea2023-02-12 08:04:43 -0700486 # Reconfigure U-Boot.
487 if options.force_reconfig:
Alex Klein1699fab2022-09-08 08:46:06 -0600488 if os.path.exists("tools/genboardscfg.py"):
489 mtarget = "defconfig"
490 else:
491 mtarget = "config"
492 cmd = base + ["%s_%s" % (uboard, mtarget)]
493 result = cros_build_lib.run(
494 cmd, stdout=True, stderr=subprocess.STDOUT, **kwargs
495 )
Simon Glassdee7d6b2023-02-10 11:35:18 -0700496 if (
497 result.returncode
498 or logging.getLogger().getEffectiveLevel() <= logging.DEBUG
499 ):
500 print(f"cmd: {result.cmdstr}")
501 print(result.stdout, file=sys.stderr)
502 if result.returncode:
503 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700504
Alex Klein1699fab2022-09-08 08:46:06 -0600505 # Do the actual build.
506 if options.build:
507 result = cros_build_lib.run(
Simon Glass0c0617f2023-02-19 18:32:16 -0700508 base + [target],
509 input="",
Simon Glassc12ccd72023-03-01 13:35:29 -0700510 capture_output=True,
Simon Glass0c0617f2023-02-19 18:32:16 -0700511 **kwargs,
Alex Klein1699fab2022-09-08 08:46:06 -0600512 )
Simon Glassdee7d6b2023-02-10 11:35:18 -0700513 if (
514 result.returncode
515 or logging.getLogger().getEffectiveLevel() <= logging.INFO
Simon Glassc12ccd72023-03-01 13:35:29 -0700516 or result.stderr
Simon Glassdee7d6b2023-02-10 11:35:18 -0700517 ):
Alex Klein1699fab2022-09-08 08:46:06 -0600518 # The build failed, so output the results to stderr.
Simon Glassc12ccd72023-03-01 13:35:29 -0700519 print(f"cmd: {result.cmdstr}", file=sys.stderr)
520 print(result.stderr, file=sys.stderr)
521
522 # Note that stdout and stderr are separated here, so warnings
523 # associated with a file will appear separately from any output
524 # from the build system
525 if logging.getLogger().getEffectiveLevel() <= logging.INFO:
526 print(result.stdout)
Simon Glassdee7d6b2023-02-10 11:35:18 -0700527 if result.returncode:
528 sys.exit(result.returncode)
Simon Glass02741682013-05-26 07:07:58 -0700529
Alex Klein1699fab2022-09-08 08:46:06 -0600530 files = ["%s/u-boot" % outdir]
531 spl = glob.glob("%s/spl/u-boot-spl" % outdir)
532 if spl:
533 files += spl
534 if options.size:
535 result = cros_build_lib.run([CompilerTool("size")] + files, **kwargs)
536 if result.returncode:
537 sys.exit()
Simon Glass02741682013-05-26 07:07:58 -0700538
Alex Klein1699fab2022-09-08 08:46:06 -0600539 # Create disassembly files .dis and .Dis (full dump)
540 for f in files:
541 base = os.path.splitext(f)[0]
542 if options.objdump:
543 queue.put(("-d", f, base + ".dis"))
544 queue.put(("-D", f, base + ".Dis"))
545 else:
546 # Remove old files which otherwise might be confusing
547 osutils.SafeUnlink(base + ".dis")
548 osutils.SafeUnlink(base + ".Dis")
Simon Glass02741682013-05-26 07:07:58 -0700549
Simon Glass9674afc2023-02-10 11:21:30 -0700550 logging.info("Output directory %s", outdir)
Simon Glass02741682013-05-26 07:07:58 -0700551
552
Simon Glass02741682013-05-26 07:07:58 -0700553def main(argv):
Simon Glasse6201d72023-02-09 16:42:22 -0700554 """Main function for script to build firmware.
Simon Glass02741682013-05-26 07:07:58 -0700555
Alex Klein1699fab2022-09-08 08:46:06 -0600556 Args:
Trent Apted66736d82023-05-25 10:38:28 +1000557 argv: Program arguments.
Alex Klein1699fab2022-09-08 08:46:06 -0600558 """
559 options = ParseCmdline(argv)
560 base = SetupBuild(options)
Simon Glass02741682013-05-26 07:07:58 -0700561
Alex Klein1699fab2022-09-08 08:46:06 -0600562 with parallel.BackgroundTaskRunner(Dumper) as queue:
563 RunBuild(options, base, options.target, queue)
Simon Glass02741682013-05-26 07:07:58 -0700564
Alex Klein1699fab2022-09-08 08:46:06 -0600565 if options.objdump:
Simon Glass9674afc2023-02-10 11:21:30 -0700566 logging.info("Writing diasssembly files")