blob: fc9e926d3ad1ffbbc0d7f79aee1a821ff23a3162 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001# SPDX-License-Identifier: GPL-2.0+
Simon Glassfc3fe1c2013-04-03 11:07:16 +00002# Copyright (c) 2013 The Chromium OS Authors.
3#
Simon Glassfc3fe1c2013-04-03 11:07:16 +00004
5import multiprocessing
Jan Kiszkade65b122023-04-22 16:42:48 +02006try:
7 import importlib.resources
8except ImportError:
9 # for Python 3.6
10 import importlib_resources
Simon Glassfc3fe1c2013-04-03 11:07:16 +000011import os
Simon Glass883a3212014-09-05 19:00:18 -060012import shutil
Simon Glass0ede00f2020-04-17 18:09:02 -060013import subprocess
Simon Glassfc3fe1c2013-04-03 11:07:16 +000014import sys
15
Simon Glassc52bd222022-07-11 19:04:03 -060016from buildman import boards
Simon Glass0ede00f2020-04-17 18:09:02 -060017from buildman import bsettings
Simon Glass2b4806e2022-01-22 05:07:33 -070018from buildman import cfgutil
Simon Glass0ede00f2020-04-17 18:09:02 -060019from buildman import toolchain
20from buildman.builder import Builder
Simon Glassbf776672020-04-17 18:09:04 -060021from patman import gitutil
22from patman import patchstream
Simon Glass4583c002023-02-23 18:18:04 -070023from u_boot_pylib import command
24from u_boot_pylib import terminal
25from u_boot_pylib import tools
26from u_boot_pylib.terminal import tprint
Simon Glassfc3fe1c2013-04-03 11:07:16 +000027
28def GetPlural(count):
29 """Returns a plural 's' if count is not 1"""
30 return 's' if count != 1 else ''
31
Simon Glassfea58582014-08-09 15:32:59 -060032def GetActionSummary(is_summary, commits, selected, options):
Simon Glassfc3fe1c2013-04-03 11:07:16 +000033 """Return a string summarising the intended action.
34
35 Returns:
36 Summary string.
37 """
Simon Glassfea58582014-08-09 15:32:59 -060038 if commits:
39 count = len(commits)
Simon Glassc05aa032019-10-31 07:42:53 -060040 count = (count + options.step - 1) // options.step
Simon Glassfea58582014-08-09 15:32:59 -060041 commit_str = '%d commit%s' % (count, GetPlural(count))
42 else:
43 commit_str = 'current source'
44 str = '%s %s for %d boards' % (
45 'Summary of' if is_summary else 'Building', commit_str,
Simon Glassfc3fe1c2013-04-03 11:07:16 +000046 len(selected))
47 str += ' (%d thread%s, %d job%s per thread)' % (options.threads,
48 GetPlural(options.threads), options.jobs, GetPlural(options.jobs))
49 return str
50
Simon Glass06890362018-06-11 23:26:46 -060051def ShowActions(series, why_selected, boards_selected, builder, options,
52 board_warnings):
Simon Glassfc3fe1c2013-04-03 11:07:16 +000053 """Display a list of actions that we would take, if not a dry run.
54
55 Args:
56 series: Series object
57 why_selected: Dictionary where each key is a buildman argument
Simon Glass8d7523c2017-01-23 05:38:56 -070058 provided by the user, and the value is the list of boards
59 brought in by that argument. For example, 'arm' might bring
60 in 400 boards, so in this case the key would be 'arm' and
Simon Glassfc3fe1c2013-04-03 11:07:16 +000061 the value would be a list of board names.
62 boards_selected: Dict of selected boards, key is target name,
63 value is Board object
64 builder: The builder that will be used to build the commits
65 options: Command line options object
Simon Glass06890362018-06-11 23:26:46 -060066 board_warnings: List of warnings obtained from board selected
Simon Glassfc3fe1c2013-04-03 11:07:16 +000067 """
68 col = terminal.Color()
Simon Glassc05aa032019-10-31 07:42:53 -060069 print('Dry run, so not doing much. But I would do this:')
70 print()
Simon Glassfea58582014-08-09 15:32:59 -060071 if series:
72 commits = series.commits
73 else:
74 commits = None
Simon Glassc05aa032019-10-31 07:42:53 -060075 print(GetActionSummary(False, commits, boards_selected,
76 options))
77 print('Build directory: %s' % builder.base_dir)
Simon Glassfea58582014-08-09 15:32:59 -060078 if commits:
79 for upto in range(0, len(series.commits), options.step):
80 commit = series.commits[upto]
Simon Glass252ac582022-01-29 14:14:17 -070081 print(' ', col.build(col.YELLOW, commit.hash[:8], bright=False), end=' ')
Simon Glassc05aa032019-10-31 07:42:53 -060082 print(commit.subject)
83 print()
Simon Glassfc3fe1c2013-04-03 11:07:16 +000084 for arg in why_selected:
85 if arg != 'all':
Simon Glassc05aa032019-10-31 07:42:53 -060086 print(arg, ': %d boards' % len(why_selected[arg]))
Simon Glass8d7523c2017-01-23 05:38:56 -070087 if options.verbose:
Simon Glassc05aa032019-10-31 07:42:53 -060088 print(' %s' % ' '.join(why_selected[arg]))
89 print(('Total boards to build for each commit: %d\n' %
90 len(why_selected['all'])))
Simon Glass06890362018-06-11 23:26:46 -060091 if board_warnings:
92 for warning in board_warnings:
Simon Glass252ac582022-01-29 14:14:17 -070093 print(col.build(col.YELLOW, warning))
Simon Glassfc3fe1c2013-04-03 11:07:16 +000094
Simon Glasscc2c0d12022-07-11 19:04:00 -060095def ShowToolchainPrefix(brds, toolchains):
Simon Glass57cb9d52019-12-05 15:59:14 -070096 """Show information about a the tool chain used by one or more boards
97
Simon Glass4e9162d2020-03-18 09:42:47 -060098 The function checks that all boards use the same toolchain, then prints
99 the correct value for CROSS_COMPILE.
Simon Glass57cb9d52019-12-05 15:59:14 -0700100
101 Args:
102 boards: Boards object containing selected boards
103 toolchains: Toolchains object containing available toolchains
Simon Glass57cb9d52019-12-05 15:59:14 -0700104
105 Return:
106 None on success, string error message otherwise
107 """
Simon Glass6014db62022-07-11 19:04:02 -0600108 board_selected = brds.get_selected_dict()
Simon Glass57cb9d52019-12-05 15:59:14 -0700109 tc_set = set()
Simon Glasscc2c0d12022-07-11 19:04:00 -0600110 for brd in board_selected.values():
Simon Glass57cb9d52019-12-05 15:59:14 -0700111 tc_set.add(toolchains.Select(brd.arch))
112 if len(tc_set) != 1:
113 return 'Supplied boards must share one toolchain'
114 return False
115 tc = tc_set.pop()
Simon Glass4e9162d2020-03-18 09:42:47 -0600116 print(tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE))
Simon Glass57cb9d52019-12-05 15:59:14 -0700117 return None
118
Tom Rinid7713ad2022-11-09 19:14:53 -0700119def get_allow_missing(opt_allow, opt_no_allow, num_selected, has_branch):
120 allow_missing = False
121 am_setting = bsettings.GetGlobalItemValue('allow-missing')
122 if am_setting:
123 if am_setting == 'always':
124 allow_missing = True
125 if 'multiple' in am_setting and num_selected > 1:
126 allow_missing = True
127 if 'branch' in am_setting and has_branch:
128 allow_missing = True
129
130 if opt_allow:
131 allow_missing = True
132 if opt_no_allow:
133 allow_missing = False
134 return allow_missing
135
Simon Glasscc2c0d12022-07-11 19:04:00 -0600136def DoBuildman(options, args, toolchains=None, make_func=None, brds=None,
Simon Glass8116c782021-04-11 16:27:27 +1200137 clean_dir=False, test_thread_exceptions=False):
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000138 """The main control code for buildman
139
140 Args:
141 options: Command line options object
142 args: Command line arguments (list of strings)
Simon Glassd4144e42014-09-05 19:00:13 -0600143 toolchains: Toolchains to use - this should be a Toolchains()
144 object. If None, then it will be created and scanned
145 make_func: Make function to use for the builder. This is called
146 to execute 'make'. If this is None, the normal function
147 will be used, which calls the 'make' tool with suitable
148 arguments. This setting is useful for tests.
Simon Glasscc2c0d12022-07-11 19:04:00 -0600149 brds: Boards() object to use, containing a list of available
Simon Glass823e60b2014-09-05 19:00:16 -0600150 boards. If this is None it will be created and scanned.
Simon Glass24993312021-04-11 16:27:25 +1200151 clean_dir: Used for tests only, indicates that the existing output_dir
152 should be removed before starting the build
Simon Glass8116c782021-04-11 16:27:27 +1200153 test_thread_exceptions: Uses for tests only, True to make the threads
154 raise an exception instead of reporting their result. This simulates
155 a failure in the code somewhere
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000156 """
Simon Glass883a3212014-09-05 19:00:18 -0600157 global builder
158
Simon Glass48ba5852014-09-05 19:00:11 -0600159 if options.full_help:
Simon Glassd85f7902023-02-23 18:18:12 -0700160 with importlib.resources.path('buildman', 'README.rst') as readme:
161 tools.print_full_help(str(readme))
Simon Glass48ba5852014-09-05 19:00:11 -0600162 return 0
163
Simon Glass0157b182022-01-29 14:14:11 -0700164 gitutil.setup()
Simon Glass713bea32016-07-27 20:33:02 -0600165 col = terminal.Color()
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000166
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000167 options.git_dir = os.path.join(options.git, '.git')
168
Simon Glass7e92e462016-07-27 20:33:04 -0600169 no_toolchains = toolchains is None
170 if no_toolchains:
Simon Glass00beb242019-01-07 16:44:20 -0700171 toolchains = toolchain.Toolchains(options.override_toolchain)
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000172
Simon Glass827e37b2014-12-01 17:34:06 -0700173 if options.fetch_arch:
174 if options.fetch_arch == 'list':
175 sorted_list = toolchains.ListArchs()
Simon Glass252ac582022-01-29 14:14:17 -0700176 print(col.build(col.BLUE, 'Available architectures: %s\n' %
Simon Glassc05aa032019-10-31 07:42:53 -0600177 ' '.join(sorted_list)))
Simon Glass827e37b2014-12-01 17:34:06 -0700178 return 0
179 else:
180 fetch_arch = options.fetch_arch
181 if fetch_arch == 'all':
182 fetch_arch = ','.join(toolchains.ListArchs())
Simon Glass252ac582022-01-29 14:14:17 -0700183 print(col.build(col.CYAN, '\nDownloading toolchains: %s' %
Simon Glassc05aa032019-10-31 07:42:53 -0600184 fetch_arch))
Simon Glass827e37b2014-12-01 17:34:06 -0700185 for arch in fetch_arch.split(','):
Simon Glassc05aa032019-10-31 07:42:53 -0600186 print()
Simon Glass827e37b2014-12-01 17:34:06 -0700187 ret = toolchains.FetchAndInstall(arch)
188 if ret:
189 return ret
190 return 0
191
Simon Glass7e92e462016-07-27 20:33:04 -0600192 if no_toolchains:
193 toolchains.GetSettings()
Simon Glass40232c92018-11-06 16:02:10 -0700194 toolchains.Scan(options.list_tool_chains and options.verbose)
Simon Glass7e92e462016-07-27 20:33:04 -0600195 if options.list_tool_chains:
196 toolchains.List()
Simon Glassc05aa032019-10-31 07:42:53 -0600197 print()
Simon Glass7e92e462016-07-27 20:33:04 -0600198 return 0
199
Simon Glass88daaef2020-04-17 17:51:32 -0600200 if not options.output_dir:
201 if options.work_in_output:
Simon Glass252ac582022-01-29 14:14:17 -0700202 sys.exit(col.build(col.RED, '-w requires that you specify -o'))
Simon Glass88daaef2020-04-17 17:51:32 -0600203 options.output_dir = '..'
Simon Glasseb70a2c2020-04-09 15:08:51 -0600204
Simon Glass1b218422023-07-19 17:48:27 -0600205 nr_cups = options.threads or multiprocessing.cpu_count()
206
Simon Glass7c66ead2019-12-05 15:59:13 -0700207 # Work out what subset of the boards we are building
Simon Glasscc2c0d12022-07-11 19:04:00 -0600208 if not brds:
Simon Glass7c66ead2019-12-05 15:59:13 -0700209 if not os.path.exists(options.output_dir):
210 os.makedirs(options.output_dir)
211 board_file = os.path.join(options.output_dir, 'boards.cfg')
Simon Glass7c66ead2019-12-05 15:59:13 -0700212
Simon Glassc52bd222022-07-11 19:04:03 -0600213 brds = boards.Boards()
Simon Glass1b218422023-07-19 17:48:27 -0600214 if options.maintainer_check:
215 warnings = brds.build_board_list(jobs=nr_cups)[1]
216 if warnings:
217 for warn in warnings:
218 print(warn, file=sys.stderr)
219 return 2
220 return 0
221
222 ok = brds.ensure_board_list(board_file, nr_cups,
Simon Glassadd76e72022-07-11 19:04:08 -0600223 force=options.regen_board_list,
224 quiet=not options.verbose)
Simon Glassa8a01412022-07-11 19:04:04 -0600225 if options.regen_board_list:
Simon Glassadd76e72022-07-11 19:04:08 -0600226 return 0 if ok else 2
Simon Glass6014db62022-07-11 19:04:02 -0600227 brds.read_boards(board_file)
Simon Glass7c66ead2019-12-05 15:59:13 -0700228
229 exclude = []
230 if options.exclude:
231 for arg in options.exclude:
232 exclude += arg.split(',')
233
234 if options.boards:
235 requested_boards = []
236 for b in options.boards:
237 requested_boards += b.split(',')
238 else:
239 requested_boards = None
Simon Glass6014db62022-07-11 19:04:02 -0600240 why_selected, board_warnings = brds.select_boards(args, exclude,
241 requested_boards)
242 selected = brds.get_selected()
Simon Glass7c66ead2019-12-05 15:59:13 -0700243 if not len(selected):
Simon Glass252ac582022-01-29 14:14:17 -0700244 sys.exit(col.build(col.RED, 'No matching boards found'))
Simon Glass7c66ead2019-12-05 15:59:13 -0700245
Simon Glass4e9162d2020-03-18 09:42:47 -0600246 if options.print_prefix:
Simon Glasscc2c0d12022-07-11 19:04:00 -0600247 err = ShowToolchainPrefix(brds, toolchains)
Simon Glass57cb9d52019-12-05 15:59:14 -0700248 if err:
Simon Glass252ac582022-01-29 14:14:17 -0700249 sys.exit(col.build(col.RED, err))
Simon Glass57cb9d52019-12-05 15:59:14 -0700250 return 0
251
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000252 # Work out how many commits to build. We want to build everything on the
253 # branch. We also build the upstream commit as a control so we can see
254 # problems introduced by the first commit on the branch.
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000255 count = options.count
Simon Glass5abab202014-12-01 17:33:57 -0700256 has_range = options.branch and '..' in options.branch
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000257 if count == -1:
258 if not options.branch:
Simon Glassfea58582014-08-09 15:32:59 -0600259 count = 1
260 else:
Simon Glass5abab202014-12-01 17:33:57 -0700261 if has_range:
Simon Glass0157b182022-01-29 14:14:11 -0700262 count, msg = gitutil.count_commits_in_range(options.git_dir,
Simon Glass5abab202014-12-01 17:33:57 -0700263 options.branch)
264 else:
Simon Glass0157b182022-01-29 14:14:11 -0700265 count, msg = gitutil.count_commits_in_branch(options.git_dir,
Simon Glass5abab202014-12-01 17:33:57 -0700266 options.branch)
Simon Glassfea58582014-08-09 15:32:59 -0600267 if count is None:
Simon Glass252ac582022-01-29 14:14:17 -0700268 sys.exit(col.build(col.RED, msg))
Simon Glass5abab202014-12-01 17:33:57 -0700269 elif count == 0:
Simon Glass252ac582022-01-29 14:14:17 -0700270 sys.exit(col.build(col.RED, "Range '%s' has no commits" %
Simon Glass5abab202014-12-01 17:33:57 -0700271 options.branch))
Simon Glass2a9e2c62014-12-01 17:33:54 -0700272 if msg:
Simon Glass252ac582022-01-29 14:14:17 -0700273 print(col.build(col.YELLOW, msg))
Simon Glassfea58582014-08-09 15:32:59 -0600274 count += 1 # Build upstream commit also
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000275
276 if not count:
Simon Glass8dd7be72023-02-23 18:18:11 -0700277 msg = ("No commits found to process in branch '%s': "
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000278 "set branch's upstream or use -c flag" % options.branch)
Simon Glass8dd7be72023-02-23 18:18:11 -0700279 sys.exit(col.build(col.RED, msg))
Simon Glassd829f122020-03-18 09:42:42 -0600280 if options.work_in_output:
281 if len(selected) != 1:
Simon Glass252ac582022-01-29 14:14:17 -0700282 sys.exit(col.build(col.RED,
Simon Glassd829f122020-03-18 09:42:42 -0600283 '-w can only be used with a single board'))
284 if count != 1:
Simon Glass252ac582022-01-29 14:14:17 -0700285 sys.exit(col.build(col.RED,
Simon Glassd829f122020-03-18 09:42:42 -0600286 '-w can only be used with a single commit'))
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000287
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000288 # Read the metadata from the commits. First look at the upstream commit,
289 # then the ones in the branch. We would like to do something like
290 # upstream/master~..branch but that isn't possible if upstream/master is
291 # a merge commit (it will list all the commits that form part of the
292 # merge)
Simon Glass950a2312014-09-05 19:00:23 -0600293 # Conflicting tags are not a problem for buildman, since it does not use
294 # them. For example, Series-version is not useful for buildman. On the
295 # other hand conflicting tags will cause an error. So allow later tags
296 # to overwrite earlier ones by setting allow_overwrite=True
Simon Glassfea58582014-08-09 15:32:59 -0600297 if options.branch:
Simon Glass3b74ba52014-08-09 15:33:09 -0600298 if count == -1:
Simon Glass5abab202014-12-01 17:33:57 -0700299 if has_range:
300 range_expr = options.branch
301 else:
Simon Glass0157b182022-01-29 14:14:11 -0700302 range_expr = gitutil.get_range_in_branch(options.git_dir,
Simon Glass5abab202014-12-01 17:33:57 -0700303 options.branch)
Simon Glass0157b182022-01-29 14:14:11 -0700304 upstream_commit = gitutil.get_upstream(options.git_dir,
Simon Glass3b74ba52014-08-09 15:33:09 -0600305 options.branch)
Simon Glassd93720e2020-10-29 21:46:19 -0600306 series = patchstream.get_metadata_for_list(upstream_commit,
Simon Glass950a2312014-09-05 19:00:23 -0600307 options.git_dir, 1, series=None, allow_overwrite=True)
Simon Glassfea58582014-08-09 15:32:59 -0600308
Simon Glassd93720e2020-10-29 21:46:19 -0600309 series = patchstream.get_metadata_for_list(range_expr,
Simon Glass950a2312014-09-05 19:00:23 -0600310 options.git_dir, None, series, allow_overwrite=True)
Simon Glass3b74ba52014-08-09 15:33:09 -0600311 else:
312 # Honour the count
Simon Glassd93720e2020-10-29 21:46:19 -0600313 series = patchstream.get_metadata_for_list(options.branch,
Simon Glass950a2312014-09-05 19:00:23 -0600314 options.git_dir, count, series=None, allow_overwrite=True)
Simon Glassfea58582014-08-09 15:32:59 -0600315 else:
316 series = None
Simon Glass8d7523c2017-01-23 05:38:56 -0700317 if not options.dry_run:
318 options.verbose = True
319 if not options.summary:
320 options.show_errors = True
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000321
322 # By default we have one thread per CPU. But if there are not enough jobs
323 # we can have fewer threads and use a high '-j' value for make.
Simon Glassb82492b2021-01-30 22:17:46 -0700324 if options.threads is None:
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000325 options.threads = min(multiprocessing.cpu_count(), len(selected))
326 if not options.jobs:
327 options.jobs = max(1, (multiprocessing.cpu_count() +
Simon Glassc05aa032019-10-31 07:42:53 -0600328 len(selected) - 1) // len(selected))
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000329
330 if not options.step:
331 options.step = len(series.commits) - 1
332
Simon Glassd9800692022-01-29 14:14:05 -0700333 gnu_make = command.output(os.path.join(options.git,
Simon Glass785f1542016-07-25 18:59:00 -0600334 'scripts/show-gnu-make'), raise_on_error=False).rstrip()
Masahiro Yamada99796922014-07-22 11:19:09 +0900335 if not gnu_make:
Masahiro Yamada31e21412014-08-16 00:59:26 +0900336 sys.exit('GNU Make not found')
Masahiro Yamada99796922014-07-22 11:19:09 +0900337
Tom Rinid7713ad2022-11-09 19:14:53 -0700338 allow_missing = get_allow_missing(options.allow_missing,
339 options.no_allow_missing, len(selected),
340 options.branch)
341
Simon Glass05c96b12014-12-01 17:33:52 -0700342 # Create a new builder with the selected options.
343 output_dir = options.output_dir
Simon Glassfea58582014-08-09 15:32:59 -0600344 if options.branch:
Simon Glassf7582ce2014-09-05 19:00:22 -0600345 dirname = options.branch.replace('/', '_')
Simon Glass5971ab52014-12-01 17:33:55 -0700346 # As a special case allow the board directory to be placed in the
347 # output directory itself rather than any subdirectory.
348 if not options.no_subdirs:
349 output_dir = os.path.join(options.output_dir, dirname)
Lothar Waßmann409fc022018-04-08 05:14:11 -0600350 if clean_dir and os.path.exists(output_dir):
351 shutil.rmtree(output_dir)
Simon Glass2b4806e2022-01-22 05:07:33 -0700352 adjust_cfg = cfgutil.convert_list_to_dict(options.adjust_cfg)
353
Simon Glassbfb708a2023-02-21 12:40:29 -0700354 # Drop LOCALVERSION_AUTO since it changes the version string on every commit
355 if options.reproducible_builds:
356 # If these are mentioned, leave the local version alone
357 if 'LOCALVERSION' in adjust_cfg or 'LOCALVERSION_AUTO' in adjust_cfg:
358 print('Not dropping LOCALVERSION_AUTO for reproducible build')
359 else:
360 adjust_cfg['LOCALVERSION_AUTO'] = '~'
361
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000362 builder = Builder(toolchains, output_dir, options.git_dir,
Masahiro Yamada99796922014-07-22 11:19:09 +0900363 options.threads, options.jobs, gnu_make=gnu_make, checkout=True,
Simon Glass5971ab52014-12-01 17:33:55 -0700364 show_unknown=options.show_unknown, step=options.step,
Simon Glassd2ce6582014-12-01 17:34:07 -0700365 no_subdirs=options.no_subdirs, full_path=options.full_path,
Stephen Warrenf79f1e02016-04-11 10:48:44 -0600366 verbose_build=options.verbose_build,
Simon Glasseb70a2c2020-04-09 15:08:51 -0600367 mrproper=options.mrproper,
Simon Glassb50113f2016-11-13 14:25:51 -0700368 per_board_out_dir=options.per_board_out_dir,
Simon Glassb464f8e2016-11-13 14:25:53 -0700369 config_only=options.config_only,
Daniel Schwierzeck2371d1b2018-01-26 16:31:05 +0100370 squash_config_y=not options.preserve_config_y,
Simon Glassd829f122020-03-18 09:42:42 -0600371 warnings_as_errors=options.warnings_as_errors,
Simon Glass8116c782021-04-11 16:27:27 +1200372 work_in_output=options.work_in_output,
Simon Glass2b4806e2022-01-22 05:07:33 -0700373 test_thread_exceptions=test_thread_exceptions,
Tom Rinid7713ad2022-11-09 19:14:53 -0700374 adjust_cfg=adjust_cfg,
Simon Glassbfb708a2023-02-21 12:40:29 -0700375 allow_missing=allow_missing, no_lto=options.no_lto,
376 reproducible_builds=options.reproducible_builds)
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000377 builder.force_config_on_failure = not options.quick
Simon Glassd4144e42014-09-05 19:00:13 -0600378 if make_func:
379 builder.do_make = make_func
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000380
381 # For a dry run, just show our actions as a sanity check
382 if options.dry_run:
Simon Glass06890362018-06-11 23:26:46 -0600383 ShowActions(series, why_selected, selected, builder, options,
384 board_warnings)
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000385 else:
386 builder.force_build = options.force_build
Simon Glass4266dc22014-07-13 12:22:31 -0600387 builder.force_build_failures = options.force_build_failures
Simon Glass97e91522014-07-14 17:51:02 -0600388 builder.force_reconfig = options.force_reconfig
Simon Glass189a4962014-07-14 17:51:03 -0600389 builder.in_tree = options.in_tree
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000390
391 # Work out which boards to build
Simon Glass6014db62022-07-11 19:04:02 -0600392 board_selected = brds.get_selected_dict()
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000393
Simon Glassfea58582014-08-09 15:32:59 -0600394 if series:
395 commits = series.commits
Simon Glass883a3212014-09-05 19:00:18 -0600396 # Number the commits for test purposes
397 for commit in range(len(commits)):
398 commits[commit].sequence = commit
Simon Glassfea58582014-08-09 15:32:59 -0600399 else:
400 commits = None
401
Simon Glassae1a09f2022-07-11 19:03:56 -0600402 if not options.ide:
403 tprint(GetActionSummary(options.summary, commits, board_selected,
404 options))
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000405
Simon Glass7798e222014-09-14 20:23:16 -0600406 # We can't show function sizes without board details at present
407 if options.show_bloat:
408 options.show_detail = True
Simon Glass174592b2020-04-09 15:08:52 -0600409 builder.SetDisplayOptions(
410 options.show_errors, options.show_sizes, options.show_detail,
411 options.show_bloat, options.list_error_boards, options.show_config,
Simon Glass113a8a52020-04-09 15:08:53 -0600412 options.show_environment, options.filter_dtb_warnings,
Simon Glassae1a09f2022-07-11 19:03:56 -0600413 options.filter_migration_warnings, options.ide)
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000414 if options.summary:
Simon Glassb2ea7ab2014-08-09 15:33:02 -0600415 builder.ShowSummary(commits, board_selected)
Simon Glassfc3fe1c2013-04-03 11:07:16 +0000416 else:
Simon Glass8116c782021-04-11 16:27:27 +1200417 fail, warned, excs = builder.BuildBoards(
418 commits, board_selected, options.keep_outputs, options.verbose)
419 if excs:
420 return 102
421 elif fail:
Simon Glassb1e5e6d2020-04-09 10:49:45 -0600422 return 100
Simon Glass7beb43c2020-03-18 09:42:44 -0600423 elif warned and not options.ignore_warnings:
Simon Glassb1e5e6d2020-04-09 10:49:45 -0600424 return 101
Simon Glass2c3deb92014-08-28 09:43:39 -0600425 return 0