The Fuchsia build system aims at building both boot images and updatable packages for various devices. To do so, it uses GN, a meta-build system that generates build files consumed by Ninja, which executes the actual build.
Note that Zircon uses a different build system, though still using GN and Ninja.
If you are unfamiliar with Fuchsia's build system and GN, see Using GN build which outlines the basic principles of the GN build system.
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 documents the structure and usage of these build configurations.
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. A set of top-level bundles are defined in //bundles
.
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:
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. There are also a handful of custom templates in .gni
files in the //build
project.
These custom templates mostly define custom target declaration types, such as the package declaration type.
TODO(pylaligand): list available templates
The simplest way to this is through the fx
tool, as described in fx workflows. 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
.
First configure the primary build artifacts by choosing the board and product to build:
$ 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:
$ 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.
The next step is to run the actual build with Ninja:
$ ninja -C out/default.zircon $ ninja -C out/default
This is what gets run under the hood by fx build
.
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.
$ fx gn desc out/default //path/to/my:target
$ gn refs out/default //path/to/my:target
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)
If a target is defined in a GN build file as //foo/bar/blah:dash
, that target (and its dependencies) can be built with:
$ 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.
GN extensively documents which Ninja targets it generates. The documentation is accessible with:
$ gn help ninja_rules
You can also browse the set of Ninja targets currently defined in your output directory with:
$ 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.
Add -d explain
to your Ninja command to have it explain every step of its execution.
When running a build, Ninja keeps logs that can be used to generate visualizations of the build process:
ninjatracing <output directory>/.ninja_log > trace.json
;about:tracing
.Make sure it rolls up to a label defined in a module file, otherwise the build system will ignore it.
sysroot
.You likely forgot to run both commands of Build step.
TODO(pylaligand): command showing path to default target
TODO(pylaligand): .gn, default target, GN labels insertion