产品配置封装了在底层硬件上支持目标用户体验所需的一组软件包和组件。每个产品配置都在 GN 导入 (.gni
) 文件中使用其 GN 标签声明其默认软件包列表。您可以通过几种不同的方式增强当前 build 配置的内容。
依赖项集
build 配置中的软件包会被分配给以下三个依赖项集之一:
- 基础:捆绑到系统映像中的系统关键型软件包。基础软件包始终会解析为系统映像中的版本,即使软件包代码库中提供了不同的版本也是如此。更新基础软件包需要进行系统 (OTA) 更新。
- 缓存:捆绑到系统映像的其他软件包。如果有其他版本可用,系统会从软件包代码库更新缓存的软件包。
- 宇宙:其他。这组软件包仅通过软件包代码库提供,并可按需分发。
以下是产品配置文件的代码段示例。此产品会继承 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 自定义
创建新的完整产品配置并不是自定义 build 的唯一方式。您还可以使用以下标志为 fx set
命令提供其他标签:
--with
:向 universe 依赖项集添加目标标签。--with-base
:向基本依赖项集添加目标标签。--with-cache
:向缓存依赖项集添加目标标签。
这是为开发临时启用您不希望包含在最终构建目标中的软件包(例如测试)的好方法。例如,以下命令会将 Fuchsia tests
软件包中的所有软件包添加到标准 workstation_eng
build 中。
fx set workstation_eng.x64 --with //bundles/tests
使用软件包进行开发
回想一下简介中提到的 Fuchsia 软件包不会“安装”到设备,而是从本地软件包缓存或软件包代码库进行解析。开发 Fuchsia 软件时,这意味着测试代码涉及以下步骤:
- 构建包含任何代码更改的更新软件包。
- 将更新后的软件包发布到软件包代码库。
- 在目标设备上触发更新。
fx build
等开发者工具会在构建流程中将软件包更新发布到本地软件包代码库。产品声明软件包的依赖项集决定了如何在目标设备上触发更新:
- 基本软件包只能通过执行整个系统更新 (OTA) 进行更新。使用
fx ota
触发系统更新或在设备上刷写新的系统映像,以更新基础软件包。 - 缓存和 Universe 软件包会在软件包下次解析时自动更新。
练习:自定义 build
在本练习中,您将临时在 universe 软件包集中包含其他软件包,使其可供目标设备使用,从而自定义 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
子命令探索构建目标。
首先,使用 desc
命令输出有关您刚刚添加到 build 的 //examples
软件包的详细信息。
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
命令向上查看构建图。它会报告对指定目标的传入引用。
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
查找目标输出的构建配置:
Version: "2000-01-01T12:00:00+00:00"
Product: "fuchsialab"
Board: "x64"
Commit: "2000-01-01T12:00:00+00:00"
恭喜!您刚刚基于 Fuchsia 构建了自己的自定义产品!