产品包

产品配置封装了一组必需的软件包和组件,用于在底层硬件上支持目标用户体验。每个产品配置都会在 GN 导入 (.gni) 文件中使用其 GN 标签声明默认的软件包列表。您可以通过几种不同的方式来扩充当前 build 配置的内容。

依赖项集

build 配置中的软件包会分配给以下三个依赖项集之一:

  • 基础:捆绑到系统映像中的系统关键软件包。基础软件包始终解析为系统映像中的版本,即使软件包代码库中提供了其他版本也是如此。更新基础软件包需要进行系统 (OTA) 更新。
  • 缓存:捆绑到系统映像中的其他软件包。如果软件包代码库中提供了不同的版本,则会更新缓存的软件包。
  • Universe:所有其他软件包。此组软件包只能通过软件包代码库获得,并按需交付。

此图显示了软件包在 build 配置的基本、缓存或全局依赖项集中所处的位置。此集决定了如何解析软件包的新版本。

以下是产品配置文件的一个示例代码段。此产品继承了 core 产品中定义的所有软件包,然后向每个依赖项集添加了一些额外的软件包:

import("//products/core.gni")

legacy_base_package_labels += [
  "//src/chromium:web_engine",
  "//src/fonts",
]

legacy_cache_package_labels += [
  "//src/media/playback/bundles:services",
]

discoverable_package_labels += [
  "//src/ui/examples:bouncing_ball",
]

在此示例中,构建系统会将运行时、资源和服务打包到目标设备的磁盘映像中。这些示例仅在需要时从软件包服务器获取。

手动构建自定义

创建新的完整产品配置并非自定义 build 的唯一方法。您还可以使用以下标志为 fx set 命令提供其他标签:

  • --with:向全集依赖项集添加目标标签。
  • --with-base:向基本依赖项集添加目标标签。
  • --with-cache:向缓存依赖项集添加目标标签。

这是一种临时启用开发软件包的好方法,这些软件包您不想包含在最终 build 目标中,例如测试。例如,以下命令会将 Fuchsia tests bundle 中的所有软件包添加到标准 workstation_eng build 中。

fx set workstation_eng.x64 --with //bundles/tests

使用软件包进行开发

在简介中我们提到过,Fuchsia 软件包不会“安装”到设备上,而是从本地软件包缓存或软件包代码库中解析。在开发 Fuchsia 软件时,这意味着测试代码需要执行以下步骤:

  1. 使用任何代码更改构建更新的软件包。
  2. 将更新后的软件包发布到软件包代码库。
  3. 在目标设备上触发更新。

此图显示了在开发过程中,开发者工具如何将软件包发布到 TUF 代码库,从而通知 Fuchsia 设备解析最新版本。

开发者工具(例如 fx build)会在构建流程中将软件包更新发布到本地软件包代码库。产品声明软件包的依赖项集决定了如何在目标设备上触发更新:

  • 只能通过执行整个系统更新 (OTA) 来更新基础软件包。 使用 fx ota 触发系统更新,或在设备上刷写新的系统映像以更新基础软件包。
  • 缓存和 universe 软件包会在下次解析软件包时自动更新。

练习:自定义 build

在此练习中,您将通过在全集软件包集中临时添加其他软件包来定制 workstation_eng build,从而使这些软件包可供目标设备使用。

向 build 中添加软件包

您可以使用 fx set--with 标志将其他目标与 build 配置捆绑在一起。重新配置 workstation_eng build 以包含所有 Fuchsia 示例:

fx set workstation_eng.x64 --with //examples

此选项通常用于添加需要在设备上运行的测试软件包,或者您正在开发但尚未包含在产品配置中的新软件包。

验证示例软件包是否已添加到 build 中:

fx list-packages example

使用 GN 探索 build 目标

GN 附带了一组强大的诊断工具,可用于检查 build 中配置的目标。请继续学习,了解如何使用 fx gn 子命令来探索 build 目标。

