blob: 67be906dbe19c11918bd401ea68b08536b4e4a79 [file] [log] [blame] [view]
# Software Assembly
**Software Assembly** enables developers to quickly build a product using a
customized operating system. Concretely, Software Assembly is a set of tools
that produce a Product Bundle (PB) from inputs including a set of Fuchsia
packages, a kernel, and config files.
## Product Bundle {:#product-bundle}
A **Product Bundle** is a directory of well-specified artifacts that can be
shipped to any environment and is used to flash, update, or emulate a Fuchsia
target. It's not expected that developers inspect the contents of a Product
Bundle directly, instead they can rely on the tools provided by Fuchsia. For
example, the `ffx` tool is used to flash or emulate a device using a Product
Bundle:
```shell {:.devsite-disable-click-to-copy}
# Flash a hardware target with the product bundle.
$ ffx target flash --product-bundle <PATH/TO/PRODUCT_BUNDLE>
# Start a new emulator instance with the product bundle.
$ ffx emu start <PATH/TO/PRODUCT_BUNDLE>
```
A Product Bundle may contain both a **main** and a **recovery** product, which
are distinct bootable experiences. Oftentimes `main` is used for the real
product experience, and `recovery` is used if `main` is malfunctioning and
cannot boot. `recovery` is generally a lightweight experience that is
capable of addressing issues in the `main` slot using a factory reset or an
Over-The-Air (OTA) update. Typically, an end-user can switch which product to
boot into by holding a physical button down on a device during boot up.
Software Assembly offers build tools for constructing Product Bundles, defines
the format of the inputs (platform, product config, board config), and provides
build rules to construct those inputs.
![A product bundle containing both a main product and a recovery product](images/software_assembly_01.svg "Diagram a main and recovery product in a product bundle"){: width="600"}
**Figure 1**. A Product Bundle may contain both a main product and a recovery
product.
Note: The terms _product, product image, system_, and _slot_ are often used
interchangeably.
## Platform, product config, and board config {:#platform-product-config-and-board-config}
The three inputs to assembly (**platform**, **product config**, **board
config**) are directories of artifacts. The internal format is subject to
change and shouldn't be depended on. Developers need to use the provided Bazel
or GN build rules to construct and use these inputs.
* The **platform** is produced by the Fuchsia team. It contains every bit of
compiled platform code that any Fuchsia product may want to use. The Fuchsia
team releases the platform to
[https://chrome-infra-packages.appspot.com/p/fuchsia/assembly/platform][cipd-platform].
* The **product config** is produced by a developer defining the end-user
experience. It may contain flags indicating which features of the platform to
include. For example, the product config can set `platform.fonts.enabled=true`,
resulting in assembly including the relevant fonts support from the platform.
See [this reference][platform-flags] for all the available flags. The product
config can additionally include custom code for building the user experience.
* The **board config** is produced by a developer supporting a particular
hardware target. It includes all the necessary drivers to boot on that hardware.
Additionally, the board config can declare which hardware is available to be
used by the platform. For example, if the hardware has a Real Time Clock (RTC),
the board config can indicate that by setting the
`provided_features=["fuchsia::real_time_clock"]` flag. Assembly reads this
flag and includes the necessary code from the Platform for using this piece of
hardware. The Fuchsia team maintains a small set of board configs and releases
them to
[https://chrome-infra-packages.appspot.com/p/fuchsia/assembly/boards][cipd-boards].
## How Software Assembly is invoked {:#how-software-assembly-is-invoked}
At its core, Fuchsia's software assembly is a rust library used by several
different CLI tools to produce a Product Bundle. The following depics the
most common ways to invoke assembly:
* **Build system integration (Bazel and GN)**: Build systems like Bazel and GN
provide simple build targets (e.g., `fuchsia_product_bundle` in Bazel) that
handle the complexity of generating the correct input files and invoking the
assembly tools for you. This is the most common and recommended way to
use software assembly.
Note: Fuchsia is actively moving to [Bazel][fuchsia-product-bundle], so this
page does not provide details for the GN environment.
* **ffx product-bundle create**: The quickest way to produce a one-off product
bundle for testing is to use `ffx product-bundle create`. This tool is
especially useful when working with prebuilt platform, product, and board
configurations as it allows for very fast assembly without a full
build system integration.
### Bazel
```bazel {:.devsite-disable-click-to-copy}
# A product bundle can contain both 'main' and 'recovery' products (systems/slots).
fuchsia_product_bundle(
name = "my_product_bundle",
main = ":main_product",
recovery = "...",
)
# A product is a single bootable experience that is built by combining
# a platform, product configuration, and board configuration.
fuchsia_product(
name = "main_product",
platform = "//platform:x64",
product = ":my_product",
board = "//boards:x64",
)
# A product configuration defines the user experience by enabling
# platform features and including custom product code.
fuchsia_product_configuration(
name = "my_product",
product_config_json = {
platform = {
fonts = {
enabled = True,
},
},
},
# The product code is included as packages.
base_packages = [ ... ],
)
```
For a complete example, see the [`getting-started`][getting-started-repo]
repository.
### Command line interface
```shell {:.devsite-disable-click-to-copy}
ffx product-bundle create --platform 28.20250718.3.1 \
--product-config <PATH/TO/MY_PRODUCT_CONFIG> \
--board-config cipd://fuchsia/assembly/boards/x64@version:28.20250718.3.1
```
The [`ffx product-bundle create`][ffx-product-bundle-create] command can be run to produce
a new product bundle using already built platform, board, and product artifacts.
## Static analysis tools {:#static-analysis}
Software Assembly provides tools for verifying the quality of a Product Bundle.
The **size check** tool informs the user whether the Product Bundle fits within
the partition size constraints of the target hardware. A [product size
report][size-check] can be generated using the following Bazel rules:
```bazel {:.devsite-disable-click-to-copy}
fuchsia_product_size_check(
name = "main_product_size_report",
product_image = ":main_product",
)
fuchsia_product(
name = "main_product",
...
)
```
The **scrutiny** tool ensures that the Product Bundle meets a set of security
standards. If a developer provides the necessary scrutiny configs,
[scrutiny][scrutiny] runs during the construction of a Product Bundle. See the
following scrutiny configuration example:
```bazel {:.devsite-disable-click-to-copy}
fuchsia_product_bundle(
name = "my_product_bundle",
main = ":main_product",
main_scrutiny_config = ":main_scrutiny_config",
)
fuchsia_scrutiny_config(
name = "main_scrutiny_config",
base_packages = [ ... ], # Allowlist of base packages to expect.
kernel_cmdline = [ ... ], # Allowlist of kernel arguments to expect.
pre_signing_policy = "...", # File containing the policies to check before signing.
)
```
Note: The `ffx product create` command doesn't support running size checks or scrutiny.
## Appendix: Developer overrides {:#developer-overrides}
Developers oftentimes want to locally test something on an existing product
by adding new code or flipping a feature flag. Modifying the product or board
configs is undesirable because it pollutes the git-tree (`fuchsia.git`).
Assembly supports a method of locally modifying an existing product without
polluting the git-tree using [developer overrides][developer-overrides].
<!-- Reference links -->
[cipd-platform]: https://chrome-infra-packages.appspot.com/p/fuchsia/assembly/platform
[platform-flags]: https://fuchsia.dev/reference/assembly/PlatformSettings
[cipd-boards]: https://chrome-infra-packages.appspot.com/p/fuchsia/assembly/boards
[fuchsia-product-bundle]: https://fuchsia.dev/reference/bazel_sdk/fuchsia_product_bundle
[getting-started-repo]: https://fuchsia.googlesource.com/sdk-samples/getting-started
[ffx-product-bundle-create]: https://fuchsia.dev/reference/tools/sdk/ffx#ffx_product-bundle_create
[size-check]: https://fuchsia.dev/reference/bazel_sdk/fuchsia_product_size_check
[scrutiny]: https://fuchsia.dev/reference/bazel_sdk/fuchsia_scrutiny_config
[developer-overrides]: /docs/development/build/assembly_developer_overrides.md