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

Unified 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, 9 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 side-by-side diff with in-line comments
Download patch
Index: tools/mb/docs/design_spec.md
diff --git a/tools/mb/docs/design_spec.md b/tools/mb/docs/design_spec.md
new file mode 100644
index 0000000000000000000000000000000000000000..9d5edf23589c624db295535382971525239292c4
--- /dev/null
+++ b/tools/mb/docs/design_spec.md
@@ -0,0 +1,312 @@
+# The MB (Meta-Build wrapper) design spec
+
+[TOC]
+
+## Summary of Design Requirements
+
+MB is intended to address two major aspects of the GYP -> GN
+transition for Chromium and two minor aspects:
+
+1. "bot toggling" - make it so that we can easily flip a given bot
+ back and forth between GN and GYP.
+
+2. "bot configuration" - provide a single source of truth for all of
+ the different configurations (os/arch/gyp_define combinations) of
+ Chromium that are supported.
+
+3. "multi-build support" - make it easier for developers to build
+ multiple different build configs (gyp and gn, or linux and android,
+ for example) in a single checkout.
+
+4. "gn configs" - explore ways to manage sets of GN flags more easily
+ (i.e., all the flags needed for a ChromeCast build, or the Linux ASAN
+ bot). Eventually we may migrate this functionality into GN itself.
+
+MB must handle at least the `gen` and `analyze` steps on the bots, i.e.,
+we need to wrap both the `gyp_chromium` invocation to generate the
+Ninja files, and the `analyze` step that takes a list of modified files
+and a list of targets to build and returns which targets are affected by
+the files.
+
+MB may also provide a `build` wrapper in order to build multiple
+configurations in a single step for developer convenience.
+
+## Design
+
+MB is intended to be as simple as possible, and to defer as much work as
+possible to GN or GYP. It should live as a very simple Python wrapper
+that offers little in the way of surprises.
+
+### Command line
+
+It is structured as a single binary that supports a list of subcommands:
+
+* `mb gen //out/Release chromium_linux_rel`
+* `mb analyze -i input.json -o output.json chromium_linux_rel`
+
+### Configurations
+
+`mb` looks in the `//build/mb_conf.pyl` config file to determine whether
+to use GYP or GN for a particular build directory, and what set of flags
+(`GYP_DEFINES` or `gn args`) to use.
+
+`mb_conf.pyl` is structured as a file containing a single PYthon Literal
+expression, a dictionary with two main keys, `build_configs` and
+`mixins`.
+
+The `build_configs` key points to a dictionary of named build
+configurations. Each name should be either a bot name (e.g.,
+`chromium_linux_rel`) or an obvious developer configuration
+(`gyp_shared_debug`).
+
+There should be an entry in this dict for every supported configuration
+of Chromium, meaning every configuration we have a bot for, and every
+configuration commonly used by develpers but that we may not have a bot
+for.
+
+Each build_config entry then points to a list of "mixins" that will
+define what that build_config does. Each item in the list must be
+an entry in the dictionary value of the `mixins` key.
+
+Each entry is itself a diction that contains one or more of the
+following keys:
+
+ * `gyp_configs`: a list of the configurations to build, e.g.,
+ ['Release', 'Release_x64']; specifying this in conjunction
+ with type=gyp_one_config can reduce the time it takes to run gyp_chromium
+ a bit.
+ * `gyp_defines`: a string containing a list of GYP_DEFINES.
+ * `gn_args`: a string containing a list of values passed to gn --args.
+ * `mixins`: a list of other mixins that should be included.
+ * `type`: a string with either the value `gyp`, `gyp_one_config`, or `gn`;
+ setting this indicates which meta-build tool to use.
+
+When `mb gen` executes, it takes a build_config name, looks it up in the
+'build_configs' dict, and then does a left-to-right expansion of the
+mixins; gyp_defines and gn_args values are concatenated, and type and
+gyp_configs values override each other.
+
+For example, if you had:
+
+```
+{
+ 'build_configs`: {
+ 'linux_release_trybot': ['gyp_release', 'trybot'],
+ 'gn_shared_debug': None,
+ }
+ 'mixins': {
+ 'bot': {
+ 'gyp_defines': 'use_goma=1 dcheck_always_on=0',
+ 'gn_args': 'use_goma=true dcheck_always_on=false',
+ },
+ 'debug': {
+ 'gn_args': 'is_debug=true',
+ },
+ 'gn': {'type': 'gn'},
+ 'gyp_release': {
+ 'gyp_config': 'Release'
+ 'mixins': ['release'],
+ 'type': 'gyp',
+ },
+ 'release': {
+ 'gn_args': 'is_debug=false',
+ }
+ 'shared': {
+ 'gn_args': 'is_component_build=true',
+ 'gyp_defines': 'component=shared_library',
+ },
+ 'trybot': {
+ 'gyp_defines': 'dcheck_always_on=1',
+ 'gn_args': 'dcheck_always_on=true',
+ }
+ }
+}
+
+and you ran `mb gen //out/Release linux_release_trybot`, it would
+translate into a call to `gyp_chromium -G Release` with `GYP_DEFINES` set to
+`"use_goma=true dcheck_always_on=false dcheck_always_on=true"`.
+
+(From that you can see that mb is intentionally dumb and does not
+attempt to de-dup the flags, it lets gyp do that).
+
+### Handling the analyze step
+
+The way a GYP bot runs the "analyze" step is to pass gyp_chromium
+two filename paths.
+
+The first path is to a JSON file used as input; it contains a single
+object with a two fields:
+
+ * `files`: an array of the modified filenames to check (as
+ paths relative to the checkout root).
+ * `targets`: an array of the unqualified target names to check.
+
+The second path is a path where the analyze generator should write the
+result, also as a JSON object. This object may contain the following
+fields:
+
+ * `error`: this should only be present if something failed.
+ * `targets`: the subset of the input `targets` that depend on the
+ input `files`.
+ * `build_targets`: the minimal subset of targets needed to build all
+ of `targets` that were affected.
+ * `status`: one of three strings:
+ * `"Found dependency"` (build the `build_targets`)
+ * `"No dependency"` (i.e., no build needed)
+ * `"Found dependency (all)"` (build everything, in which case
+ `targets` and `build_targets` are not returned).
+
+mb replicates this command line interface, through `'mb analyze -i
+input.json -o output.json build_config`.
+
+It implements the equivalent functionality in GN by calling `'gn refs
+[list of files] --type=executable --all --as=output` and filtering the
+output to match the list of targets.
+
+### Multi-build support
+
+Today one can pass options to GYP builds in many different ways:
+
+* specifying args directly to `gyp_chromium` with the `-D` flag.
+* setting the `GYP_DEFINES` environment variable.
+* setting the `GYP_DEFINES` key in a file named `chromium.gyp_env` that
+ lives in the directory above `src`.
+* setting variables in a file in `~/.gyp/include.gypi`.
+
+Each of these approaches has advantages and disadvantages; the first two
+are flexible, and allow you to customize each build directory (except
+that you cannot have different flags for debug and release builds unless
+you invoke gyp twice and only build one config each time), but they
+require you to set something every time you run the command line (i.e.,
+extra typing). The third saves typing, but does not allow you to
+generate different build dirs in a single checkout; the fourth applies
+not only to every build dir, but every checkout.
+
+GN, on the other hand, only supports setting flags via the `--args`
+command line argument, or the `args.gn` file in the build directory;
+these are the equivalent of the first two GYP methods.
+
+Ideally we would have a mechanism that offered the best of both worlds:
+we could customize each build directory (including whether to use gyp or
+gn), and we could generate multiple directories at once.
+
+MB supports this by looking for a config file named `builds.pyl` in the
+directory above the checkout. The builds.pyl config file should contain
+a dictionary where each key indicates the path to a desired build
+directory, and each value specifies a particular build config (one of
+the valid `build_config` values in `//build/mb_conf.pyl`).
+
+For example, this:
+
+```
+src% cat ../build.pyl
+{
+ "//out/Release": ["linux_release_trybot"],
+ "//out/Debug.gn": ["gn_shared_debug"],
+}
+src% mbw gen
+src%
+```
+
+is the equivalent of:
+
+```
+src% GYP_DEFINES="use_goma=1 dcheck_always_on=0 dcheck_always_on=1" build/gyp_chromium -G config=Release -G output_dir=out
+src% gn gen //out/Debug.gn --args='use_goma=true dcheck_always_on=true dcheck_always_on=false'
+```
+
+## Detailed Design Requirements and Rationale
+
+This section is collection of semi-organized notes on why MB is the way
+it is
+
+### in-tree or out-of-tree
+
+The first issue is whether or not this should exist as a script in
+Chromium at all; an alternative would be to simply change the bot
+configurations to know whether to use GYP or GN, and which flags to
+pass.
+
+That would certainly work, but experience over the past two years
+suggests a few things:
+
+ * we should push as much logic as we can into the source repositories
+ so that they can be versioned and changed atomically with changes to
+ the product code; having to coordinate changes between src/ and
+ build/ is at best annoying and can lead to weird errors.
+ * the infra team would really like to move to providing
+ product-independent services (i.e., not have to do one thing for
+ Chromium, another for NaCl, a third for V8, etc.).
+ * we found that during the SVN->GIT migration the ability to flip bot
+ configurations between the two via changes to a file in chromium
+ was very useful.
+
+All of this suggests that the interface between bots and Chromium should
+be a simple one, hiding as much of the chromium logic as possible.
+
+### Do we need multi-build support?
+
+Strictly speaking, no. MB could be useful just as a bot->chromium
+interface. However, we do know that managing multiple build directories
+is often awkward for many Chromium devs, at least until they write their
+own wrappers. Many devs often also use multiple checkouts here, which
+has higher overhead and can lead to confusion.
+
+We also know that some people miss the equivalents of setting
+environment variables, chromium.gyp_env, etc., and would like an easier
+way to make sure that multiple build dirs can share settings (like
+use_goma and goma_dir, for example).
+
+### Why not have MB be smarter about de-duping flags?
+
+This just adds complexity to the MB implementation, and duplicates logic
+that GYP and GN already have to support anyway; in particular, it might
+require MB to know how to parse GYP and GN values. The belief is that
+if MB does *not* do this, it will lead to fewer surprises.
+
+It will not be hard to change this if need be.
+
+### Non-goals
+
+* MB is not intended to replace the
+ [CR tool](https://code.google.com/p/chromium/wiki/CRUserManual). It
+ is only intended to replace the gyp_chromium part of `'gclient
+ runhooks'`. Hopefully the CR tool will learn about and integrate w/ MB
+ once MB becomes stable.
+
+* MB is not (yet?) intended to replace direct invocation of GN or GYP for
+ complicated build scenarios (aka ChromeOS), where multiple flags need
+ to be set to user-defined paths for specific toolchains (e.g., where
+ ChromeOS needs to specify specific board types and compilers).
+
+### Open issues
+
+* Some common flags (goma_dir being the obvious one) may need to be
+ specified via the user, and it's unclear how to integrate this with
+ the concept of build_configs.
+
+ Right now, MB has hard-coded support for a few flags (i.e., you can
+ pass the --goma-dir flag, and it will know to expand "${goma_dir}" in
+ the string before calling out to the tool. We may want to generalize
+ this to a common key/value approach (perhaps then meeting the
+ ChromeOS non-goal, above), or we may want to keep this very strictly
+ limited for simplicity.
+
+* Do we need to add a `'mb build'` command?
+
+ Being able to update multiple build dirs after syncing is useful, but
+ for GN-based dirs, ninja will do it for us automatically. It's unclear
+ if enough people will have a mixture of GYP and GN builds to make this
+ worth it to add.
+
+* How do we integrate `mb` with `gclient runhooks`?
+
+ On the bots, we will disable gyp_chromium as part of runhooks (using
+ GYP_CHROMIUM_NO_ACTION=1), so that mb shows up as a separate step.
+
+ However, gyp_chromium is run by default as part of `gclient runhooks`
+ and `gclient sync` for normal developers, and we probably don't want
+ to make everyone need to use GYP_CHROMIUM_NO_ACTION. Given that
+ `mb gen` with no arguments and no builds.pyl file is equivalent to
+ `gyp_chromium`, we might want to just update the hook to call mb.
+ Are there downsides to doing so?
« 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