blob: aacfb2fc0db0eec843afbb8f0c2fe770e195bbe8 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001# SPDX-License-Identifier: GPL-2.0+
Simon Glassc05694f2013-04-03 11:07:16 +00002# Copyright (c) 2013 The Chromium OS Authors.
3#
Simon Glassc05694f2013-04-03 11:07:16 +00004
5import multiprocessing
6import os
Simon Glassa10ebe12014-09-05 19:00:18 -06007import shutil
Simon Glassf0d9c102020-04-17 18:09:02 -06008import subprocess
Simon Glassc05694f2013-04-03 11:07:16 +00009import sys
10
Simon Glass20751d62022-07-11 19:04:03 -060011from buildman import boards
Simon Glassf0d9c102020-04-17 18:09:02 -060012from buildman import bsettings
Simon Glasse5650a82022-01-22 05:07:33 -070013from buildman import cfgutil
Simon Glassf0d9c102020-04-17 18:09:02 -060014from buildman import toolchain
15from buildman.builder import Builder
Simon Glassa997ea52020-04-17 18:09:04 -060016from patman import gitutil
17from patman import patchstream
Simon Glass131444f2023-02-23 18:18:04 -070018from u_boot_pylib import command
19from u_boot_pylib import terminal
20from u_boot_pylib import tools
21from u_boot_pylib.terminal import tprint
Simon Glassc05694f2013-04-03 11:07:16 +000022
23def GetPlural(count):
24 """Returns a plural 's' if count is not 1"""
25 return 's' if count != 1 else ''
26
Simon Glassd326ad72014-08-09 15:32:59 -060027def GetActionSummary(is_summary, commits, selected, options):
Simon Glassc05694f2013-04-03 11:07:16 +000028 """Return a string summarising the intended action.
29
30 Returns:
31 Summary string.
32 """
Simon Glassd326ad72014-08-09 15:32:59 -060033 if commits:
34 count = len(commits)
Simon Glassc78ed662019-10-31 07:42:53 -060035 count = (count + options.step - 1) // options.step
Simon Glassd326ad72014-08-09 15:32:59 -060036 commit_str = '%d commit%s' % (count, GetPlural(count))
37 else:
38 commit_str = 'current source'
39 str = '%s %s for %d boards' % (
40 'Summary of' if is_summary else 'Building', commit_str,
Simon Glassc05694f2013-04-03 11:07:16 +000041 len(selected))
42 str += ' (%d thread%s, %d job%s per thread)' % (options.threads,
43 GetPlural(options.threads), options.jobs, GetPlural(options.jobs))
44 return str
45
Simon Glassd9eb9f02018-06-11 23:26:46 -060046def ShowActions(series, why_selected, boards_selected, builder, options,
47 board_warnings):
Simon Glassc05694f2013-04-03 11:07:16 +000048 """Display a list of actions that we would take, if not a dry run.
49
50 Args:
51 series: Series object
52 why_selected: Dictionary where each key is a buildman argument
Simon Glass6af145f2017-01-23 05:38:56 -070053 provided by the user, and the value is the list of boards
54 brought in by that argument. For example, 'arm' might bring
55 in 400 boards, so in this case the key would be 'arm' and
Simon Glassc05694f2013-04-03 11:07:16 +000056 the value would be a list of board names.
57 boards_selected: Dict of selected boards, key is target name,
58 value is Board object
59 builder: The builder that will be used to build the commits
60 options: Command line options object
Simon Glassd9eb9f02018-06-11 23:26:46 -060061 board_warnings: List of warnings obtained from board selected
Simon Glassc05694f2013-04-03 11:07:16 +000062 """
63 col = terminal.Color()
Simon Glassc78ed662019-10-31 07:42:53 -060064 print('Dry run, so not doing much. But I would do this:')
65 print()
Simon Glassd326ad72014-08-09 15:32:59 -060066 if series:
67 commits = series.commits
68 else:
69 commits = None
Simon Glassc78ed662019-10-31 07:42:53 -060070 print(GetActionSummary(False, commits, boards_selected,
71 options))
72 print('Build directory: %s' % builder.base_dir)
Simon Glassd326ad72014-08-09 15:32:59 -060073 if commits:
74 for upto in range(0, len(series.commits), options.step):
75 commit = series.commits[upto]
Simon Glassf45d3742022-01-29 14:14:17 -070076 print(' ', col.build(col.YELLOW, commit.hash[:8], bright=False), end=' ')
Simon Glassc78ed662019-10-31 07:42:53 -060077 print(commit.subject)
78 print()
Simon Glassc05694f2013-04-03 11:07:16 +000079 for arg in why_selected:
80 if arg != 'all':
Simon Glassc78ed662019-10-31 07:42:53 -060081 print(arg, ': %d boards' % len(why_selected[arg]))
Simon Glass6af145f2017-01-23 05:38:56 -070082 if options.verbose:
Simon Glassc78ed662019-10-31 07:42:53 -060083 print(' %s' % ' '.join(why_selected[arg]))
84 print(('Total boards to build for each commit: %d\n' %
85 len(why_selected['all'])))
Simon Glassd9eb9f02018-06-11 23:26:46 -060086 if board_warnings:
87 for warning in board_warnings:
Simon Glassf45d3742022-01-29 14:14:17 -070088 print(col.build(col.YELLOW, warning))
Simon Glassc05694f2013-04-03 11:07:16 +000089
Simon Glass5df45222022-07-11 19:04:00 -060090def ShowToolchainPrefix(brds, toolchains):
Simon Glass48ac42e2019-12-05 15:59:14 -070091 """Show information about a the tool chain used by one or more boards
92
Simon Glass2df44be2020-03-18 09:42:47 -060093 The function checks that all boards use the same toolchain, then prints
94 the correct value for CROSS_COMPILE.
Simon Glass48ac42e2019-12-05 15:59:14 -070095
96 Args:
97 boards: Boards object containing selected boards
98 toolchains: Toolchains object containing available toolchains
Simon Glass48ac42e2019-12-05 15:59:14 -070099
100 Return:
101 None on success, string error message otherwise
102 """
Simon Glass127a2392022-07-11 19:04:02 -0600103 board_selected = brds.get_selected_dict()
Simon Glass48ac42e2019-12-05 15:59:14 -0700104 tc_set = set()
Simon Glass5df45222022-07-11 19:04:00 -0600105 for brd in board_selected.values():
Simon Glass48ac42e2019-12-05 15:59:14 -0700106 tc_set.add(toolchains.Select(brd.arch))
107 if len(tc_set) != 1:
108 return 'Supplied boards must share one toolchain'
109 return False
110 tc = tc_set.pop()
Simon Glass2df44be2020-03-18 09:42:47 -0600111 print(tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE))
Simon Glass48ac42e2019-12-05 15:59:14 -0700112 return None
113
Tom Rini93ebd462022-11-09 19:14:53 -0700114def get_allow_missing(opt_allow, opt_no_allow, num_selected, has_branch):
115 allow_missing = False
116 am_setting = bsettings.GetGlobalItemValue('allow-missing')
117 if am_setting:
118 if am_setting == 'always':
119 allow_missing = True
120 if 'multiple' in am_setting and num_selected > 1:
121 allow_missing = True
122 if 'branch' in am_setting and has_branch:
123 allow_missing = True
124
125 if opt_allow:
126 allow_missing = True
127 if opt_no_allow:
128 allow_missing = False
129 return allow_missing
130
Simon Glass5df45222022-07-11 19:04:00 -0600131def DoBuildman(options, args, toolchains=None, make_func=None, brds=None,
Simon Glass9bf9a722021-04-11 16:27:27 +1200132 clean_dir=False, test_thread_exceptions=False):
Simon Glassc05694f2013-04-03 11:07:16 +0000133 """The main control code for buildman
134
135 Args:
136 options: Command line options object
137 args: Command line arguments (list of strings)
Simon Glassed098bb2014-09-05 19:00:13 -0600138 toolchains: Toolchains to use - this should be a Toolchains()
139 object. If None, then it will be created and scanned
140 make_func: Make function to use for the builder. This is called
141 to execute 'make'. If this is None, the normal function
142 will be used, which calls the 'make' tool with suitable
143 arguments. This setting is useful for tests.
Simon Glass5df45222022-07-11 19:04:00 -0600144 brds: Boards() object to use, containing a list of available
Simon Glasscbd36582014-09-05 19:00:16 -0600145 boards. If this is None it will be created and scanned.
Simon Glassa29b3ea2021-04-11 16:27:25 +1200146 clean_dir: Used for tests only, indicates that the existing output_dir
147 should be removed before starting the build
Simon Glass9bf9a722021-04-11 16:27:27 +1200148 test_thread_exceptions: Uses for tests only, True to make the threads
149 raise an exception instead of reporting their result. This simulates
150 a failure in the code somewhere
Simon Glassc05694f2013-04-03 11:07:16 +0000151 """
Simon Glassa10ebe12014-09-05 19:00:18 -0600152 global builder
153
Simon Glassca9b06e2014-09-05 19:00:11 -0600154 if options.full_help:
Simon Glass80025522022-01-29 14:14:04 -0700155 tools.print_full_help(
Simon Glass79cc9be2022-11-09 19:14:43 -0700156 os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])),
157 'README.rst'))
Simon Glassca9b06e2014-09-05 19:00:11 -0600158 return 0
159
Simon Glass761648b2022-01-29 14:14:11 -0700160 gitutil.setup()
Simon Glass9f1ba0f2016-07-27 20:33:02 -0600161 col = terminal.Color()
Simon Glassc05694f2013-04-03 11:07:16 +0000162
Simon Glassc05694f2013-04-03 11:07:16 +0000163 options.git_dir = os.path.join(options.git, '.git')
164
Simon Glassa3d9b4f2016-07-27 20:33:04 -0600165 no_toolchains = toolchains is None
166 if no_toolchains:
Simon Glassf77ca5b2019-01-07 16:44:20 -0700167 toolchains = toolchain.Toolchains(options.override_toolchain)
Simon Glassc05694f2013-04-03 11:07:16 +0000168
Simon Glass7e803e12014-12-01 17:34:06 -0700169 if options.fetch_arch:
170 if options.fetch_arch == 'list':
171 sorted_list = toolchains.ListArchs()
Simon Glassf45d3742022-01-29 14:14:17 -0700172 print(col.build(col.BLUE, 'Available architectures: %s\n' %
Simon Glassc78ed662019-10-31 07:42:53 -0600173 ' '.join(sorted_list)))
Simon Glass7e803e12014-12-01 17:34:06 -0700174 return 0
175 else:
176 fetch_arch = options.fetch_arch
177 if fetch_arch == 'all':
178 fetch_arch = ','.join(toolchains.ListArchs())
Simon Glassf45d3742022-01-29 14:14:17 -0700179 print(col.build(col.CYAN, '\nDownloading toolchains: %s' %
Simon Glassc78ed662019-10-31 07:42:53 -0600180 fetch_arch))
Simon Glass7e803e12014-12-01 17:34:06 -0700181 for arch in fetch_arch.split(','):
Simon Glassc78ed662019-10-31 07:42:53 -0600182 print()
Simon Glass7e803e12014-12-01 17:34:06 -0700183 ret = toolchains.FetchAndInstall(arch)
184 if ret:
185 return ret
186 return 0
187
Simon Glassa3d9b4f2016-07-27 20:33:04 -0600188 if no_toolchains:
189 toolchains.GetSettings()
Simon Glass74579fc2018-11-06 16:02:10 -0700190 toolchains.Scan(options.list_tool_chains and options.verbose)
Simon Glassa3d9b4f2016-07-27 20:33:04 -0600191 if options.list_tool_chains:
192 toolchains.List()
Simon Glassc78ed662019-10-31 07:42:53 -0600193 print()
Simon Glassa3d9b4f2016-07-27 20:33:04 -0600194 return 0
195
Simon Glassd9c98632020-04-17 17:51:32 -0600196 if not options.output_dir:
197 if options.work_in_output:
Simon Glassf45d3742022-01-29 14:14:17 -0700198 sys.exit(col.build(col.RED, '-w requires that you specify -o'))
Simon Glassd9c98632020-04-17 17:51:32 -0600199 options.output_dir = '..'
Simon Glass6029af12020-04-09 15:08:51 -0600200
Simon Glassc05694f2013-04-03 11:07:16 +0000201 # Work out what subset of the boards we are building
Simon Glass5df45222022-07-11 19:04:00 -0600202 if not brds:
Tom Rini6ef6b3f2019-11-19 15:14:33 -0500203 if not os.path.exists(options.output_dir):
204 os.makedirs(options.output_dir)
Bin Meng0733e202019-10-28 07:24:59 -0700205 board_file = os.path.join(options.output_dir, 'boards.cfg')
Masahiro Yamadae9bc8d22014-07-30 14:08:22 +0900206
Simon Glass20751d62022-07-11 19:04:03 -0600207 brds = boards.Boards()
Simon Glassafbd2132022-07-11 19:04:08 -0600208 ok = brds.ensure_board_list(board_file,
209 options.threads or multiprocessing.cpu_count(),
210 force=options.regen_board_list,
211 quiet=not options.verbose)
Simon Glass0c477b72022-07-11 19:04:04 -0600212 if options.regen_board_list:
Simon Glassafbd2132022-07-11 19:04:08 -0600213 return 0 if ok else 2
Simon Glass127a2392022-07-11 19:04:02 -0600214 brds.read_boards(board_file)
Simon Glass924c73a2014-08-28 09:43:41 -0600215
216 exclude = []
217 if options.exclude:
218 for arg in options.exclude:
219 exclude += arg.split(',')
220
Simon Glassd9eb9f02018-06-11 23:26:46 -0600221 if options.boards:
222 requested_boards = []
223 for b in options.boards:
224 requested_boards += b.split(',')
225 else:
226 requested_boards = None
Simon Glass127a2392022-07-11 19:04:02 -0600227 why_selected, board_warnings = brds.select_boards(args, exclude,
228 requested_boards)
229 selected = brds.get_selected()
Simon Glassc05694f2013-04-03 11:07:16 +0000230 if not len(selected):
Simon Glassf45d3742022-01-29 14:14:17 -0700231 sys.exit(col.build(col.RED, 'No matching boards found'))
Simon Glassc05694f2013-04-03 11:07:16 +0000232
Simon Glass2df44be2020-03-18 09:42:47 -0600233 if options.print_prefix:
Simon Glass5df45222022-07-11 19:04:00 -0600234 err = ShowToolchainPrefix(brds, toolchains)
Simon Glass48ac42e2019-12-05 15:59:14 -0700235 if err:
Simon Glassf45d3742022-01-29 14:14:17 -0700236 sys.exit(col.build(col.RED, err))
Simon Glass48ac42e2019-12-05 15:59:14 -0700237 return 0
238
Simon Glass9b550912019-12-05 15:59:13 -0700239 # Work out how many commits to build. We want to build everything on the
240 # branch. We also build the upstream commit as a control so we can see
241 # problems introduced by the first commit on the branch.
242 count = options.count
243 has_range = options.branch and '..' in options.branch
244 if count == -1:
245 if not options.branch:
246 count = 1
247 else:
248 if has_range:
Simon Glass761648b2022-01-29 14:14:11 -0700249 count, msg = gitutil.count_commits_in_range(options.git_dir,
Simon Glass9b550912019-12-05 15:59:13 -0700250 options.branch)
251 else:
Simon Glass761648b2022-01-29 14:14:11 -0700252 count, msg = gitutil.count_commits_in_branch(options.git_dir,
Simon Glass9b550912019-12-05 15:59:13 -0700253 options.branch)
254 if count is None:
Simon Glassf45d3742022-01-29 14:14:17 -0700255 sys.exit(col.build(col.RED, msg))
Simon Glass9b550912019-12-05 15:59:13 -0700256 elif count == 0:
Simon Glassf45d3742022-01-29 14:14:17 -0700257 sys.exit(col.build(col.RED, "Range '%s' has no commits" %
Simon Glass9b550912019-12-05 15:59:13 -0700258 options.branch))
259 if msg:
Simon Glassf45d3742022-01-29 14:14:17 -0700260 print(col.build(col.YELLOW, msg))
Simon Glass9b550912019-12-05 15:59:13 -0700261 count += 1 # Build upstream commit also
262
263 if not count:
Simon Glassba666eb2023-02-23 18:18:11 -0700264 msg = ("No commits found to process in branch '%s': "
Simon Glass9b550912019-12-05 15:59:13 -0700265 "set branch's upstream or use -c flag" % options.branch)
Simon Glassba666eb2023-02-23 18:18:11 -0700266 sys.exit(col.build(col.RED, msg))
Simon Glassb6eb8cf2020-03-18 09:42:42 -0600267 if options.work_in_output:
268 if len(selected) != 1:
Simon Glassf45d3742022-01-29 14:14:17 -0700269 sys.exit(col.build(col.RED,
Simon Glassb6eb8cf2020-03-18 09:42:42 -0600270 '-w can only be used with a single board'))
271 if count != 1:
Simon Glassf45d3742022-01-29 14:14:17 -0700272 sys.exit(col.build(col.RED,
Simon Glassb6eb8cf2020-03-18 09:42:42 -0600273 '-w can only be used with a single commit'))
Simon Glass9b550912019-12-05 15:59:13 -0700274
Simon Glassc05694f2013-04-03 11:07:16 +0000275 # Read the metadata from the commits. First look at the upstream commit,
276 # then the ones in the branch. We would like to do something like
277 # upstream/master~..branch but that isn't possible if upstream/master is
278 # a merge commit (it will list all the commits that form part of the
279 # merge)
Simon Glass359b55a62014-09-05 19:00:23 -0600280 # Conflicting tags are not a problem for buildman, since it does not use
281 # them. For example, Series-version is not useful for buildman. On the
282 # other hand conflicting tags will cause an error. So allow later tags
283 # to overwrite earlier ones by setting allow_overwrite=True
Simon Glassd326ad72014-08-09 15:32:59 -0600284 if options.branch:
Simon Glass16a52882014-08-09 15:33:09 -0600285 if count == -1:
Simon Glass5eeef462014-12-01 17:33:57 -0700286 if has_range:
287 range_expr = options.branch
288 else:
Simon Glass761648b2022-01-29 14:14:11 -0700289 range_expr = gitutil.get_range_in_branch(options.git_dir,
Simon Glass5eeef462014-12-01 17:33:57 -0700290 options.branch)
Simon Glass761648b2022-01-29 14:14:11 -0700291 upstream_commit = gitutil.get_upstream(options.git_dir,
Simon Glass16a52882014-08-09 15:33:09 -0600292 options.branch)
Simon Glass93f61c02020-10-29 21:46:19 -0600293 series = patchstream.get_metadata_for_list(upstream_commit,
Simon Glass359b55a62014-09-05 19:00:23 -0600294 options.git_dir, 1, series=None, allow_overwrite=True)
Simon Glassd326ad72014-08-09 15:32:59 -0600295
Simon Glass93f61c02020-10-29 21:46:19 -0600296 series = patchstream.get_metadata_for_list(range_expr,
Simon Glass359b55a62014-09-05 19:00:23 -0600297 options.git_dir, None, series, allow_overwrite=True)
Simon Glass16a52882014-08-09 15:33:09 -0600298 else:
299 # Honour the count
Simon Glass93f61c02020-10-29 21:46:19 -0600300 series = patchstream.get_metadata_for_list(options.branch,
Simon Glass359b55a62014-09-05 19:00:23 -0600301 options.git_dir, count, series=None, allow_overwrite=True)
Simon Glassd326ad72014-08-09 15:32:59 -0600302 else:
303 series = None
Simon Glass6af145f2017-01-23 05:38:56 -0700304 if not options.dry_run:
305 options.verbose = True
306 if not options.summary:
307 options.show_errors = True
Simon Glassc05694f2013-04-03 11:07:16 +0000308
309 # By default we have one thread per CPU. But if there are not enough jobs
310 # we can have fewer threads and use a high '-j' value for make.
Simon Glassc635d892021-01-30 22:17:46 -0700311 if options.threads is None:
Simon Glassc05694f2013-04-03 11:07:16 +0000312 options.threads = min(multiprocessing.cpu_count(), len(selected))
313 if not options.jobs:
314 options.jobs = max(1, (multiprocessing.cpu_count() +
Simon Glassc78ed662019-10-31 07:42:53 -0600315 len(selected) - 1) // len(selected))
Simon Glassc05694f2013-04-03 11:07:16 +0000316
317 if not options.step:
318 options.step = len(series.commits) - 1
319
Simon Glass840be732022-01-29 14:14:05 -0700320 gnu_make = command.output(os.path.join(options.git,
Simon Glassc55e0562016-07-25 18:59:00 -0600321 'scripts/show-gnu-make'), raise_on_error=False).rstrip()
Masahiro Yamada1fe610d2014-07-22 11:19:09 +0900322 if not gnu_make:
Masahiro Yamada880828d2014-08-16 00:59:26 +0900323 sys.exit('GNU Make not found')
Masahiro Yamada1fe610d2014-07-22 11:19:09 +0900324
Tom Rini93ebd462022-11-09 19:14:53 -0700325 allow_missing = get_allow_missing(options.allow_missing,
326 options.no_allow_missing, len(selected),
327 options.branch)
328
Simon Glassdbc01c72014-12-01 17:33:52 -0700329 # Create a new builder with the selected options.
330 output_dir = options.output_dir
Simon Glassd326ad72014-08-09 15:32:59 -0600331 if options.branch:
Simon Glass4aeceb92014-09-05 19:00:22 -0600332 dirname = options.branch.replace('/', '_')
Simon Glasse87bde12014-12-01 17:33:55 -0700333 # As a special case allow the board directory to be placed in the
334 # output directory itself rather than any subdirectory.
335 if not options.no_subdirs:
336 output_dir = os.path.join(options.output_dir, dirname)
Lothar Waßmannce6df922018-04-08 05:14:11 -0600337 if clean_dir and os.path.exists(output_dir):
338 shutil.rmtree(output_dir)
Simon Glasse5650a82022-01-22 05:07:33 -0700339 adjust_cfg = cfgutil.convert_list_to_dict(options.adjust_cfg)
340
Simon Glass828d70d2023-02-21 12:40:29 -0700341 # Drop LOCALVERSION_AUTO since it changes the version string on every commit
342 if options.reproducible_builds:
343 # If these are mentioned, leave the local version alone
344 if 'LOCALVERSION' in adjust_cfg or 'LOCALVERSION_AUTO' in adjust_cfg:
345 print('Not dropping LOCALVERSION_AUTO for reproducible build')
346 else:
347 adjust_cfg['LOCALVERSION_AUTO'] = '~'
348
Simon Glassc05694f2013-04-03 11:07:16 +0000349 builder = Builder(toolchains, output_dir, options.git_dir,
Masahiro Yamada1fe610d2014-07-22 11:19:09 +0900350 options.threads, options.jobs, gnu_make=gnu_make, checkout=True,
Simon Glasse87bde12014-12-01 17:33:55 -0700351 show_unknown=options.show_unknown, step=options.step,
Simon Glass655b6102014-12-01 17:34:07 -0700352 no_subdirs=options.no_subdirs, full_path=options.full_path,
Stephen Warren97c96902016-04-11 10:48:44 -0600353 verbose_build=options.verbose_build,
Simon Glass6029af12020-04-09 15:08:51 -0600354 mrproper=options.mrproper,
Simon Glass739e8512016-11-13 14:25:51 -0700355 per_board_out_dir=options.per_board_out_dir,
Simon Glasscde5c302016-11-13 14:25:53 -0700356 config_only=options.config_only,
Daniel Schwierzeck20e2ea92018-01-26 16:31:05 +0100357 squash_config_y=not options.preserve_config_y,
Simon Glassb6eb8cf2020-03-18 09:42:42 -0600358 warnings_as_errors=options.warnings_as_errors,
Simon Glass9bf9a722021-04-11 16:27:27 +1200359 work_in_output=options.work_in_output,
Simon Glasse5650a82022-01-22 05:07:33 -0700360 test_thread_exceptions=test_thread_exceptions,
Tom Rini93ebd462022-11-09 19:14:53 -0700361 adjust_cfg=adjust_cfg,
Simon Glass828d70d2023-02-21 12:40:29 -0700362 allow_missing=allow_missing, no_lto=options.no_lto,
363 reproducible_builds=options.reproducible_builds)
Simon Glassc05694f2013-04-03 11:07:16 +0000364 builder.force_config_on_failure = not options.quick
Simon Glassed098bb2014-09-05 19:00:13 -0600365 if make_func:
366 builder.do_make = make_func
Simon Glassc05694f2013-04-03 11:07:16 +0000367
368 # For a dry run, just show our actions as a sanity check
369 if options.dry_run:
Simon Glassd9eb9f02018-06-11 23:26:46 -0600370 ShowActions(series, why_selected, selected, builder, options,
371 board_warnings)
Simon Glassc05694f2013-04-03 11:07:16 +0000372 else:
373 builder.force_build = options.force_build
Simon Glass7041c392014-07-13 12:22:31 -0600374 builder.force_build_failures = options.force_build_failures
Simon Glassf3018b7a2014-07-14 17:51:02 -0600375 builder.force_reconfig = options.force_reconfig
Simon Glass38df2e22014-07-14 17:51:03 -0600376 builder.in_tree = options.in_tree
Simon Glassc05694f2013-04-03 11:07:16 +0000377
378 # Work out which boards to build
Simon Glass127a2392022-07-11 19:04:02 -0600379 board_selected = brds.get_selected_dict()
Simon Glassc05694f2013-04-03 11:07:16 +0000380
Simon Glassd326ad72014-08-09 15:32:59 -0600381 if series:
382 commits = series.commits
Simon Glassa10ebe12014-09-05 19:00:18 -0600383 # Number the commits for test purposes
384 for commit in range(len(commits)):
385 commits[commit].sequence = commit
Simon Glassd326ad72014-08-09 15:32:59 -0600386 else:
387 commits = None
388
Simon Glass6c435622022-07-11 19:03:56 -0600389 if not options.ide:
390 tprint(GetActionSummary(options.summary, commits, board_selected,
391 options))
Simon Glassc05694f2013-04-03 11:07:16 +0000392
Simon Glass232d8502014-09-14 20:23:16 -0600393 # We can't show function sizes without board details at present
394 if options.show_bloat:
395 options.show_detail = True
Simon Glass9ea93812020-04-09 15:08:52 -0600396 builder.SetDisplayOptions(
397 options.show_errors, options.show_sizes, options.show_detail,
398 options.show_bloat, options.list_error_boards, options.show_config,
Simon Glassf4ebfba2020-04-09 15:08:53 -0600399 options.show_environment, options.filter_dtb_warnings,
Simon Glass6c435622022-07-11 19:03:56 -0600400 options.filter_migration_warnings, options.ide)
Simon Glassc05694f2013-04-03 11:07:16 +0000401 if options.summary:
Simon Glasseb48bbc2014-08-09 15:33:02 -0600402 builder.ShowSummary(commits, board_selected)
Simon Glassc05694f2013-04-03 11:07:16 +0000403 else:
Simon Glass9bf9a722021-04-11 16:27:27 +1200404 fail, warned, excs = builder.BuildBoards(
405 commits, board_selected, options.keep_outputs, options.verbose)
406 if excs:
407 return 102
408 elif fail:
Simon Glasse4cd5062020-04-09 10:49:45 -0600409 return 100
Simon Glass35e7d382020-03-18 09:42:44 -0600410 elif warned and not options.ignore_warnings:
Simon Glasse4cd5062020-04-09 10:49:45 -0600411 return 101
Simon Glassc2f91072014-08-28 09:43:39 -0600412 return 0