blob: bdeae85c03c56cc6892cb0fed690c271fe930fcc [file] [log] [blame]
Diana Picus3b2ef822016-10-13 16:53:18 +03001"""This is the main tool for handling llvm builds, bisects etc."""
2
3import os
Diana Picusadb07c42017-11-22 16:12:57 +01004from sys import argv
Diana Picus3b2ef822016-10-13 16:53:18 +03005from sys import exit
6
Diana Picus052b7d32017-11-24 16:19:41 +01007from modules.llvm import LLVMBuildConfig
Diana Picus95226d42017-11-01 13:16:54 +01008from modules.llvm import LLVMSubproject
9from modules.llvm import LLVMSourceConfig
Diana Picusb368cb62018-01-23 16:41:59 +010010from modules.llvm import run_test_suite
Diana Picusf73abbf2018-01-26 07:06:20 +010011from modules.llvm import setup_test_suite
Diana Picus052b7d32017-11-24 16:19:41 +010012from modules.utils import CommandPrinter
13from modules.utils import CommandRunner
Diana Picus5ad55422017-12-14 17:57:10 +010014from modules.utils import get_remote_branch
15from modules.utils import push_branch
Diana Picus95226d42017-11-01 13:16:54 +010016
Diana Picus052b7d32017-11-24 16:19:41 +010017from linaropy.cd import cd
Diana Picus3b2ef822016-10-13 16:53:18 +030018from linaropy.git.clone import Clone
19from linaropy.proj import Proj
20
21from argparse import Action, ArgumentParser, RawTextHelpFormatter
Diana Picusefc7bda2017-06-09 19:14:08 +020022from functools import partial
Diana Picus3b2ef822016-10-13 16:53:18 +030023
24
25def die(message, config_to_dump=None):
26 """Print an error message and exit."""
Diana Picusb4307602017-04-05 19:48:39 +020027 print(message)
Diana Picus3b2ef822016-10-13 16:53:18 +030028
29 if config_to_dump is not None:
30 dump_config(config_to_dump)
31
32 exit(1)
33
Diana Picus3d1a3012017-03-14 17:38:32 +010034
Diana Picus3b2ef822016-10-13 16:53:18 +030035def dump_config(config):
36 """Dump the list of projects that are enabled in the given config."""
37
Diana Picusb4307602017-04-05 19:48:39 +020038 print("Projects linked:")
Diana Picus3b2ef822016-10-13 16:53:18 +030039 enabled = config.get_enabled_subprojects()
40 if not enabled:
Diana Picusb4307602017-04-05 19:48:39 +020041 print("none")
Diana Picus3b2ef822016-10-13 16:53:18 +030042 else:
43 for subproj in sorted(enabled):
Diana Picusb4307602017-04-05 19:48:39 +020044 print(" + {}".format(subproj))
Diana Picus3b2ef822016-10-13 16:53:18 +030045
46
Diana Picus2c580832018-02-14 14:51:00 +010047def subproj_to_repo_map(subprojs, proj, reposRoot, dry=False):
48 """Get a dictionary mapping each subproject in subprojs to its repo."""
49 subprojsToRepos = {}
50 repo = None
51 for subproj in subprojs:
52 if not dry:
53 repo = Clone(proj, os.path.join(reposRoot, subproj))
54 subprojsToRepos[subproj] = repo
55
56 return subprojsToRepos
57
58
Diana Picus3b2ef822016-10-13 16:53:18 +030059def projects(args):
60 """Add/remove subprojects based on the values in args."""
61
62 proj = Proj()
Diana Picus3d1a3012017-03-14 17:38:32 +010063
Diana Picus9f756862017-12-20 10:35:08 +010064 llvm_worktree_root = args.sources
Diana Picus81089db2017-05-05 22:26:49 +020065 llvm_repos_root = args.repos
Diana Picusb1dbcba2018-02-07 01:33:17 +010066 config = LLVMSourceConfig(proj, llvm_worktree_root, dry=False)
Diana Picus3b2ef822016-10-13 16:53:18 +030067
68 if not args.add and not args.remove:
69 # Nothing to change, just print the current configuration
70 dump_config(config)
71 exit(0)
72
73 to_add = {}
74 if args.add:
Diana Picus2c580832018-02-14 14:51:00 +010075 to_add = subproj_to_repo_map(args.add, proj, llvm_repos_root)
Diana Picus3b2ef822016-10-13 16:53:18 +030076
77 try:
78 config.update(to_add, args.remove)
79 except (EnvironmentError, ValueError) as exc:
80 die("Failed to update subprojects because:\n{}".format(str(exc)))
81
82 dump_config(config)
83
Diana Picusefc7bda2017-06-09 19:14:08 +020084
Diana Picus95226d42017-11-01 13:16:54 +010085def push_current_branch(args):
Diana Picusefc7bda2017-06-09 19:14:08 +020086 """Push current branch to origin."""
87
88 proj = Proj()
89
Diana Picus9f756862017-12-20 10:35:08 +010090 llvm_worktree_root = args.sources
Diana Picusb1dbcba2018-02-07 01:33:17 +010091 config = LLVMSourceConfig(proj, llvm_worktree_root, dry=False)
Diana Picusefc7bda2017-06-09 19:14:08 +020092
Diana Picus95226d42017-11-01 13:16:54 +010093 llvm_worktree = Clone(proj, llvm_worktree_root)
94 local_branch = llvm_worktree.getbranch()
Diana Picusefc7bda2017-06-09 19:14:08 +020095
96 try:
Diana Picus95226d42017-11-01 13:16:54 +010097 remote_branch = get_remote_branch(llvm_worktree, local_branch)
98 config.for_each_enabled(partial(push_branch, proj, local_branch,
99 remote_branch))
100 print("Pushed to {}".format(remote_branch))
101 except (EnvironmentError, RuntimeError) as exc:
Diana Picusefc7bda2017-06-09 19:14:08 +0200102 die("Failed to push branch because: " + str(exc) + str(exc.__cause__))
103
Diana Picus95226d42017-11-01 13:16:54 +0100104
Diana Picus2c580832018-02-14 14:51:00 +0100105def cmake_flags_from_args(defs):
106 """
107 Get a list of valid CMake flags from the input VAR=VALUE list.
108 This boils down to just adding -D in front of each of them.
109 """
110 return ["-D{}".format(v) for v in defs]
111
112
Diana Picus052b7d32017-11-24 16:19:41 +0100113def configure_build(args):
114 """Configure a given build directory."""
115
116 proj = Proj()
117
Diana Picus9f756862017-12-20 10:35:08 +0100118 llvm_worktree_root = args.sources
Diana Picusb1dbcba2018-02-07 01:33:17 +0100119 sourceConfig = LLVMSourceConfig(proj, llvm_worktree_root, args.dry)
Diana Picus052b7d32017-11-24 16:19:41 +0100120
Diana Picus052b7d32017-11-24 16:19:41 +0100121 if args.dry:
122 consumer = CommandPrinter()
123 else:
124 if not os.path.exists(args.build):
125 os.makedirs(args.build)
126 consumer = CommandRunner()
127
Diana Picus6b1935f2018-02-07 16:44:11 +0100128 buildConfig = LLVMBuildConfig(sourceConfig, args.build, consumer)
129
130 if args.defs:
Diana Picus2c580832018-02-14 14:51:00 +0100131 args.defs = cmake_flags_from_args(args.defs)
Diana Picus6b1935f2018-02-07 16:44:11 +0100132
Diana Picus052b7d32017-11-24 16:19:41 +0100133 try:
Diana Picus6b1935f2018-02-07 16:44:11 +0100134 buildConfig.cmake(args.defs, args.generator)
Diana Picus052b7d32017-11-24 16:19:41 +0100135 except RuntimeError as exc:
136 die("Failed to configure {} because:\n{}".format(args.build, str(exc)))
137
138
Diana Picus37126b82018-01-19 16:14:26 +0100139def run_build(args):
140 """Run a build command in a given directory."""
141 build_dir = args.build
142
143 if args.dry:
144 consumer = CommandPrinter()
145 else:
146 consumer = CommandRunner()
147
148 try:
Diana Picus6b1935f2018-02-07 16:44:11 +0100149 LLVMBuildConfig(None, args.build, consumer).build(args.flags)
Diana Picus37126b82018-01-19 16:14:26 +0100150 except RuntimeError as exc:
151 die("Failed to build {} because:\n{}".format(args.build, str(exc)))
152
153
Diana Picusf73abbf2018-01-26 07:06:20 +0100154def setup_the_test_suite(args):
155 """Setup a sandbox for the test-suite."""
156 if args.dry:
157 consumer = CommandPrinter()
158 else:
159 consumer = CommandRunner()
160
161 try:
162 setup_test_suite(consumer, args.sandbox, args.lnt)
163 except RuntimeError as exc:
164 die("Failed to setup the test-suite because:\n{}".format(str(exc)))
165
166
Diana Picusb368cb62018-01-23 16:41:59 +0100167def run_the_test_suite(args):
168 """Run the test-suite in a given sandbox."""
169 if args.dry:
170 consumer = CommandPrinter()
171 else:
172 consumer = CommandRunner()
173
174 compilers = ["--cc={}".format(args.cc)]
175 if args.cxx:
176 compilers.append("--cxx={}".format(args.cxx))
177
178 try:
179 run_test_suite(consumer, args.sandbox, args.testsuite, args.lit,
180 compilers + args.flags)
181 except RuntimeError as exc:
182 die("Failed to run the test-suite because:\n{}".format(str(exc)))
183
Diana Picusb03e5082018-02-05 12:36:49 +0100184
185def build_and_test(args):
186 """
187 Build a set of LLVM subprojects, in one or two stages, with or without a
188 test-suite run.
189 """
190
191 proj = Proj()
192
193 dryRun = args.dry
Diana Picusfcfc6282018-02-14 18:50:24 +0100194 llvmRepos = args.repos
Diana Picusb03e5082018-02-05 12:36:49 +0100195 llvmWorktreeRoot = args.sources
196
197 stage1BuildDir = args.stage1
Diana Picus2c580832018-02-14 14:51:00 +0100198 stage1Subprojs = args.stage1Subprojs
199 stage1Defs = cmake_flags_from_args(args.stage1Defs)
200 stage1BuildFlags = args.stage1BuildFlags
201
Diana Picusb03e5082018-02-05 12:36:49 +0100202 stage2BuildDir = args.stage2
Diana Picus6cdb5162018-02-15 05:29:46 +0100203 stage2Subprojs = args.stage2Subprojs
204 stage2Defs = cmake_flags_from_args(args.stage2Defs)
205 stage2BuildFlags = args.stage2BuildFlags
Diana Picusfcfc6282018-02-14 18:50:24 +0100206
207 enableTestSuite = args.enableTestSuite
Diana Picusb03e5082018-02-05 12:36:49 +0100208 sandboxDir = args.sandbox
Diana Picusb03e5082018-02-05 12:36:49 +0100209
210 if dryRun:
211 consumer = CommandPrinter()
212 else:
213 consumer = CommandRunner()
214
215 try:
216 sourceConfig = LLVMSourceConfig(proj, llvmWorktreeRoot, args.dry)
Diana Picus2c580832018-02-14 14:51:00 +0100217 if stage1Subprojs:
218 # FIXME: Decide whether or not we want to remove anything that isn't
219 # in stage1Subprojs (in case there are already some enabled
220 # subprojects in the source config).
221 sourceConfig.update(
222 subproj_to_repo_map(stage1Subprojs, proj, llvmRepos,
223 args.dry),
224 [])
Diana Picusb03e5082018-02-05 12:36:49 +0100225
226 if not dryRun and not os.path.exists(stage1BuildDir):
227 os.makedirs(stage1BuildDir)
228
229 buildConfig1 = LLVMBuildConfig(sourceConfig, stage1BuildDir, consumer)
Diana Picus2c580832018-02-14 14:51:00 +0100230 buildConfig1.cmake(stage1Defs, "Ninja")
231 buildConfig1.build(stage1BuildFlags)
Diana Picusb03e5082018-02-05 12:36:49 +0100232 testedBuildDir = stage1BuildDir
233
234 if stage2BuildDir is not None:
Diana Picus6cdb5162018-02-15 05:29:46 +0100235 if stage2Subprojs:
236 toAdd = list(set(stage2Subprojs) - set(stage1Subprojs))
237 toRemove = list(set(stage1Subprojs) - set(stage2Subprojs))
238 sourceConfig.update(
239 subproj_to_repo_map(toAdd, proj, llvmRepos, args.dry),
240 toRemove)
241
Diana Picusb03e5082018-02-05 12:36:49 +0100242 if not dryRun and not os.path.exists(stage2BuildDir):
243 os.makedirs(stage2BuildDir)
244
245 buildConfig2 = LLVMBuildConfig(sourceConfig, stage2BuildDir,
246 consumer)
247
248 # TODO: Make sure clang is actually built in this config (preferably
249 # before reaching this point)
250 buildConfig2.cmake(
Diana Picus6cdb5162018-02-15 05:29:46 +0100251 stage2Defs + [
Diana Picusb03e5082018-02-05 12:36:49 +0100252 "-DCMAKE_C_COMPILER={}/bin/clang".format(stage1BuildDir),
253 "-DCMAKE_CXX_COMPILER={}/bin/clang++".format(stage1BuildDir)],
254 "Ninja")
Diana Picus6cdb5162018-02-15 05:29:46 +0100255 buildConfig2.build(stage2BuildFlags)
Diana Picusb03e5082018-02-05 12:36:49 +0100256 testedBuildDir = stage2BuildDir
257
Diana Picusfcfc6282018-02-14 18:50:24 +0100258 if enableTestSuite:
259 testSuiteDir = os.path.join(llvmRepos, "test-suite")
260 lntDir = os.path.join(llvmRepos, "lnt")
261
Diana Picusb03e5082018-02-05 12:36:49 +0100262 setup_test_suite(consumer, sandboxDir, lntDir)
263
264 # TODO: Make sure clang is actually built in this config (preferably
265 # before reaching this point)
266 lit = os.path.join(testedBuildDir, "bin", "llvm-lit")
267 clang = os.path.join(testedBuildDir, "bin", "clang")
268 run_test_suite(consumer, sandboxDir, testSuiteDir, lit,
269 ["--cc={}".format(clang)])
270
271 except RuntimeError as exc:
272 die("Failed because:\n{}".format(str(exc)))
273
274
Diana Picus3b2ef822016-10-13 16:53:18 +0300275##########################################################################
276# Command line parsing #
277##########################################################################
278
279# If we decide we want shorthands for the subprojects, we can append to this
280# list
Diana Picusb4307602017-04-05 19:48:39 +0200281valid_subprojects = list(LLVMSubproject.get_all_subprojects().keys())
Diana Picus3b2ef822016-10-13 16:53:18 +0300282
283options = ArgumentParser(formatter_class=RawTextHelpFormatter)
Diana Picusadb07c42017-11-22 16:12:57 +0100284subcommands = options.add_subparsers(dest="subcommand")
Diana Picus3b2ef822016-10-13 16:53:18 +0300285
286# Subcommand for adding / removing subprojects
Diana Picus36317e82017-10-31 15:35:24 +0100287projs = subcommands.add_parser(
288 "projects", help="Add/remove LLVM subprojects.\n"
289 "Adding a subproject will create a worktree for it "
290 "somewhere in the LLVM source tree, on the same git "
291 "branch as LLVM itself.\n"
292 "Removing a subproject will remove the worktree, but "
293 "not the underlying git branch.")
Diana Picus3b2ef822016-10-13 16:53:18 +0300294projs.set_defaults(run_command=projects)
295
296# TODO: Overwriting previous values is not necessarily what users expect (so for
297# instance --add S1 S2 --remove S3 --add S4 would lead to adding only S4). We
298# can do better by using action='append', which would create a list (of lists?
299# or of lists and scalars?) that we can flatten to obtain all the values passed
300# by the user.
301projs.add_argument(
302 '-a', '--add',
303 nargs='+',
304 choices=valid_subprojects,
305 metavar='subproject',
Diana Picus36317e82017-10-31 15:35:24 +0100306 help="Enable given subprojects. Valid values are:\n\t{}\n".format(
Diana Picus3b2ef822016-10-13 16:53:18 +0300307 "\n\t".join(valid_subprojects)))
308projs.add_argument(
309 '-r', '--remove',
310 nargs='+',
311 choices=valid_subprojects,
312 metavar='subproject',
Diana Picus36317e82017-10-31 15:35:24 +0100313 help="Disable given subprojects.")
Diana Picusadb07c42017-11-22 16:12:57 +0100314projs.add_argument(
315 '--repos',
316 help="Path to the directory containing the repositories for all LLVM "
317 "subprojects.")
Diana Picus9f756862017-12-20 10:35:08 +0100318projs.add_argument(
319 '--source-dir',
320 dest='sources',
321 required=True,
322 help="Path to the directory containing the LLVM worktree that we're adding "
323 "or removing subprojects from.")
Diana Picus3b2ef822016-10-13 16:53:18 +0300324
Diana Picusefc7bda2017-06-09 19:14:08 +0200325# Subcommand for pushing the current branch to origin
326push = subcommands.add_parser(
327 "push",
Diana Picus36317e82017-10-31 15:35:24 +0100328 help="Push current branch to origin linaro-local/<user>/<branch>, "
329 "for all enabled subprojects.")
Diana Picus95226d42017-11-01 13:16:54 +0100330push.set_defaults(run_command=push_current_branch)
Diana Picus9f756862017-12-20 10:35:08 +0100331push.add_argument(
332 '--source-dir',
333 dest='sources',
334 required=True,
335 help="Path to the directory containing the LLVM worktree.")
Diana Picusefc7bda2017-06-09 19:14:08 +0200336
Diana Picus052b7d32017-11-24 16:19:41 +0100337# Subcommand for configuring a build directory
338configure = subcommands.add_parser(
339 'configure',
340 help="Run CMake in the given build directory.")
341configure.add_argument(
Diana Picus9f756862017-12-20 10:35:08 +0100342 '--source-dir',
343 dest='sources',
344 required=True,
345 help="Path to the sources directory. It should contain an LLVM worktree.")
346configure.add_argument(
Diana Picus052b7d32017-11-24 16:19:41 +0100347 '--build-dir',
348 dest='build',
349 required=True,
350 help="Path to the build directory. It will be created if it does not exist")
351configure.add_argument(
352 '--cmake-generator',
353 dest='generator',
354 default='Ninja',
355 help="CMake generator to use (default is Ninja).")
356configure.add_argument(
357 '--cmake-def',
358 dest='defs',
359 metavar='VAR=VALUE',
360 default=[],
361 action='append',
362 # We add the -D in front of the variable ourselves because the argument
363 # parsing gets confused otherwise (and quoting doesn't help).
364 help="Additional CMake definitions, e.g. CMAKE_BUILD_TYPE=Release."
365 "May be passed several times. The -D is added automatically.")
366configure.add_argument(
367 '-n', '--dry-run',
368 dest='dry',
369 action='store_true',
370 default=False,
371 help="Print the CMake command instead of executing it.")
372configure.set_defaults(run_command=configure_build)
373
Diana Picus37126b82018-01-19 16:14:26 +0100374# Subcommand for building a target
375build = subcommands.add_parser(
376 'build',
377 help="Run a build command in the given directory."
378 "The build command can be either a 'ninja' or a 'make' command, depending "
379 "on what the build directory contains. First, we look for a 'build.ninja' "
380 "file. If that is not found, we look for a 'Makefile'. If that is not "
381 "found either, the script fails.")
382build.add_argument(
383 '--build-dir',
384 dest='build',
385 required=True,
386 help="Path to the build directory. It must have already been configured.")
387build.add_argument(
388 '-n', '--dry-run',
389 dest='dry',
390 action='store_true',
391 default=False,
392 help="Print the build command instead of executing it.")
393build.add_argument(
394 '--build-flag',
395 dest='flags',
396 metavar='FLAG',
397 default=[],
398 action='append',
399 help="Additional flags for the build command (e.g. targets to build). "
400 "May be passed several times. If your flag starts with a '-', use "
401 "'--build-flag=-FLAG' to pass it.")
402build.set_defaults(run_command=run_build)
403
Diana Picusf73abbf2018-01-26 07:06:20 +0100404# Subcommand for setting up the test-suite
405setupTestSuite = subcommands.add_parser(
406 'setup-test-suite',
407 help="Prepare a sandbox for running the test-suite.")
408setupTestSuite.add_argument(
409 '--sandbox',
410 required=True,
411 help="Path where we should setup the sandbox.")
412setupTestSuite.add_argument(
413 '--lnt',
414 required=True,
415 help="Path to the LNT sources.")
416setupTestSuite.add_argument(
417 '-n', '--dry-run',
418 dest='dry',
419 action='store_true',
420 default=False,
421 help="Print the commands instead of executing them.")
422setupTestSuite.set_defaults(run_command=setup_the_test_suite)
423
Diana Picusb368cb62018-01-23 16:41:59 +0100424# Subcommand for running the test-suite
425runTestSuite = subcommands.add_parser(
426 'run-test-suite',
427 help="Run the test-suite in the given sandbox.")
428runTestSuite.add_argument(
429 '--sandbox',
430 required=True,
431 help="Path to the sandbox. It must point to a virtualenv with a LNT setup.")
432runTestSuite.add_argument(
433 '--test-suite',
434 dest="testsuite",
435 required=True,
436 help="Path to the test-suite repo.")
437runTestSuite.add_argument(
438 '--use-lit',
439 dest="lit",
440 required=True,
441 help="Path to llvm-lit.")
442runTestSuite.add_argument(
443 '--lnt-flag',
444 dest='flags',
445 metavar='FLAG',
446 default=[],
447 action='append',
448 help="Additional flags to be passed to LNT when running the test-suite."
449 "May be passed several times. If your flag starts with a '-', use "
450 "'--lnt-flag=-FLAG' to pass it.")
451runTestSuite.add_argument(
452 # We can pass --cc through the --lnt-flag interface, but we generally won't
453 # want to test the system compiler, so force the user to be specific.
454 '--cc',
455 required=True,
456 help="The path to the C compiler that we're testing.")
457runTestSuite.add_argument(
458 # For symmetry, we also provide a --cxx argument, but this one isn't
459 # required since LNT tries to guess it based on the value of --cc.
460 '--cxx',
461 required=False,
462 help="The path to the C++ compiler that we're testing.")
463runTestSuite.add_argument(
464 '-n', '--dry-run',
465 dest='dry',
466 action='store_true',
467 default=False,
468 help="Print the commands instead of executing them.")
469runTestSuite.set_defaults(run_command=run_the_test_suite)
470
Diana Picusb03e5082018-02-05 12:36:49 +0100471buildAndTest = subcommands.add_parser(
472 'build-and-test', # TODO: This really needs a better name...
473 help="Run complex build scenarios with one or two stages of clang and "
474 "optionally a test-suite run. This should be flexible enough to allow "
475 "us to reproduce any buildbot configuration, but it can obviously be "
476 "used for other purposes as well.")
477buildAndTest.set_defaults(run_command=build_and_test)
478buildAndTest.add_argument(
Diana Picusfcfc6282018-02-14 18:50:24 +0100479 '--repos-dir',
480 dest='repos',
481 required=True,
482 help="Path to the root directory containing the repositories for LLVM and "
483 "the other subprojects.")
484buildAndTest.add_argument(
Diana Picusb03e5082018-02-05 12:36:49 +0100485 '--source-dir',
486 dest='sources',
487 required=True,
488 help="Path to the directory containing the LLVM worktree that we're going "
489 "to build from.")
490buildAndTest.add_argument(
491 '--stage1-build-dir',
492 dest='stage1',
493 required=True,
494 help="Path to the build directory for stage 1.")
495buildAndTest.add_argument(
Diana Picus2c580832018-02-14 14:51:00 +0100496 '--stage1-subproject',
497 dest='stage1Subprojs',
498 metavar='SUBPROJ',
499 choices=valid_subprojects,
500 default=[],
501 action='append',
502 help="Subprojects to enable for stage 1 of the build. Can be passed "
503 "multiple times. Valid values for the subproject are: {}. "
504 "If this is a 2-stage build, the same subprojects will be used for "
505 "both stages unless other subprojects are explicitly requested for "
506 "stage 2.".format(" ".join(valid_subprojects)))
507buildAndTest.add_argument(
508 '--stage1-cmake-def',
509 dest='stage1Defs',
510 metavar='VAR=VALUE',
511 default=[],
512 action='append',
513 help="Additional CMake definitions for stage 1, e.g. "
514 "CMAKE_BUILD_TYPE=Release. Can be passed multiple times. "
515 "The -D is added automatically. Does not affect stage 2.")
516buildAndTest.add_argument(
517 '--stage1-build-flag',
518 dest='stage1BuildFlags',
519 metavar='FLAG',
520 default=[],
521 action='append',
522 help="Additional flags for the stage 1 build command (e.g. targets to "
523 "build). Can be passed multiple times. If your flag starts with "
524 "a '-', use '--stage1-build-flag=-FLAG' to pass it. "
525 "Does not affect stage 2.")
526buildAndTest.add_argument(
Diana Picusb03e5082018-02-05 12:36:49 +0100527 '--stage2-build-dir',
528 dest='stage2',
529 help="Path to the build directory for stage 2.")
530buildAndTest.add_argument(
Diana Picus6cdb5162018-02-15 05:29:46 +0100531 '--stage2-subproject',
532 dest='stage2Subprojs',
533 metavar='SUBPROJ',
534 choices=valid_subprojects,
535 default=[],
536 action='append',
537 help="Subprojects to enable for stage 2 of the build. Can be passed "
538 "multiple times. Valid values for the subproject are: {}. "
539 "If this is a 2-stage build, the same subprojects will be used for "
540 "both stages unless other subprojects are explicitly requested for "
541 "stage 2.".format(" ".join(valid_subprojects)))
542buildAndTest.add_argument(
543 '--stage2-cmake-def',
544 dest='stage2Defs',
545 metavar='VAR=VALUE',
546 default=[],
547 action='append',
548 help="Additional CMake definitions for stage 2, e.g. "
549 "CMAKE_BUILD_TYPE=Release. Can be passed multiple times. "
550 "The -D is added automatically.")
551buildAndTest.add_argument(
552 '--stage2-build-flag',
553 dest='stage2BuildFlags',
554 metavar='FLAG',
555 default=[],
556 action='append',
557 help="Additional flags for the stage 2 build command (e.g. targets to "
558 "build). Can be passed multiple times. If your flag starts with "
559 "a '-', use '--stage2-build-flag=-FLAG' to pass it.")
560buildAndTest.add_argument(
Diana Picusfcfc6282018-02-14 18:50:24 +0100561 "--enable-test-suite",
562 dest='enableTestSuite',
563 action='store_true',
564 default=False,
565 help="Whether or not to run the test-suite with the last compiler built.")
Diana Picusb03e5082018-02-05 12:36:49 +0100566buildAndTest.add_argument(
567 "--sandbox",
568 help="Path to the sandbox where the test-suite should be setup.")
569buildAndTest.add_argument(
Diana Picusb03e5082018-02-05 12:36:49 +0100570 '-n', '--dry-run',
571 dest='dry',
572 action='store_true',
573 default=False,
574 help="Print the commands instead of executing them.")
575
Diana Picus3b2ef822016-10-13 16:53:18 +0300576args = options.parse_args()
Diana Picusadb07c42017-11-22 16:12:57 +0100577if args.subcommand == "projects" and args.add and not args.repos:
578 projs.error(
579 "When adding a subproject you must also pass the --repos argument")
Diana Picus3b2ef822016-10-13 16:53:18 +0300580args.run_command(args)