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.gnfile 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_worldFor a Fuchsia emulator with the minimum build configuration, the command is:
fx set core.x64 --with //examples/hello_worldIn 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_worldSee Configure a build for more options.
Once you have set your build configuration, build Fuchsia with the following command:
fx buildYou 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-packagesThere 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-testsRun 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 serveOpen 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.cmRust
ffx component run /core/ffx-laboratory:hello-world-rust fuchsia-pkg://fuchsia.com/hello-world-rust#meta/hello-world-rust.cmOpen another terminal and view the system log:
ffx log --filter hello-worldThe 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.