Run an example component

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:

  1. Open a terminal and run fx serve:

    fx serve
  2. 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
  3. 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.