首先,使用 desc 命令打印有关您刚刚添加到 build 中的 //examples bundle 的详细信息。

fx gn desc out/default //examples

此命令会输出有关目标类型及其所有依赖项的详细信息。对于 //examples 软件包,依赖项列表表示添加到 build 中的各个示例软件包。

使用同一命令探索 hello-world 目标的详细信息。

fx gn desc out/default //examples/hello_world:hello-world

此目标表示包含多个组件软件包,因此您会看到其他依赖项,例如组件清单和软件包元数据。

再向下进入一个层级,探索 hello-world-rust 组件。

fx gn desc out/default //examples/hello_world/rust:hello-world-rust-component

从特定目标(例如 hello-world-rust 组件)的角度来看,您还可以使用 refs 命令在 build 图中向上查找。此报告会显示对指定目标的传入引用。

fx gn refs out/default //examples/hello_world/rust:hello-world-rust-component

最后,使用 path 命令报告任意两个目标之间的引用链。通过检查目标与 //:default 之间的引用路径,这有助于确定目标在 build 中包含的位置和方式。

fx gn path out/default //:default //examples/hello_world:hello-world

在模拟器中运行示例

再次运行 fx build 以构建更新后的软件包:

fx build

使用 ffx component 命令运行 Hello World 组件示例:

ffx component run /core/ffx-laboratory:hello-world-cpp fuchsia-pkg://fuchsia.com/hello-world-cpp#meta/hello-world-cpp.cm

打开一个新终端窗口,并过滤设备日志以查找示例中的消息:

ffx log --filter hello

您应该会在设备日志中看到以下输出内容:

[hello-world-cpp][I] Hello, World!

练习:创建新的 build 产品

在下一个练习中,您会将这些额外的软件包封装到扩展 workstation_eng 的新产品配置中。

声明产品配置

//vendor 下创建一个名为 fuchsia-codelab 的新目录:

mkdir -p vendor/fuchsia-codelab

//vendor/fuchsia-codelab/products 下创建一个包含以下内容的新文件 fuchsialab.gni

# Extend the workstation_eng product
import("//products/workstation_eng.gni")

这会创建一个名为 fuchsialab 的新商品,该商品扩展了 workstation_eng,并继承了它定义的所有软件包标签。

使用 fx list-products 命令验证构建系统是否识别您的新产品。您应该会在商品列表中看到 fuchsialab

fx list-products

为商品添加套餐

如需自定义产品中包含的特定软件包,请将其添加到产品配置中相应软件包集的标签。

将以下行添加到 //vendor/fuchsia-codelab/products/fuchsialab.gni,以在自定义产品中包含 Hello World 示例:

discoverable_package_labels += [
    "//examples/hello_world",
]

构建新产品

重新配置在 FEMU 板上运行的 fuchsialab 产品的 build:

fx set fuchsialab.x64

验证 Hello World 示例软件包现在是否已成为 build 的一部分:

fx list-packages hello

运行 fx build 为您的自定义商品生成新图片:

fx build

重启模拟器

  1. 运行以下命令以关闭当前打开的所有模拟器实例:

    ffx emu stop --all
  2. 启动新的模拟器实例:

    ffx emu start --headless

    启动完成后,模拟器会输出以下消息并返回:

    Logging to "$HOME/.local/share/Fuchsia/ffx/emu/instances/fuchsia-emulator/emulator.log"
    Waiting for Fuchsia to start (up to 60 seconds)........
    Emulator is ready.
    

检查设备

打开另一个终端窗口,然后运行以下命令以打印设备目标的详细信息:

ffx target show

查找目标输出的 build 配置:

Version: "2000-01-01T12:00:00+00:00"
Product: "fuchsialab"
Board: "x64"
Commit: "2000-01-01T12:00:00+00:00"

恭喜!您刚刚基于 Fuchsia 构建了自己的自定义产品!