产品配置封装了一组必需的软件包和组件,用于在底层硬件上支持目标用户体验。每个产品配置都会在 GN 导入 (.gni) 文件中使用其 GN 标签声明默认的软件包列表。您可以通过几种不同的方式来扩充当前 build 配置的内容。
依赖项集
build 配置中的软件包会分配给以下三个依赖项集之一:
- 基础:捆绑到系统映像中的系统关键软件包。基础软件包始终解析为系统映像中的版本,即使软件包代码库中提供了其他版本也是如此。更新基础软件包需要进行系统 (OTA) 更新。
- 缓存:捆绑到系统映像中的其他软件包。如果软件包代码库中提供了不同的版本,则会更新缓存的软件包。
- Universe:所有其他软件包。此组软件包只能通过软件包代码库获得,并按需交付。
以下是产品配置文件的一个示例代码段。此产品继承了 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 软件时,这意味着测试代码需要执行以下步骤:
- 使用任何代码更改构建更新的软件包。
- 将更新后的软件包发布到软件包代码库。
- 在目标设备上触发更新。
开发者工具(例如 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重启模拟器
运行以下命令以关闭当前打开的所有模拟器实例:
ffx emu stop --all启动新的模拟器实例:
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 构建了自己的自定义产品!