程式碼研究室:定義及建構產品組合

本程式碼研究室會逐步說明如何使用 Bazel 建構系統,在 Fuchsia 中定義及建構新產品套裝組合。產品組合是可發布的構件,內含刷寫、更新或模擬 Fuchsia 產品所需的所有映像檔和中繼資料。

在這個過程中,您也會定義產品設定,指定構成產品的軟體功能、設定和套件。

必要條件

什麼是產品設定?

Fuchsia 中的產品設定會定義特定產品的使用者體驗。這與主機板設定不同,主機板設定會指定硬體專屬詳細資料。產品設定通常包括:

  • 平台設定:基礎 Fuchsia 作業系統的設定 (例如建構類型、已啟用的系統功能)。
  • 產品設定:產品體驗專屬設定 (例如工作階段殼層、特定套件)。

產品設定是使用 BUILD.bazel 檔案中的 fuchsia_product_configuration 規則定義。

撰寫產品設定

我們來瞭解如何定義產品設定,並使用該設定建構系統映像檔。

基本設定

產品設定主要為傳遞至 fuchsia_product_configuration 規則的 JSON 物件 (以 Starlark 中的字典表示)。

# //products/my_product/BUILD.bazel
load(
    "@rules_fuchsia//fuchsia:assembly.bzl",
    "fuchsia_product_configuration",
)

fuchsia_product_configuration(
    name = "product_config",
    product_config_json = {
        "platform": {
            "build_type": "eng",
            "feature_set_level": "standard",
        },
        "product": {},
    },
)

平台設定

設定字典中的 platform 鍵可控管 Fuchsia 系統的各個層面。常見的欄位包括:

  • build_type:控制安全性和最佳化等級。
    • eng:工程建構版本。這個版本最適合用於偵錯,因為已啟用斷言,並停用最佳化功能。
    • userdebug:這個版本經過最佳化,與 user 版本類似,但啟用了一些偵錯功能和工具。
    • user:正式版建構作業。這個版本經過全面最佳化,安全無虞。
  • feature_set_level:定義系統中包含的基準功能集。
    • embeddable:Bootstrap 的最小子集。這個版本經過最佳化,可適用於記憶體受限的環境,且不會自動更新。
    • bootstrap:可啟動,僅限序號。僅限 /bootstrap 領域。沒有 netstack 或儲存空間驅動程式。主要用於板級啟動。
    • utility:包含 /core 領域的最小設定。適用於復原等公用程式類型的系統。
    • standard:完整的 Fuchsia 設定。包括 Netstack 和自我更新功能。此為預設值。
  • storage:設定檔案系統 (例如 Fxfs) 和儲存空間配置。

如需完整的平台設定清單,請參閱 PlatformSettings 說明文件

舉例來說,Fuchsia 產品設定和平台設定可能如下所示:

fuchsia_product_configuration(
    name = "product_config",
    product_config_json = {

        "platform": {
            "build_type": "eng",
            "feature_set_level": "standard",
            "storage": {
                "filesystems": {
                    "volume": "fxfs",
                },
            },
        },
        "product": {},

    },
)

產品設定

product 鍵用於較高層級的產品設定。

其中最重要的設定是工作階段。工作階段是定義產品使用者體驗的頂層元件 (例如圖形介面或主要應用程式)。

如要使用工作階段,您必須指定其網址,並確保包含元件的套件已納入基本套件

基礎套件是系統映像檔中包含的一組套件。這些屬性會在開機時立即提供,且不可變更 (唯讀),並會隨著系統 OTA 更新。

舉例來說,含有產品設定的 Fuchsia 產品設定可能如下所示:

範例:

fuchsia_product_configuration(
    name = "product_config",
    product_config_json = {
        "platform": {
            "build_type": "eng",
            "feature_set_level": "standard",
        },

        "product": {
            "session": {
                "url": "fuchsia-pkg://fuchsia.com/my_session#meta/my_session.cm",
            },
        },
    },
    base_packages = [
        "//src/my_session:my_session_package",
    ],

)

如需完整的產品設定清單,請參閱 ProductSettings 說明文件

組裝產品圖片

取得 fuchsia_product_configuration 後,您可以使用 fuchsia_product 規則組裝最終的系統映像檔。這項規則會將產品設定與特定開發板設定合併。

