Structured configuration allows C++/Rust components to declare configuration schemas directly in their manifest. Benefits of using structured configuration include:
ffx
tooling.To use structured configuration in your component, you must update build rules, declare a schema, define values, and generate a client library.
To prevent cyclic dependencies when generating client libraries, define a fuchsia_component_manifest
rule that compiles the component manifest. Pass this compiled manifest GN label into the fuchsia_component
rule.
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/cpp/BUILD.gn" region_tag="component" adjust_indentation="auto" %}
You must declare a configuration schema in a component's manifest. Structured config supports booleans, integers, strings and vectors of these types. The CML reference doc describes the complete syntax for a config schema.
{ ... {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/meta/config_example.cml" region_tag="config" %} }
You must define configuration values for a component's schema. The fuchsia_structured_config_values
GN template validates the defined values against the config schema and compiles them into a .cvf
file that must be packaged with your component.
There are two ways to define config values: in a JSON5 file or inline in GN.
You can write a component's configuration values in a JSON5 file. Because JSON5 is a strict superset of JSON, existing JSON configuration files can also be reused for structured config.
Each key in the JSON object must correspond to a config key in the schema and the value must be of a compatible JSON type:
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/config_example_default_values.json5" adjust_indentation="auto" %}
Provide the path to the JSON5 file in a fuchsia_structured_config_values
rule.
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/BUILD.gn" region_tag="config_values_json" adjust_indentation="auto" %}
The fuchsia_structured_config_values
template also supports defining configuration values inline:
{C++}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/cpp/BUILD.gn" region_tag="args_declare" adjust_indentation="auto" %} {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/cpp/BUILD.gn" region_tag="config_values_gn" adjust_indentation="auto" %}
{Rust}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/BUILD.gn" region_tag="args_declare" adjust_indentation="auto" %} {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/BUILD.gn" region_tag="config_values_gn" adjust_indentation="auto" %}
By using declare_args
, you can change configuration values on the command line at build time:
{C++}
$ fx set core.qemu-x64 \ --with //examples/components/config \ --args='config_example_cpp_greeting="C++ CLI Override"'
{Rust}
$ fx set core.qemu-x64 \ --with //examples/components/config \ --args='config_example_rust_greeting="Rust CLI Override"'
To package a component and a set of values together, add the fuchsia_component
and fuchsia_structured_config_values
rules as dependencies of a fuchsia_package
.
{C++}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/cpp/BUILD.gn" region_tag="package" adjust_indentation="auto" %}
{Rust}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/BUILD.gn" region_tag="package" adjust_indentation="auto" %}
The build system verifies your component's configuration schema and value file. A component with a faulty configuration (for example: field mismatch, bad constraints, missing value file) will fail to build.
Component manager validates a component's configuration when the component is resolved.
Use ffx component show
to print out a components configuration key-value pairs. The component does not have to be running for this to work.
$ ffx component show config_example Moniker: /core/ffx-laboratory:config_example Component State: Resolved ... Configuration: greeting -> "World" ...
Components read their resolved configuration values with a generated library. Generate a library using the following build templates:
{C++}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/cpp/BUILD.gn" region_tag="binary" adjust_indentation="auto" %} {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/cpp/BUILD.gn" region_tag="library" adjust_indentation="auto" %}
{Rust}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/BUILD.gn" region_tag="binary" adjust_indentation="auto" %} {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/BUILD.gn" region_tag="library" adjust_indentation="auto" %}
Use the following functions from the library to read configuration values:
{C++}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/cpp/main.cc" region_tag="imports" adjust_indentation="auto" %} ... {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/cpp/main.cc" region_tag="get_config" adjust_indentation="auto" %}
{Rust}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/src/main.rs" region_tag="imports" adjust_indentation="auto" %} ... {% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/src/main.rs" region_tag="get_config" adjust_indentation="auto" %}
You can export a components configuration to Inspect so that it is available in crash reports. The client libraries have functions to export a component's configuration to an Inspect tree:
{C++}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/cpp/main.cc" region_tag="inspect" adjust_indentation="auto" %}
{Rust}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/rust/src/main.rs" region_tag="inspect" adjust_indentation="auto" %}
Use ffx inspect show
to print out the component's exported configuration:
$ ffx inspect show core/ffx-laboratory\*config_example core/ffx-laboratory\:config_example: ... payload: root: config: greeting = World
You can use Realm Builder to dynamically replace the configuration values of a component.
{C++}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/integration_test/cpp/test.cc" region_tag="config_replace" adjust_indentation="auto" %}
{Rust}
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/components/config/integration_test/rust/lib.rs" region_tag="config_replace" adjust_indentation="auto" %}
Realm Builder validates the replaced value against the component's configuration schema.