编写“Hello World”会话

会话是常规组件,session_manager 可在 启动。也就是说,创建会话组件需要遵循 和创建任何其他组件一样的步骤本文档介绍了如何创建 在启动时启动并显示“Hello World!”的示例会话发送到系统 日志。

创建目录结构

组件需要特定的目录结构。fx 工具提供 生成器为您创建此结构。它接受 组件和要用作参数的语言。例如, 组件称为 hello-world-session,采用 Rust 编写。

运行以下命令,为此示例创建目录结构:

fx create component --path hello-world-session --lang rust

该命令使用模板创建以下目录结构: 组件:

hello-world-session
  |- meta
  |   |- hello-world-session.cml
  |
  |- src
  |   |- main.rs
  |
  |- BUILD.gn

创建组件清单

组件清单文件 (hello-world-session.cml) 声明了组件 送到 Fuchsia。在本示例中,使用默认清单就足够了,但 来探索 hello-world-session.cml 中的以下代码行:

  1. 该文件首先会根据需要添加其他 cml 文件。

    include: [
        "inspect/client.shard.cml",
        "syslog/client.shard.cml",
    ],
    
    

    通过此 include 键,会话组件可以使用 fuchsia.logger.LogSink 功能,以便输出到系统日志。

  2. 接下来是 program 代码块。

    // Information about the program to run.
    program: {
        // Use the built-in ELF runner to run native binaries.
        runner: "elf",
    
        // The binary to run for this component.
        binary: "bin/hello-world-session",
    },
    
    

    program 代码块会告知 component_manager 将 会话组件。runner 键会告知 component_manager 它应使用 ELF 运行程序来运行组件二进制文件。

  3. 最后,该组件清单描述了 组件可以是 useofferexpose

    // Capabilities used by this component.
    use: [
        // List your component's dependencies here, ex:
        // { protocol: "fuchsia.net.name.Lookup" }
    ],
    expose: [
        // session_manager uses this protocol to start the session.
        {
            protocol: "fuchsia.component.Binder",
            from: "framework",
        },
    ],
    
    

使用 Rust 编写会话

现在,您可以编写会话组件的实现了。在 生成的 src/main.rs 文件中包含大量不需要的代码 这个示例就介绍到这里

src/main.rs 的内容替换为以下代码:

use anyhow::Error;

/// Creates a simple session that just prints "Hello World" to the syslog.
#[fuchsia::main(logging = true)]
async fn main() -> Result<(), Error> {
    tracing::info!("Hello World!");

    Ok(())
}

此代码会初始化系统日志,然后输出“Hello World!”。 tracing::info! 是一个宏,可输出级别为 info 的日志。 errorwarn 也有类似的宏。

编写 BUILD.gn

要修改的最后一个文件是 BUILD.gn。这会告知编译器如何构建 会话组件

Rust 二进制文件

下一部分将介绍实际的 Rust 二进制文件。它会告诉编译器 二进制文件的名称应该是什么?其中包含单元测试 及其来源所在的位置。在此示例中, 依赖项即可:

rustc_binary("bin") {
  edition = "2021"
  output_name = "hello-world-session"

  # Generates a GN target for unit-tests with the label `bin_test`, and
  # a binary named `hello_world_session_bin_test`.
  with_unit_tests = true

  deps = [
    "//src/lib/fuchsia",
    "//third_party/rust_crates:anyhow",
    "//third_party/rust_crates:tracing",
  ]

  sources = [ "src/main.rs" ]
}

fuchsia_component()fuchsia_package() 模板可让 Fuchsia 了解更多详细信息 包括组件名称、清单的位置 以及软件包和组件的依赖项:

fuchsia_component("component") {
  component_name = "hello-world-session"
  manifest = "meta/hello-world-session.cml"
  deps = [ ":bin" ]
}

fuchsia_package("hello-world-session") {
  deps = [ ":component" ]
}

识别会话网址

session_manager 需要知道在启动时启动哪个会话组件, 通过提供会话的组成部分网址进行配置

组件网址采用以下格式:

fuchsia-pkg://fuchsia.com/package_name#meta/component_name.cm

请注意,该路径指向 .cm 文件。.cm 文件是编译版本 (共 .cml 个,这是运行 fx build 时生成的文件)。在这个示例中, 组件网址为:

fuchsia-pkg://fuchsia.com/hello-world-session#meta/hello-world-session.cm

构建会话

如需构建会话,必须先使用 fx set 来配置构建, session_manager,您的会话组件和会话配置 。这是使用 --with-base 标志完成的。会话 此外,还必须配置网址,这是使用 --args 标志完成的。

fx set core.x64 \
    --with-base //src/session/bin/session_manager \
    --with-base //path/to/your/session \
    --args=product_config.session_url = "fuchsia-pkg://fuchsia.com/<var>package_name</var>#meta/<var>component_name</var>.cm"

如果您使用的是 //src/session/examples 目录中的示例项目, fx set 命令将为:

fx set core.x64 \
    --with-base //src/session/bin/session_manager \
    --with-base //src/session/examples/hello-world-session \
    --args=product_config.session_url = "fuchsia-pkg://fuchsia.com/hello-world-session#meta/hello-world-session.cm"

完成上述操作并构建完毕后,session_manager 应该会自动启动您的 启动会话。您应该会看到“Hello”消息。

$ ffx log --filter hello
[session_manager] INFO: Launching session: fuchsia-pkg://fuchsia.com/hello-world-session#meta/hello-world-session.cm
[hello_world_session] INFO: Hello World!