blob: ac96e8484cb10544bdc4764aeb39555dc08005ba [file] [log] [blame] [view]
# Build system
Fuchsia builds use [Generate Ninja](https://gn.googlesource.com/gn/) (GN),
a meta-build system that generates build files consumed by
[Ninja](https://ninja-build.org/){:.external}, which executes the actual build.
The build system provides the tools to configure the build for a specific
product and templates to build code for Fuchsia targets.
## Build targets
You define individual build targets for GN using `BUILD.gn` files located with
your project source code. The Fuchsia build system provides templates as GN
imports (`.gni`) for you to declare Fuchsia artifacts, such as:
* `fuchsia_component()`: Defines an executable
[component](/docs/concepts/components/v2), containing the manifest, program
binary, and resources.
* `fuchsia_package()`: Defines a [package](/docs/concepts/packages/package.md)
containing one or more components for distribution in a package repository.
* `fuchsia_test_package()`: Defines a package containing test components.
Note: You can see all the Fuchsia build templates in
[`//build/components.gni`](/build/components.gni).
Below is an example of a `BUILD.gn` file for a simple component package with
tests:
```gn
import("//build/components.gni")
executable("bin") {
sources = [ "main.cc" ]
}
fuchsia_component("hello-world-component") {
deps = [ ":bin" ]
manifest = "meta/hello-world.cml"
}
fuchsia_package("hello-world") {
deps = [
":hello-world-component",
]
}
fuchsia_component("hello-world-test-component") {
testonly = true
deps = [ ":bin_test" ]
manifest = "meta/hello-world-bin-test.cml"
}
fuchsia_test_package("hello-world-tests") {
test_components = [ ":hello-world-test-component" ]
}
```
A unique **label** composed of the target's name and the path to its `BUILD.gn`
file identifies everything that can participate in the build. In the above
example, the `hello-world` target might have a label that looks like
this: `//src/examples/basic:hello-world`.
Note: For more details on the mechanics of building with GN, see
[Introduction to GN](/docs/development/build/build_system/intro.md).
## Build configuration
The GN front-end configures the build according to the chosen Fuchsia
**product configuration**, collecting all the necessary packages and components
required by the build. These targets are defined in various `BUILD.gn` files
throughout the source tree. The output of the GN step is an optimized set of
instructions for Ninja in the build directory.
The build system invokes GN when you run the `fx set` command to configure
the build.
```posix-terminal
fx set minimal.x64
```
<aside class="key-point">
You can also invoke GN directly with <code>fx gn</code> to customize or
troubleshoot the build.
</aside>
You should run the GN configuration step anytime you want to adjust the product
configuration or the packages available to the build. GN is also invoked
automatically during a build anytime one of the `BUILD.gn` files in the current
configuration is changed.
## Boards and products
The Fuchsia build system defines the baseline configuration for a Fuchsia build
as a combination of a **product** and **board**. Together, these elements form
the build configuration you provide to `fx set`.
Boards define the architecture that the build targets, which may affect what
drivers are included and influence device specific kernel parameters.
This codelab targets the `x64` board, which supports the Fuchsia emulator
(FEMU) running on x64 architecture.
<aside class="key-point">
You can discover all the available target boards with
<code>fx list-boards</code>.
</aside>
A product defines the software configuration that a build produces. This
configuration may include what services are available and the user-facing
experience.
This codelab targets the `minimal_eng` product.
<aside class="key-point">
You can discover all the available target products with
<code>fx list-products</code>.
</aside>
## Build
Once the GN build configuration is complete, Ninja consumes the generated build
files and runs the appropriate compile, link, and packaging commands to generate
the Fuchsia image.
The build system invokes Ninja when you run the `fx build` command to execute
the current build configuration.
```posix-terminal
fx build
```
<aside class="key-point">
You can also invoke Ninja directly with <code>fx ninja</code> to customize or
troubleshoot the build.
</aside>
## Exercise: Build Minimal
In this exercise, you'll build the `minimal_eng` product configuration from
source to run on the `x64` emulator board.
### Configure the build
Set up the build environment for the `minimal` product and `x64` board:
```posix-terminal
fx set minimal.x64
```
This command runs GN on the set of targets defined in the product's build
configuration to produce the build instructions. **It does not actually
perform the build**, but instead defines the parameters of what is considered
buildable.
<aside class="key-point">
You can also ask GN to regenerate the existing build configuration using
<code>fx gen</code> without needing to supply the product configuration again.
This can be helpful when you are editing <code>BUILD.gn</code> files and want to
quickly validate without running a full build.
</aside>
### Inspect the build configuration
Once the build is configured, use `fx list-packages` to print the set of
packages the build is aware of:
```posix-terminal
fx list-packages
```
This is a useful tool to determine if a package you need was properly included
in the build configuration.
### Build Fuchsia Minimal
Build the Minimal target with `fx build`:
<aside class="caution">
A full build on a fresh checkout of the source can take upwards of 60-90 minutes
to complete, depending on the capabilities of the build machine. Subsequent
incremental builds will only take a few minutes.
</aside>
```posix-terminal
fx build
```
<<../_common/_restart_femu.md>>
### Inspect the device
Open another terminal window and run the following command to print the details
of your device target:
Note: See the full [`ffx` reference documentation](/reference/tools/sdk/ffx.md).
```posix-terminal
ffx target show
```
Look for the build configuration of the target output:
```none {:.devsite-disable-click-to-copy}
{{ '<strong>' }}Version: "2000-01-01T12:00:00+00:00"{{ '</strong>' }}
Product: "minimal_eng"
Board: "x64"
{{ '<strong>' }}Commit: "2000-01-01T12:00:00+00:00"{{ '</strong>' }}
```
Notice that the configuration points to the build you just completed on your
machine.
You are now running your own build of Fuchsia!
## Exercise: Run a repository server and serve packages
In this exercise, you'll run a repository server to serve the packages available
in the `universe` set to your running Fuchsia target on the emulator.
To learn more about repository and the different package sets, refer
to [RFC-0212 Package Sets](/docs/contribute/governance/rfcs/0212_package_sets.md)
For example, running `ffx debug connect` will fail because the target needs the
a component that exposes the `fuchsia.debugger.Launcher` capability. This is
available in the `debug_agent` package in the `universe` set of `minimal.x64`.
### List the packages in the universe set
Run `fx list-packages` to list the packages in the `universe` set. For
`minimal.x64` there is only one package:
```posix-terminal
fx list-packages --universe
```
The output shows only `debug_agent` package. The `debug_agent` includes a
component that provides the `fuchsia.debugger.Launcher` capability. We will
exercise this capability by launching a debugger in the next steps.
### Start a repository server and register it with the Fuchsia target
The `fx serve` command starts the repository server and registers it with
the target.
```posix-terminal
$ fx serve
```
You will see the following output if the command is run successfully:
```posix-terminal
2024-05-20 12:51:03 [serve] Discovery...
2024-05-20 12:51:07 [serve] Device up
2024-05-20 12:51:07 [serve] Registering devhost as update source
Serving repository '/usr/local/google/home/amituttam/fuchsia/out/minimal.x64/amber-files' to target 'fuchsia-emulator' over address '[::]:8083'.
```
Leave this command running the foreground. To run in verbose mode pass the
`--verbose` or `-v` flag to `fx serve`.
## Exercise: Run the debugger and list the running processes
With the repository server running, and the Fuchsia target configured to resolve
packages from that repository, we can run a command that resolves the package
and runs the component within.
First, let's run logs so we can see what is happening:
```posix-terminal
ffx log --filter debug_agent
```
Run the above command in a separate terminal, the output will be empty. Leave
the command running. Here, we are filtering on `debug_agent` as the system will
need to resolve that package to run the debugger.
In the other terminal, connect the debugger to the running system:
```posix-terminal
ffx debug connect
```
The command should launch `zxdb` and place you in an interactive shell. If you
switch back to the other terminal with the running `ffx log`, you will see
output along the lines of:
```
[01949.544917][pkg-resolver] INFO: attempting to resolve fuchsia-pkg://fuchsia.com/debug_agent as fuchsia-pkg://devhost/debug_agent with TUF
[01949.624075][pkg-resolver] INFO: updated local TUF metadata for "fuchsia-pkg://devhost" to version RepoVersions { root: 9, timestamp: Some(1715399460), snapshot: Some(1715399460), targets: Some(1715399460) } while getting merkle for TargetPath("debug_agent/0")
[01949.835760][pkg-resolver] INFO: resolved fuchsia-pkg://fuchsia.com/debug_agent as fuchsia-pkg://devhost/debug_agent to 3f9783abed30d70b72d5f0730bd6e6033481073126aac0b74cbbf2d14909497e with TUF
[01949.882891][debugger] INFO: [main_launcher.cc(182)] Start listening on FIDL fuchsia::debugger::Launcher.
```
Here the system attempts to resolve the `debug_agent` package and is able to do
so from the configured `devhost` repository. Once it resolves the package, the
component is launched that listens for the debugger launcher protocol.
Back to `zxdb`, you can now run `ps` to see the list of running processes on
the system.
```
[zxdb] ps
j: 1033 root
p: 1102 bin/component_manager
j: 1649
j: 1780 bootstrap/console fuchsia-boot:///console#meta/console.cm
p: 1822 console.cm
j: 1989 bootstrap/archivist fuchsia-boot:///archivist#meta/archivist.cm
p: 2051 archivist.cm
j: 2064 bootstrap/console-launcher fuchsia-boot:///console-launcher#meta/console-launcher.cm
...
```