Fuchsia build 使用 Generate Ninja (GN),这是一个元构建系统,用于生成 Ninja 使用的 build 文件,后者会执行实际 build。构建系统提供了用于为特定产品配置 build 的工具,以及用于为 Fuchsia 目标构建代码的模板。
编译目标
您可以使用位于项目源代码中的 BUILD.gn
文件为 GN 定义各个构建目标。Fuchsia 构建系统会将模板作为 GN 导入项 (.gni
) 提供给您,以便您声明 Fuchsia 工件,例如:
fuchsia_component()
:定义一个包含清单、程序二进制文件和资源的可执行组件。fuchsia_package()
:定义一个包含一个或多个组件以在软件包仓库中分发的软件包。fuchsia_test_package()
:定义包含测试组件的软件包。
以下是包含测试的简单组件软件包的 BUILD.gn
文件示例:
import("//build/components.gni")
executable("bin") {
sources = [ "main.cc" ]
}
fuchsia_component("hello-world-component") {
deps = [ ":bin" ]
manifest = "meta/hello-world.cml"
}
fuchsia_package("hello-world") {
deps = [
":hello-world-component",
]
}
fuchsia_component("hello-world-test-component") {
testonly = true
deps = [ ":bin_test" ]
manifest = "meta/hello-world-bin-test.cml"
}
fuchsia_test_package("hello-world-tests") {
test_components = [ ":hello-world-test-component" ]
}
由目标的名称和其 BUILD.gn
文件的路径组成的唯一标签用于标识可以参与 build 的所有内容。在上面的示例中,hello-world
目标的标签可能如下所示://src/examples/basic:hello-world
。
build 配置
GN 前端会根据所选的 Fuchsia 产品配置配置 build,收集 build 所需的所有必要软件包和组件。这些目标在源代码树中的各种 BUILD.gn
文件中定义。GN 步骤的输出是 build 目录中针对 Ninja 的一组经过优化的指令。
当您运行 fx set
命令来配置 build 时,构建系统会调用 GN。
fx set minimal.x64
每当您想要调整产品配置或 build 可用的软件包时,都应运行 GN 配置步骤。此外,每当当前配置中的某个 BUILD.gn
文件发生更改时,系统都会在构建期间自动调用 GN。
面板和产品
Fuchsia 构建系统将 Fuchsia 构建的基准配置定义为产品和开发板的组合。这些元素共同构成了您提供给 fx set
的 build 配置。
开发板定义了 build 目标的架构,这可能会影响包含的驱动程序以及设备专用内核参数。
此 Codelab 以 x64
开发板为目标平台,该开发板支持在 x64 架构上运行的 Fuchsia 模拟器 (FEMU)。
产品定义了 build 生成的软件配置。此配置可能包括可用服务和面向用户的体验。
此 Codelab 以 minimal_eng
产品为目标平台。
构建
GN 构建配置完成后,Ninja 会使用生成的构建文件,并运行适当的编译、链接和打包命令来生成 Fuchsia 映像。
当您运行 fx build
命令以执行当前构建配置时,构建系统会调用 Ninja。
fx build
练习:构建 Minimal
在本练习中,您将从源代码构建 minimal_eng
产品配置,以便在 x64
模拟器开发板上运行。
配置 build
为 minimal
产品和 x64
开发板设置构建环境:
fx set minimal.x64
此命令会对产品 build 配置中定义的一组目标运行 GN,以生成 build 说明。它实际上不会执行构建操作,而是定义了可构建内容的参数。
检查 build 配置
配置 build 后,使用 fx list-packages
输出 build 知晓的一组软件包:
fx list-packages
这是一个实用工具,可用于确定您需要的软件包是否已正确包含在 build 配置中。
构建 Fuchsia Minimal
使用 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: "minimal_eng"
Board: "x64"
Commit: "2000-01-01T12:00:00+00:00"
请注意,该配置指向您刚刚在机器上完成的 build。
现在,您正在运行自己的 Fuchsia build!
练习:运行代码库服务器并分发软件包
在本练习中,您将运行代码库服务器,以将 universe
中提供的软件包分发到模拟器上运行的 Fuchsia 目标。
如需详细了解代码库和不同的软件包集,请参阅 RFC-0212 软件包集
例如,运行 ffx debug connect
将会失败,因为目标需要公开 fuchsia.debugger.Launcher
capability 的组件。此方法可在 minimal.x64
的 universe
集中的 debug_agent
软件包中使用。
列出“universe”集中的软件包
运行 fx list-packages
以列出 universe
集中的软件包。对于 minimal.x64
,只有一个软件包:
fx list-packages --universe
输出仅显示 debug_agent
软件包。debug_agent
包含一个提供 fuchsia.debugger.Launcher
功能的组件。在后续步骤中,我们将通过启动调试程序来演示此功能。
启动代码库服务器并将其注册到 Fuchsia 目标
fx serve
命令会启动代码库服务器并将其注册到目标。
$ fx serve
如果命令成功运行,您将看到以下输出:
2024-05-20 12:51:03 [serve] Discovery...
2024-05-20 12:51:07 [serve] Device up
2024-05-20 12:51:07 [serve] Registering devhost as update source
Serving repository '/usr/local/google/home/amituttam/fuchsia/out/minimal.x64/amber-files' to target 'fuchsia-emulator' over address '[::]:8083'.
让此命令在前台运行。如需在详细模式下运行,请将 --verbose
或 -v
标志传递给 fx serve
。
练习:运行调试程序并列出正在运行的进程
代码库服务器运行后,并将 Fuchsia 目标配置为从该代码库解析软件包,我们就可以运行一个命令来解析软件包并运行其中的组件。
首先,我们运行日志,以便了解发生了什么:
ffx log --filter debug_agent
在单独的终端中运行上述命令,输出将为空。让该命令保持运行状态。在这里,我们过滤 debug_agent
,因为系统需要解析该软件包才能运行调试程序。
在另一个终端中,将调试程序连接到正在运行的系统:
ffx debug connect
该命令应启动 zxdb
并将您置于交互式 shell 中。如果您切换回运行 ffx log
的另一个终端,则会看到类似以下内容的输出:
[01949.544917][pkg-resolver] INFO: attempting to resolve fuchsia-pkg://fuchsia.com/debug_agent as fuchsia-pkg://devhost/debug_agent with TUF
[01949.624075][pkg-resolver] INFO: updated local TUF metadata for "fuchsia-pkg://devhost" to version RepoVersions { root: 9, timestamp: Some(1715399460), snapshot: Some(1715399460), targets: Some(1715399460) } while getting merkle for TargetPath("debug_agent/0")
[01949.835760][pkg-resolver] INFO: resolved fuchsia-pkg://fuchsia.com/debug_agent as fuchsia-pkg://devhost/debug_agent to 3f9783abed30d70b72d5f0730bd6e6033481073126aac0b74cbbf2d14909497e with TUF
[01949.882891][debugger] INFO: [main_launcher.cc(182)] Start listening on FIDL fuchsia::debugger::Launcher.
在这里,系统会尝试解析 debug_agent
软件包,并且能够从配置的 devhost
代码库中执行此操作。解析软件包后,系统会启动监听调试程序启动器协议的组件。
返回 zxdb
,您现在可以运行 ps
来查看系统上正在运行的进程列表。
[zxdb] ps
j: 1033 root
p: 1102 bin/component_manager
j: 1649
j: 1780 bootstrap/console fuchsia-boot:///console#meta/console.cm
p: 1822 console.cm
j: 1989 bootstrap/archivist fuchsia-boot:///archivist#meta/archivist.cm
p: 2051 archivist.cm
j: 2064 bootstrap/console-launcher fuchsia-boot:///console-launcher#meta/console-launcher.cm
...