工作階段是 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 中的以下程式碼行:
- 檔案一開始會加入其他 cml 檔案 (如有需要)。 - include: [ "inspect/client.shard.cml", "syslog/client.shard.cml", ],- 這個 - include鍵可讓工作階段元件使用- fuchsia.logger.LogSink能力,以便將資訊列印到系統記錄檔。
- 接下來是 - 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 執行器執行元件二進位檔。
- 最後,元件資訊清單會說明元件可以 - use、- offer或- expose的其他功能。- // 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!」。log::info! 是巨集,會以 info 層級輸出至記錄。error 和 warn 也有類似的巨集。
寫入 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
建構工作階段
如要建構工作階段,必須先使用 //local/BUILD.gn 覆寫組合設定值,以便將 session_manager、工作階段元件和工作階段設定納入基本套件組合。這項操作是透過 assembly_developer_overrides 範本完成。
  import("//build/assembly/developer_overrides.gni")
assembly_developer_overrides("custom_session") {
    base_packages = [
      "//path/to/your/session"
    ]
    platform = {
      session = {
        enabled = true
      }
    }
    product = {
      session = {
        url = "fuchsia-pkg://fuchsia.com/pkg-name#meta/your_session.cm"
      }
    }
  }
  
接著,您必須使用 fx set 指令,在建構中加入自訂工作階段設定。
fx set minimal.x64 --assembly-override=//local:<var>custom_session</var>如果您使用的是 //src/session/examples 目錄中的範例專案,assembly_developer_overrides 會是:
  assembly_developer_overrides("hello-world-session") {
     platform = {
        session = {
           enabled = true
        }
     }
     product = {
        session = {
           url = "fuchsia-pkg://fuchsia.com/hello-world-session#meta/hello-world-session.cm"
        }
     }
  }
  並在 fx set 引數中加入建構目標:
fx set minimal.x64 --assembly-override=//local:hello-world-session
完成後,建構的 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!