| # The Fuchsia build system |
| |
| ## Overview |
| |
| The Fuchsia build system aims at building both boot images and updatable |
| packages for various devices. To do so, it uses [GN][gn-main], a meta-build |
| system that generates build files consumed by [Ninja][ninja-main], which |
| executes the actual build. |
| |
| Note that Zircon uses a different build system, though still using GN and |
| Ninja. |
| |
| ## Getting started |
| |
| If you are unfamiliar with Fuchsia's build system and GN, see [Using GN |
| build][gn-preso] which outlines the basic principles of the GN build system. |
| |
| ## Boards and Products |
| |
| The contents of the generated image are controlled by a combination of a |
| board and a product that are the minimal starting configuration of a Fuchsia |
| build. Boards and products define dependency sets that define the packages |
| that are included in images, updates, and package repositories. |
| [boards and products](boards_and_products.md) documents the structure and |
| usage of these build configurations. |
| |
| ## Bundles |
| |
| A bundle is a grouping of related packages within a part of the source tree, |
| such as all tools or all tests. An overview of bundles is provided in |
| [bundles](bundles.md). A set of top-level bundles are defined in |
| [`//bundles`](/bundles/README.md). |
| |
| ## Build targets |
| |
| Build targets are defined in `BUILD.gn` files scattered all over the source |
| tree. These files use a Python-like syntax to declare buildable objects: |
| |
| ```py |
| import("//build/some/template.gni") |
| |
| my_template("foo") { |
| name = "foo" |
| extra_options = "//my/foo/options" |
| deps = [ |
| "//some/random/framework", |
| "//some/other/random/framework", |
| ] |
| } |
| ``` |
| |
| Available commands (invoked using gn cli tool) and constructs (built-in target |
| declaration types) are defined in the [GN reference][gn-reference]. There are |
| also a handful of custom templates in `.gni` files in the |
| [`//build` project][build-project]. |
| |
| These custom templates mostly define custom target declaration types, such as |
| the package declaration type. |
| |
| > TODO(pylaligand): list available templates |
| |
| ## Executing a build |
| |
| The simplest way to this is through the `fx` tool, as described in |
| [Getting Started](/docs/getting_started.md#Setup-Build-Environment). Read on to see |
| what `fx` does under the hood. |
| |
| The rest of this document assumes that `gn` and `ninja` commands are |
| available in your `PATH`. These commands can be found in |
| `prebuilt/third_party/gn/<platform>` and |
| `prebuilt/third_party/ninja/<platform>` respectively. Alternatively, if |
| you want to avoid modifying your `PATH`, you can prefix all invocations |
| with `fx`, i.e. `fx gn` or `fx ninja`. |
| |
| ### Gen step |
| |
| First configure the primary build artifacts by choosing the board and product |
| to build: |
| |
| ```bash |
| $ gn gen out/default --args='import("//boards/x64.gni") import("//products/core.gni")' |
| ``` |
| |
| This will create an `out/default` directory containing Ninja files. |
| |
| The equivalent `fx set` command is: |
| |
| ```bash |
| $ fx set core.x64 |
| ``` |
| |
| For a list of all GN build arguments, run `gn args out/default --list`. |
| For documentation on the `select_variant` argument, see [Variants](variants.md). |
| |
| ### Build step |
| |
| The next step is to run the actual build with Ninja: |
| |
| ```bash |
| $ ninja -C out/default.zircon |
| $ ninja -C out/default |
| ``` |
| |
| This is what gets run under the hood by `fx build`. |
| |
| ## Rebuilding |
| |
| In order to rebuild the tree after modifying some sources, just rerun |
| **Build step**. This holds true even if you modify `BUILD.gn` files as GN adds |
| Ninja targets to update Ninja targets if build files are changed! The same |
| holds true for other files used to configure the build. Any change of source |
| that requires a manual re-invocation of the **Gen step** is a build bug and |
| should be reported. |
| |
| ## Tips and tricks |
| |
| ### Inspecting the content of a GN target |
| |
| ```bash |
| $ fx gn desc out/default //path/to/my:target |
| ``` |
| |
| ### Finding references to a GN target |
| |
| ```bash |
| $ gn refs out/default //path/to/my:target |
| ``` |
| |
| ### Referencing targets for the build host |
| |
| Various host tools (some used in the build itself) need to be built along with |
| the final image. |
| |
| To reference a build target for the host toolchain from a module file: |
| |
| ``` |
| //path/to/target(//build/toolchain:host_x64) |
| ``` |
| |
| To reference a build target for the host toolchain from within a `BUILD.gn` |
| file: |
| |
| ``` |
| //path/to/target($host_toolchain) |
| ``` |
| |
| ### Building only a specific target |
| |
| If a target is defined in a GN build file as `//foo/bar/blah:dash`, that target |
| (and its dependencies) can be built with: |
| |
| ```bash |
| $ ninja -C out/default -j64 foo/bar/blah:dash |
| ``` |
| |
| Note that this only works for targets in the default toolchain. |
| |
| Note: Building package targets does not result in an updated package |
| repository, because the package repository is updated by the `updates` group |
| target. In order for updated package changes to be made available via `fx |
| serve`, users must build the `updates` group. |
| |
| ### Exploring Ninja targets |
| |
| GN extensively documents which Ninja targets it generates. The documentation is |
| accessible with: |
| |
| ```bash |
| $ gn help ninja_rules |
| ``` |
| |
| You can also browse the set of Ninja targets currently defined in your output |
| directory with: |
| |
| ```bash |
| $ ninja -C out/default -t browse |
| ``` |
| |
| Note that the presence of a Ninja target does not mean it will be built - for |
| that it needs to depend on the “default” target. |
| |
| ### Understanding why Ninja does what it does |
| |
| Add `-d explain` to your Ninja command to have it explain every step of its |
| execution. |
| |
| ### Debugging build timing issues |
| |
| When running a build, Ninja keeps logs that can be used to generate |
| visualizations of the build process: |
| |
| 1. Delete your output directory - this is to ensure the logs represent only the |
| build iteration you’re about to run; |
| 1. Run a build as you would normally do; |
| 1. Get <https://github.com/nico/ninjatracing>; |
| 1. Run `ninjatracing <output directory>/.ninja_log > trace.json`; |
| 1. Load the resulting json file in Chrome in `about:tracing`. |
| |
| |
| ## Troubleshooting |
| |
| ### My GN target is not being built! |
| |
| Make sure it rolls up to a label defined in a module file, otherwise the build |
| system will ignore it. |
| |
| ### GN complains about missing `sysroot`. |
| |
| You likely forgot to run both commands of **Build step**. |
| |
| > TODO(pylaligand): command showing path to default target |
| |
| |
| ### Internal GN setup |
| |
| > TODO(pylaligand): .gn, default target, GN labels insertion |
| |
| [gn-main]: https://gn.googlesource.com/gn/ |
| [gn-preso]: https://docs.google.com/presentation/d/15Zwb53JcncHfEwHpnG_PoIbbzQ3GQi_cpujYwbpcbZo/ |
| [ninja-main]: https://ninja-build.org/ |
| [gn-reference]: https://gn.googlesource.com/gn/+/master/docs/reference.md |
| [build-project]: /build/ |
| [zircon-getting-started]: /docs/zircon/getting_started.md |