This guide shows you how to build Fuchsia to include an example package from
Fuchsia's source //examples
directory and run a component on
your Fuchsia target.
Prerequisites
Before you can run an example component, you must:
Exploring the example
This example component prints Hello, world!
to the system log. The example has
three main elements:
- An executable binary written in a supported language.
- A component manifest (
.cml
) file to declare the component and its capabilities. - A
BUILD.gn
file to define the component build target and include it in a Fuchsia package.
Executable program
Fuchsia components can execute programs written in any language with a supported runtime. The most common runtime used for C++ and Rust programs is the ELF runner.
C++
#include <iostream>
int main() {
std::cout << "Hello, World!\n";
return 0;
}
Rust
fn main() {
println!("{}, world!", greeting());
eprintln!("{}, world!", greeting());
}
fn greeting() -> String {
return String::from("Hello");
}
Component manifest
A component manifest describes how to run a Fuchsia program as a component . This includes declaring program binary, runtime information, and any capabilities the component requires to execute, such as logging support.
C++
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
{
// Enable system logging capabilities
include: [ "syslog/client.shard.cml" ],
// Information about the program to run
program: {
// Use the built-in ELF runner for the executable
runner: "elf",
binary: "bin/hello_world_cpp",
// Enable stdout logging
forward_stderr_to: "log",
forward_stdout_to: "log",
},
}
Rust
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
{
// Enable system logging capabilities
include: [ "syslog/client.shard.cml" ],
// Information about the program to run
program: {
// Use the built-in ELF runner for the executable
runner: "elf",
binary: "bin/hello_world_rust",
// Enable stdout logging
forward_stderr_to: "log",
forward_stdout_to: "log",
},
}
For more details on component manifests and their declaration syntax, see component manifests.
BUILD.gn
Fuchsia uses the Generate Ninja (GN) meta-build system to generate inputs for
Ninja, which executes the actual build.
The BUILD.gn
file declares the build targets for a fuchsia_component()
and
fuchsia_package()
.
C++
executable("bin") {
output_name = "hello_world_cpp"
sources = [ "hello_world.cc" ]
}
fuchsia_component("hello-world-cpp-component") {
deps = [ ":bin" ]
# Defines the name given to the manifest when included in a fuchsia package.
# In this case: "hello-world-cpp.cm"
component_name = "hello-world-cpp"
manifest = "meta/hello_world_cpp.cml"
}
fuchsia_package("hello-world-cpp") {
deps = [
# component-url: fuchsia-pkg://fuchsia.com/hello-world-cpp#meta/hello-world-cpp.cm
":hello-world-cpp-component",
]
}
Rust
rustc_binary("bin") {
name = "hello_world_rust"
# Generates the "bin_test" build target
with_unit_tests = true
edition = "2021"
deps = []
test_deps = [ "//src/lib/fuchsia" ]
sources = [ "src/main.rs" ]
}
fuchsia_component("hello-world-rust-component") {
deps = [ ":bin" ]
# Defines the name given to the manifest when included in a fuchsia package.
# In this case: "hello-world-rust.cm"
component_name = "hello-world-rust"
manifest = "meta/hello_world_rust.cml"
}
fuchsia_package("hello-world-rust") {
deps = [
# component-url: fuchsia-pkg://fuchsia.com/hello-world-rust#meta/hello-world-rust.cm
":hello-world-rust-component",
]
}
To learn more about how Fuchsia uses GN to define components and packages, see: Building components.
Include the example package in your Fuchsia image
To include the example package in your build configuration, use the --with
flag
when setting your product and board environment:
fx set product.board --with //examples/hello_world
For a Fuchsia emulator with the minimum build configuration, the command is:
fx set core.x64 --with //examples/hello_world
In this example, core
is a product with a minimal feature set, which includes
common network capabilities, and x64
refers to the x64 architecture.
For a Fuchsia device with the minimum build configuration, the command is:
fx set core.x64 --with //examples/hello_world
See Configure a build for more options.
Once you have set your build configuration, build Fuchsia with the following command:
fx build
You now have a build that includes the example package that can be fetched and launched on demand.
Explore your product configuration
You can explore the contents of your product configuration using the
list-packages
command.
List all:
fx list-packages
There may be many entries, so add the name to find the one you're looking for:
fx list-packages hello-world
hello-world
hello-world-cpp-unittests
hello-world-rust-tests
Run the example component
To run a Fuchsia component, use its
Fuchsia package URL
as an argument
to the run
command:
Open a terminal and run
fx serve
:fx serve
Open another terminal and run the example component:
C++
ffx component run /core/ffx-laboratory:hello-world-cpp fuchsia-pkg://fuchsia.com/hello-world-cpp#meta/hello-world-cpp.cm
Rust
ffx component run /core/ffx-laboratory:hello-world-rust fuchsia-pkg://fuchsia.com/hello-world-rust#meta/hello-world-rust.cm
Open another terminal and view the system log:
ffx log --filter hello-world
The component prints the following output to the log:
[ffx-laboratory:hello-world] INFO: Hello, World!
Troubleshooting
If fx serve
is not running, the command prints an error message from the
device or emulator.
If fx serve
is running, but the package is not found,
repeat these steps and rebuild your Fuchsia image to
include the appropriate packages.