Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(115)

Side by Side Diff: tools/mb/docs/design_spec.md

Issue 1005723003: First pass at a meta-build wrapper for the gyp->gn migration (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rename to mb, add docs Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # The MB (Meta-Build wrapper) design spec
2
3 [TOC]
4
5 ## Summary of Design Requirements
6
7 MB is intended to address two major aspects of the GYP -> GN
8 transition for Chromium and two minor aspects:
9
10 1. "bot toggling" - make it so that we can easily flip a given bot
11 back and forth between GN and GYP.
12
13 2. "bot configuration" - provide a single source of truth for all of
14 the different configurations (os/arch/gyp_define combinations) of
15 Chromium that are supported.
16
17 3. "multi-build support" - make it easier for developers to build
18 multiple different build configs (gyp and gn, or linux and android,
19 for example) in a single checkout.
20
21 4. "gn configs" - explore ways to manage sets of GN flags more easily
22 (i.e., all the flags needed for a ChromeCast build, or the Linux ASAN
23 bot). Eventually we may migrate this functionality into GN itself.
24
25 MB must handle at least the `gen` and `analyze` steps on the bots, i.e.,
26 we need to wrap both the `gyp_chromium` invocation to generate the
27 Ninja files, and the `analyze` step that takes a list of modified files
28 and a list of targets to build and returns which targets are affected by
29 the files.
30
31 MB may also provide a `build` wrapper in order to build multiple
32 configurations in a single step for developer convenience.
33
34 ## Design
35
36 MB is intended to be as simple as possible, and to defer as much work as
37 possible to GN or GYP. It should live as a very simple Python wrapper
38 that offers little in the way of surprises.
39
40 ### Command line
41
42 It is structured as a single binary that supports a list of subcommands:
43
44 * `mb gen //out/Release chromium_linux_rel`
45 * `mb analyze -i input.json -o output.json chromium_linux_rel`
46
47 ### Configurations
48
49 `mb` looks in the `//build/mb_conf.pyl` config file to determine whether
50 to use GYP or GN for a particular build directory, and what set of flags
51 (`GYP_DEFINES` or `gn args`) to use.
52
53 `mb_conf.pyl` is structured as a file containing a single PYthon Literal
54 expression, a dictionary with two main keys, `build_configs` and
55 `mixins`.
56
57 The `build_configs` key points to a dictionary of named build
58 configurations. Each name should be either a bot name (e.g.,
59 `chromium_linux_rel`) or an obvious developer configuration
60 (`gyp_shared_debug`).
61
62 There should be an entry in this dict for every supported configuration
63 of Chromium, meaning every configuration we have a bot for, and every
64 configuration commonly used by develpers but that we may not have a bot
65 for.
66
67 Each build_config entry then points to a list of "mixins" that will
68 define what that build_config does. Each item in the list must be
69 an entry in the dictionary value of the `mixins` key.
70
71 Each entry is itself a diction that contains one or more of the
72 following keys:
73
74 * `gyp_configs`: a list of the configurations to build, e.g.,
75 ['Release', 'Release_x64']; specifying this in conjunction
76 with type=gyp_one_config can reduce the time it takes to run gyp_chromium
77 a bit.
78 * `gyp_defines`: a string containing a list of GYP_DEFINES.
79 * `gn_args`: a string containing a list of values passed to gn --args.
80 * `mixins`: a list of other mixins that should be included.
81 * `type`: a string with either the value `gyp`, `gyp_one_config`, or `gn`;
82 setting this indicates which meta-build tool to use.
83
84 When `mb gen` executes, it takes a build_config name, looks it up in the
85 'build_configs' dict, and then does a left-to-right expansion of the
86 mixins; gyp_defines and gn_args values are concatenated, and type and
87 gyp_configs values override each other.
88
89 For example, if you had:
90
91 ```
92 {
93 'build_configs`: {
94 'linux_release_trybot': ['gyp_release', 'trybot'],
95 'gn_shared_debug': None,
96 }
97 'mixins': {
98 'bot': {
99 'gyp_defines': 'use_goma=1 dcheck_always_on=0',
100 'gn_args': 'use_goma=true dcheck_always_on=false',
101 },
102 'debug': {
103 'gn_args': 'is_debug=true',
104 },
105 'gn': {'type': 'gn'},
106 'gyp_release': {
107 'gyp_config': 'Release'
108 'mixins': ['release'],
109 'type': 'gyp',
110 },
111 'release': {
112 'gn_args': 'is_debug=false',
113 }
114 'shared': {
115 'gn_args': 'is_component_build=true',
116 'gyp_defines': 'component=shared_library',
117 },
118 'trybot': {
119 'gyp_defines': 'dcheck_always_on=1',
120 'gn_args': 'dcheck_always_on=true',
121 }
122 }
123 }
124
125 and you ran `mb gen //out/Release linux_release_trybot`, it would
126 translate into a call to `gyp_chromium -G Release` with `GYP_DEFINES` set to
127 `"use_goma=true dcheck_always_on=false dcheck_always_on=true"`.
128
129 (From that you can see that mb is intentionally dumb and does not
130 attempt to de-dup the flags, it lets gyp do that).
131
132 ### Handling the analyze step
133
134 The way a GYP bot runs the "analyze" step is to pass gyp_chromium
135 two filename paths.
136
137 The first path is to a JSON file used as input; it contains a single
138 object with a two fields:
139
140 * `files`: an array of the modified filenames to check (as
141 paths relative to the checkout root).
142 * `targets`: an array of the unqualified target names to check.
143
144 The second path is a path where the analyze generator should write the
145 result, also as a JSON object. This object may contain the following
146 fields:
147
148 * `error`: this should only be present if something failed.
149 * `targets`: the subset of the input `targets` that depend on the
150 input `files`.
151 * `build_targets`: the minimal subset of targets needed to build all
152 of `targets` that were affected.
153 * `status`: one of three strings:
154 * `"Found dependency"` (build the `build_targets`)
155 * `"No dependency"` (i.e., no build needed)
156 * `"Found dependency (all)"` (build everything, in which case
157 `targets` and `build_targets` are not returned).
158
159 mb replicates this command line interface, through `'mb analyze -i
160 input.json -o output.json build_config`.
161
162 It implements the equivalent functionality in GN by calling `'gn refs
163 [list of files] --type=executable --all --as=output` and filtering the
164 output to match the list of targets.
165
166 ### Multi-build support
167
168 Today one can pass options to GYP builds in many different ways:
169
170 * specifying args directly to `gyp_chromium` with the `-D` flag.
171 * setting the `GYP_DEFINES` environment variable.
172 * setting the `GYP_DEFINES` key in a file named `chromium.gyp_env` that
173 lives in the directory above `src`.
174 * setting variables in a file in `~/.gyp/include.gypi`.
175
176 Each of these approaches has advantages and disadvantages; the first two
177 are flexible, and allow you to customize each build directory (except
178 that you cannot have different flags for debug and release builds unless
179 you invoke gyp twice and only build one config each time), but they
180 require you to set something every time you run the command line (i.e.,
181 extra typing). The third saves typing, but does not allow you to
182 generate different build dirs in a single checkout; the fourth applies
183 not only to every build dir, but every checkout.
184
185 GN, on the other hand, only supports setting flags via the `--args`
186 command line argument, or the `args.gn` file in the build directory;
187 these are the equivalent of the first two GYP methods.
188
189 Ideally we would have a mechanism that offered the best of both worlds:
190 we could customize each build directory (including whether to use gyp or
191 gn), and we could generate multiple directories at once.
192
193 MB supports this by looking for a config file named `builds.pyl` in the
194 directory above the checkout. The builds.pyl config file should contain
195 a dictionary where each key indicates the path to a desired build
196 directory, and each value specifies a particular build config (one of
197 the valid `build_config` values in `//build/mb_conf.pyl`).
198
199 For example, this:
200
201 ```
202 src% cat ../build.pyl
203 {
204 "//out/Release": ["linux_release_trybot"],
205 "//out/Debug.gn": ["gn_shared_debug"],
206 }
207 src% mbw gen
208 src%
209 ```
210
211 is the equivalent of:
212
213 ```
214 src% GYP_DEFINES="use_goma=1 dcheck_always_on=0 dcheck_always_on=1" build/gyp_ch romium -G config=Release -G output_dir=out
215 src% gn gen //out/Debug.gn --args='use_goma=true dcheck_always_on=true dcheck_al ways_on=false'
216 ```
217
218 ## Detailed Design Requirements and Rationale
219
220 This section is collection of semi-organized notes on why MB is the way
221 it is
222
223 ### in-tree or out-of-tree
224
225 The first issue is whether or not this should exist as a script in
226 Chromium at all; an alternative would be to simply change the bot
227 configurations to know whether to use GYP or GN, and which flags to
228 pass.
229
230 That would certainly work, but experience over the past two years
231 suggests a few things:
232
233 * we should push as much logic as we can into the source repositories
234 so that they can be versioned and changed atomically with changes to
235 the product code; having to coordinate changes between src/ and
236 build/ is at best annoying and can lead to weird errors.
237 * the infra team would really like to move to providing
238 product-independent services (i.e., not have to do one thing for
239 Chromium, another for NaCl, a third for V8, etc.).
240 * we found that during the SVN->GIT migration the ability to flip bot
241 configurations between the two via changes to a file in chromium
242 was very useful.
243
244 All of this suggests that the interface between bots and Chromium should
245 be a simple one, hiding as much of the chromium logic as possible.
246
247 ### Do we need multi-build support?
248
249 Strictly speaking, no. MB could be useful just as a bot->chromium
250 interface. However, we do know that managing multiple build directories
251 is often awkward for many Chromium devs, at least until they write their
252 own wrappers. Many devs often also use multiple checkouts here, which
253 has higher overhead and can lead to confusion.
254
255 We also know that some people miss the equivalents of setting
256 environment variables, chromium.gyp_env, etc., and would like an easier
257 way to make sure that multiple build dirs can share settings (like
258 use_goma and goma_dir, for example).
259
260 ### Why not have MB be smarter about de-duping flags?
261
262 This just adds complexity to the MB implementation, and duplicates logic
263 that GYP and GN already have to support anyway; in particular, it might
264 require MB to know how to parse GYP and GN values. The belief is that
265 if MB does *not* do this, it will lead to fewer surprises.
266
267 It will not be hard to change this if need be.
268
269 ### Non-goals
270
271 * MB is not intended to replace the
272 [CR tool](https://code.google.com/p/chromium/wiki/CRUserManual). It
273 is only intended to replace the gyp_chromium part of `'gclient
274 runhooks'`. Hopefully the CR tool will learn about and integrate w/ MB
275 once MB becomes stable.
276
277 * MB is not (yet?) intended to replace direct invocation of GN or GYP for
278 complicated build scenarios (aka ChromeOS), where multiple flags need
279 to be set to user-defined paths for specific toolchains (e.g., where
280 ChromeOS needs to specify specific board types and compilers).
281
282 ### Open issues
283
284 * Some common flags (goma_dir being the obvious one) may need to be
285 specified via the user, and it's unclear how to integrate this with
286 the concept of build_configs.
287
288 Right now, MB has hard-coded support for a few flags (i.e., you can
289 pass the --goma-dir flag, and it will know to expand "${goma_dir}" in
290 the string before calling out to the tool. We may want to generalize
291 this to a common key/value approach (perhaps then meeting the
292 ChromeOS non-goal, above), or we may want to keep this very strictly
293 limited for simplicity.
294
295 * Do we need to add a `'mb build'` command?
296
297 Being able to update multiple build dirs after syncing is useful, but
298 for GN-based dirs, ninja will do it for us automatically. It's unclear
299 if enough people will have a mixture of GYP and GN builds to make this
300 worth it to add.
301
302 * How do we integrate `mb` with `gclient runhooks`?
303
304 On the bots, we will disable gyp_chromium as part of runhooks (using
305 GYP_CHROMIUM_NO_ACTION=1), so that mb shows up as a separate step.
306
307 However, gyp_chromium is run by default as part of `gclient runhooks`
308 and `gclient sync` for normal developers, and we probably don't want
309 to make everyone need to use GYP_CHROMIUM_NO_ACTION. Given that
310 `mb gen` with no arguments and no builds.pyl file is equivalent to
311 `gyp_chromium`, we might want to just update the hook to call mb.
312 Are there downsides to doing so?
OLDNEW
« tools/mb/README.md ('K') | « tools/mb/README.md ('k') | tools/mb/docs/user_guide.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698