blob: 8c66cd328c728050279d455b2fd7ef4b0b8835ec [file] [log] [blame] [view]
kjellandera013a022016-11-14 13:54:221# The MB (Meta-Build wrapper) user guide
2
3[TOC]
4
5## Introduction
6
7`mb` is a simple python wrapper around the GYP and GN meta-build tools to
8be used as part of the GYP->GN migration.
9
10It is intended to be used by bots to make it easier to manage the configuration
11each bot builds (i.e., the configurations can be changed from chromium
12commits), and to consolidate the list of all of the various configurations
13that Chromium is built in.
14
15Ideally this tool will no longer be needed after the migration is complete.
16
17For more discussion of MB, see also [the design spec](design_spec.md).
18
19## MB subcommands
20
21### `mb analyze`
22
23`mb analyze` is reponsible for determining what targets are affected by
24a list of files (e.g., the list of files in a patch on a trybot):
25
26```
27mb analyze -c chromium_linux_rel //out/Release input.json output.json
28```
29
Mirko Bonadei8606b9c2021-01-12 13:29:4030Either the `-c/--config` flag or the `-m/--builder-group` and `-b/--builder`
31flags must be specified so that `mb` can figure out which config to use.
kjellandera013a022016-11-14 13:54:2232
33The first positional argument must be a GN-style "source-absolute" path
34to the build directory.
35
36The second positional argument is a (normal) path to a JSON file containing
37a single object with the following fields:
38
39 * `files`: an array of the modified filenames to check (as paths relative to
40 the checkout root).
41 * `test_targets`: an array of (ninja) build targets that needed to run the
42 tests we wish to run. An empty array will be treated as if there are
43 no tests that will be run.
44 * `additional_compile_targets`: an array of (ninja) build targets that
45 reflect the stuff we might want to build *in addition to* the list
46 passed in `test_targets`. Targets in this list will be treated
47 specially, in the following way: if a given target is a "meta"
48 (GN: group, GYP: none) target like 'blink_tests' or
49 'chromium_builder_tests', or even the ninja-specific 'all' target,
50 then only the *dependencies* of the target that are affected by
51 the modified files will be rebuilt (not the target itself, which
52 might also cause unaffected dependencies to be rebuilt). An empty
53 list will be treated as if there are no additional targets to build.
54 Empty lists for both `test_targets` and `additional_compile_targets`
55 would cause no work to be done, so will result in an error.
56 * `targets`: a legacy field that resembled a union of `compile_targets`
57 and `test_targets`. Support for this field will be removed once the
58 bots have been updated to use compile_targets and test_targets instead.
59
60The third positional argument is a (normal) path to where mb will write
61the result, also as a JSON object. This object may contain the following
62fields:
63
64 * `error`: this should only be present if something failed.
65 * `compile_targets`: the list of ninja targets that should be passed
66 directly to the corresponding ninja / compile.py invocation. This
67 list may contain entries that are *not* listed in the input (see
68 the description of `additional_compile_targets` above and
69 [design_spec.md](the design spec) for how this works).
70 * `invalid_targets`: a list of any targets that were passed in
71 either of the input lists that weren't actually found in the graph.
72 * `test_targets`: the subset of the input `test_targets` that are
73 potentially out of date, indicating that the matching test steps
74 should be re-run.
75 * `targets`: a legacy field that indicates the subset of the input `targets`
76 that depend on the input `files`.
77 * `build_targets`: a legacy field that indicates the minimal subset of
78 targets needed to build all of `targets` that were affected.
79 * `status`: a field containing one of three strings:
80
81 * `"Found dependency"` (build the `compile_targets`)
82 * `"No dependency"` (i.e., no build needed)
83 * `"Found dependency (all)"` (`test_targets` is returned as-is;
84 `compile_targets` should contain the union of `test_targets` and
85 `additional_compile_targets`. In this case the targets do not
86 need to be pruned).
87
88See [design_spec.md](the design spec) for more details and examples; the
89differences can be subtle. We won't even go into how the `targets` and
90`build_targets` differ from each other or from `compile_targets` and
91`test_targets`.
92
Mirko Bonadei8606b9c2021-01-12 13:29:4093The `-b/--builder`, `-c/--config`, `-f/--config-file`, `-m/--builder-group`,
kjellandera013a022016-11-14 13:54:2294`-q/--quiet`, and `-v/--verbose` flags work as documented for `mb gen`.
95
96### `mb audit`
97
98`mb audit` is used to track the progress of the GYP->GN migration. You can
Mirko Bonadei8606b9c2021-01-12 13:29:4099use it to check a single builder group, or all the builder groups we care
100about.
101See `mb help audit` for more details (most people are not expected to care
102about this).
kjellandera013a022016-11-14 13:54:22103
104### `mb gen`
105
106`mb gen` is responsible for generating the Ninja files by invoking either GYP
107or GN as appropriate. It takes arguments to specify a build config and
108a directory, then runs GYP or GN as appropriate:
109
110```
111% mb gen -m tryserver.chromium.linux -b linux_rel //out/Release
112% mb gen -c linux_rel_trybot //out/Release
113```
114
Mirko Bonadei8606b9c2021-01-12 13:29:40115Either the `-c/--config` flag or the `-m/--builder-group` and `-b/--builder`
116flags must be specified so that `mb` can figure out which config to use. The
kjellandera013a022016-11-14 13:54:22117`--phase` flag must also be used with builders that have multiple
118build/compile steps (and only with those builders).
119
120By default, MB will look for a bot config file under `//ios/build/bots` (see
121[design_spec.md](the design spec) for details of how the bot config files
122work). If no matching one is found, will then look in
123`//tools/mb/mb_config.pyl` to look up the config information, but you can
124specify a custom config file using the `-f/--config-file` flag.
125
126The path must be a GN-style "source-absolute" path (as above).
127
128You can pass the `-n/--dryrun` flag to mb gen to see what will happen without
129actually writing anything.
130
131You can pass the `-q/--quiet` flag to get mb to be silent unless there is an
132error, and pass the `-v/--verbose` flag to get mb to log all of the files
133that are read and written, and all the commands that are run.
134
135If the build config will use the Goma distributed-build system, you can pass
136the path to your Goma client in the `-g/--goma-dir` flag, and it will be
137incorporated into the appropriate flags for GYP or GN as needed.
138
139If gen ends up using GYP, the path must have a valid GYP configuration as the
140last component of the path (i.e., specify `//out/Release_x64`, not `//out`).
141The gyp script defaults to `//build/gyp_chromium`, but can be overridden with
142the `--gyp-script` flag, e.g. `--gyp-script=gypfiles/gyp_v8`.
143
144### `mb help`
145
146Produces help output on the other subcommands
147
148### `mb lookup`
149
150Prints what command will be run by `mb gen` (like `mb gen -n` but does
151not require you to specify a path).
152
Mirko Bonadei8606b9c2021-01-12 13:29:40153The `-b/--builder`, `-c/--config`, `-f/--config-file`, `-m/--builder-group`,
kjellandera013a022016-11-14 13:54:22154`--phase`, `-q/--quiet`, and `-v/--verbose` flags work as documented for
155`mb gen`.
156
157### `mb validate`
158
159Does internal checking to make sure the config file is syntactically
160valid and that all of the entries are used properly. It does not validate
161that the flags make sense, or that the builder names are legal or
162comprehensive, but it does complain about configs and mixins that aren't
163used.
164
165The `-f/--config-file` and `-q/--quiet` flags work as documented for
166`mb gen`.
167
168This is mostly useful as a presubmit check and for verifying changes to
169the config file.
170
171## Isolates and Swarming
172
173`mb gen` is also responsible for generating the `.isolate` and
174`.isolated.gen.json` files needed to run test executables through swarming
175in a GN build (in a GYP build, this is done as part of the compile step).
176
177If you wish to generate the isolate files, pass `mb gen` the
178`--swarming-targets-file` command line argument; that arg should be a path
179to a file containing a list of ninja build targets to compute the runtime
180dependencies for (on Windows, use the ninja target name, not the file, so
181`base_unittests`, not `base_unittests.exe`).
182
183MB will take this file, translate each build target to the matching GN
184label (e.g., `base_unittests` -> `//base:base_unittests`, write that list
185to a file called `runtime_deps` in the build directory, and pass that to
186`gn gen $BUILD ... --runtime-deps-list-file=$BUILD/runtime_deps`.
187
188Once GN has computed the lists of runtime dependencies, MB will then
189look up the command line for each target (currently this is hard-coded
190in [mb.py](https://code.google.com/p/chromium/codesearch?q=mb.py#chromium/src/tools/mb/mb.py&q=mb.py%20GetIsolateCommand&sq=package:chromium&type=cs)), and write out the
191matching `.isolate` and `.isolated.gen.json` files.
192
193## The `mb_config.pyl` config file
194
195The `mb_config.pyl` config file is intended to enumerate all of the
196supported build configurations for Chromium. Generally speaking, you
197should never need to (or want to) build a configuration that isn't
198listed here, and so by using the configs in this file you can avoid
199having to juggle long lists of GYP_DEFINES and gn args by hand.
200
201`mb_config.pyl` is structured as a file containing a single PYthon Literal
Mirko Bonadei8606b9c2021-01-12 13:29:40202expression: a dictionary with three main keys, `builder_groups`, `configs` and
kjellandera013a022016-11-14 13:54:22203`mixins`.
204
Mirko Bonadei8606b9c2021-01-12 13:29:40205The `builder_groups` key contains a nested series of dicts containing mappings
206of builder group -> builder -> config . This allows us to isolate the buildbot
kjellandera013a022016-11-14 13:54:22207recipes from the actual details of the configs. The config should either
208be a single string value representing a key in the `configs` dictionary,
209or a list of strings, each of which is a key in the `configs` dictionary;
210the latter case is for builders that do multiple compiles with different
211arguments in a single build, and must *only* be used for such builders
212(where a --phase argument must be supplied in each lookup or gen call).
213
214The `configs` key points to a dictionary of named build configurations.
215
216There should be an key in this dict for every supported configuration
217of Chromium, meaning every configuration we have a bot for, and every
218configuration commonly used by develpers but that we may not have a bot
219for.
220
221The value of each key is a list of "mixins" that will define what that
222build_config does. Each item in the list must be an entry in the dictionary
223value of the `mixins` key.
224
225Each mixin value is itself a dictionary that contains one or more of the
226following keys:
227
228 * `gyp_crosscompile`: a boolean; if true, GYP_CROSSCOMPILE=1 is set in
229 the environment and passed to GYP.
230 * `gyp_defines`: a string containing a list of GYP_DEFINES.
231 * `gn_args`: a string containing a list of values passed to gn --args.
232 * `mixins`: a list of other mixins that should be included.
233 * `type`: a string with either the value `gyp` or `gn`;
234 setting this indicates which meta-build tool to use.
235
236When `mb gen` or `mb analyze` executes, it takes a config name, looks it
237up in the 'configs' dict, and then does a left-to-right expansion of the
238mixins; gyp_defines and gn_args values are concatenated, and the type values
239override each other.
240
241For example, if you had:
242
243```
244{
245 'configs`: {
246 'linux_release_trybot': ['gyp_release', 'trybot'],
247 'gn_shared_debug': None,
248 }
249 'mixins': {
250 'bot': {
Mirko Bonadei481e3452021-07-30 11:57:25251 'gyp_defines': 'use_goma=1 dcheck_always_on=0',
252 'gn_args': 'use_goma=true dcheck_always_on=false',
kjellandera013a022016-11-14 13:54:22253 },
254 'debug': {
255 'gn_args': 'is_debug=true',
256 },
257 'gn': {'type': 'gn'},
258 'gyp_release': {
259 'mixins': ['release'],
260 'type': 'gyp',
261 },
262 'release': {
263 'gn_args': 'is_debug=false',
264 }
265 'shared': {
266 'gn_args': 'is_component_build=true',
267 'gyp_defines': 'component=shared_library',
268 },
269 'trybot': {
Mirko Bonadei481e3452021-07-30 11:57:25270 'gyp_defines': 'dcheck_always_on=1',
271 'gn_args': 'dcheck_always_on=true',
kjellandera013a022016-11-14 13:54:22272 }
273 }
274}
275```
276
277and you ran `mb gen -c linux_release_trybot //out/Release`, it would
278translate into a call to `gyp_chromium -G Release` with `GYP_DEFINES` set to
Mirko Bonadei481e3452021-07-30 11:57:25279`"use_goma=true dcheck_always_on=false dcheck_always_on=true"`.
kjellandera013a022016-11-14 13:54:22280
281(From that you can see that mb is intentionally dumb and does not
282attempt to de-dup the flags, it lets gyp do that).
283
284## Debugging MB
285
286By design, MB should be simple enough that very little can go wrong.
287
288The most obvious issue is that you might see different commands being
289run than you expect; running `'mb -v'` will print what it's doing and
290run the commands; `'mb -n'` will print what it will do but *not* run
291the commands.
292
293If you hit weirder things than that, add some print statements to the
294python script, send a question to gn-dev@chromium.org, or
295[file a bug](https://crbug.com/new) with the label
296'mb' and cc: dpranke@chromium.org.
297
298