The Fuchsia build is a large and complicated build, as it covers a wide variety of software and dependencies, both first and third party, from kernel up to multi-media user applications and whole-system constructions.
The Fuchsia build aims to provide common desirable build properties:
It is a goal of the Fuchsia architecture that all products may co-exist in a global Fuchsia ecosystem, sharing component addressability and updates throughout the ecosystem. In order to reach this goal, components that are provided a name in that ecosystem must have the same meaning regardless of the particulars of the build from which they are produced. If a build may produce a package called fortune
, there should not be any build configuration used to produce fortune
that alters the intended use case or behavior of fortune that is not considered a bug or a local-only workflow tool.
Examples of allowed configuration changes for a build target:
Examples of disallowed changes for a build target:
fortune
implements the com.fuchsia.FortuneExtra
interface.It must be possible for one configuration and invocation to build all possible feature axes and combinations. Products and image sets are composed with particular features by modulating the set of dependencies those products are composed from, rather than modulating the behavior or implementation of a particular component.
The following is a small example demonstrating the approach:
config("feature-foo") { cflags = [ "-DFOO=1" ] } executable("mytool-nofoo") { ... } executable("mytool-foo") { configs = [":feature-foo"] } package("mytool-with-foo") { deps = [":mytool-foo"] ... } package("mytool") { deps = [":mytool-nofoo"] ... }
An example of an undesirable approach is as follows:
declare_args() { enable_foo = false } executable("mytool") { if (enable_foo) { cflags = [ "-DFOO=1" ] } ... }
The above negative example would modulate the behavior, and definition of the component “mytool” based on build configuration, preventing the build from being able to build all possible configurations, and violating the component addressability scheme of the Fuchsia architecture.
It is often tempting to want to use specific board properties, or a board name to modulate the configuration or behavior of software. This is undesirable as products should run on a variety of target hardware. A board does not define a product, even if it might for a user. Instead, a board defines only a set of hardware properties.
Board package dependency configuration should ideally only provide configuration data and driver selection. Runtime or product software should not be reconfigured by the board, as the board as an abstraction cannot know what software configuration might run on it. For example, you may run the router product configuration on top of a VIM2 board configuration.
Packages often contain components with runtime configurable behavior and/or a need for additional data or metadata that a component consumes in order to function for a particular purpose. There are two commonly used methods to provide such data to a component, first to include that data in variations of the package, for example fortune-with-jokes
and fortune-without-jokes
, and the second to configure fortune
using config-data
provided data. The package configuration pattern is always preferred over the config-data mechanism where applicable, as it provides the maximum flexibility and longevity in the build and product composition system. Additionally, the config-data pattern is to be considered temporary - it does not yet solve the configuration management challenge well for all possible forms of product composition, and may not last through future architecture changes.
A build that invoked twice with no source code changes must perform no build actions. The ninja build system that is used in Fuchsia encodes a strong concept of a null build that is performed when ninja can observe no dirty inputs to any targets. A failure of a build configuration to be a null-build on repeated invocations is an indication of a configuration error in the build system that should be fixed promptly. Failures to null-build often indicate failures of hermetic build behavior or failures in repeatability of the build.
The following exceptions are recorded as known issues that may not be resolved for an extended time. Newly discovered issues of a similar issues are to be first treated as bugs rather than becoming new exceptions.
fx set
) to include a subset of the previously requested artifacts, some dependencies not relevant to the new configuration may be rebuilt, and sometimes this may lead to build failure. This is a known challenge of the build system and users are encouraged to clean their build tree when performing major or subtractive build configuration changes.