load(
    "@rules_fuchsia//fuchsia:assembly.bzl",
    "fuchsia_product",
)

fuchsia_product(
    name = "image.x64",
    board_config = "//boards:x64",
    platform_artifacts = "//build/bazel/assembly/assembly_input_bundles:platform_eng",

    product_config = ":product_config",

)
  • board_config:指向開發板設定目標。
  • platform_artifacts:指向要使用的平台構件 (AIB) 組合。

建立產品組合

如要在裝置或模擬器上執行產品,您需要使用 fuchsia_product_bundle 規則將產品套件至產品組合。

load(
    "@rules_fuchsia//fuchsia:assembly.bzl",
    "fuchsia_product_bundle",
)

fuchsia_product_bundle(
    name = "my_product.x64",
    product_bundle_name = "my_product.x64",

    main = ":image.x64",

)

這個目標會產生 ffx product-bundle 指令所需的構件。

例如:

  • 在模擬器中執行:

    ffx emu start my_product.x64
  • 將檔案刷入裝置:

    ffx target flash -b my_product.x64

向建構系統註冊

如要建構產品套裝組合,必須向 GN 建構系統註冊。其中包含下列步驟:

橋接至 GN

Fuchsia 的建構系統使用 GN,但產品套裝組合是在 Bazel 中定義。您必須使用 bazel_product_bundle GN 範本建立橋接器。

在產品目錄中建立 BUILD.gn 檔案 (例如//products/my_product/BUILD.gn):

# //products/my_product/BUILD.gn
import("//build/bazel/assembly/bazel_product_bundle.gni")

bazel_product_bundle("my_product.x64") {
  testonly = true
  product_bundle_name = "my_product.x64"
  bazel_product_bundle_target = ":my_product.x64"
  bazel_product_image_target = ":image.x64"
  bazel_inputs_from_gn = [
    "//boards/x64:x64.bazel_input",
    "//build/images/flash:esp.bazel_input",
  ]
  allow_eng_platform_bundle_use = true
}

加入許可清單

你可能需要在bazel_action_allowlist中新增產品,以免發生曝光錯誤://build/bazel/BUILD.gn

# //build/bazel/BUILD.gn
group("bazel_action_allowlist") {
  visibility = [
    # ...
    "//products/my_product:*",
  ]
  # ...
}

您可能也需要在//build/BUILD.gnnon_hermetic_deps可見度清單中新增該項目:

# //build/BUILD.gn
group("non_hermetic_deps") {
  visibility = [
    # ...
    "//products/my_product:*",
  ]
  # ...
}

這個 GN 目標 (:my_product.x64) 現在代表 GN 建構圖中的 Bazel 產品組合。

新增至可用的產品

最後,將這個新的 GN 目標新增至 //products/BUILD.gn 中的產品組合全域清單,讓 fx 能夠探索到:

# //products/BUILD.gn
group("product_bundles") {
  testonly = true
  deps = [
    # ... other products
    "//products/my_product:my_product.x64",
  ]
}

建構產品

Fuchsia 支援多產品建構作業,也就是說,您可以在同一個建構目錄中提供多項產品。

設定建構作業

使用 fx set 設定建構環境。您應使用啟用 Bazel 建構系統的產品設定,例如 fuchsia.x64

fx set fuchsia.x64

設定主要產品

如要使用特定產品,請將其設為「主要」產品組合。這會將 fx 工具預設為以您的產品為目標:

fx set-main-pb my_product.x64

建構產品

如要建構目前所選的主要產品 (及其依附元件):

fx build

如要明確建立特定產品組合,而不論主要設定為何:

fx build my_product.x64

切換產品

您可以隨時切換有效的「主要」產品組合,不必重新執行 fx set,只要再次執行 fx set-main-pb 即可:

fx set-main-pb minimal.x64

GN 引數與組件

在多產品建構環境中,所有產品都會共用相同的 GN 引數 (由 fx set 定義)。因此,您無法使用 fx set ... --args 設定產品專屬功能。所有產品設定都必須透過 fuchsia_product_configuration Bazel 規則完成,如本程式碼研究室所示。

後續步驟

本程式碼研究室涵蓋定義及建構新產品組合的基本概念。

如要繼續學習,請參閱下列文章: