Fuchsia 构建系统旨在为各种设备构建启动映像和可更新的软件包。Fuchsia 构建系统使用 GN(一种元构建系统,可生成由 Ninja 使用的构建文件,后者会执行实际的构建)。
概念
如果您不熟悉 Fuchsia 的构建系统和 GN,请参阅使用 GN 构建,其中概述了 GN 构建系统的基本原则。
以下部分介绍了 Fuchsia 构建系统的一些概念。
开发板和产品
生成的 Fuchsia 映像的内容由主板和产品的组合控制。主板和产品是用于定义映像中包含的软件包和依赖项的 build 目标。如需详细了解这些 build 配置的结构和用法,请参阅主板和产品。
编译目标
build 目标在整个源代码树中存在的 BUILD.gn 文件中定义。这些文件使用类似于 Python 的语法来声明可构建的对象。
例如:
import("//build/some/template.gni")
my_template("foo") {
name = "foo"
extra_options = "//my/foo/options"
deps = [
"//some/random/framework",
"//some/other/random/framework",
]
}
GN 参考中定义了可用的命令(通过 gn CLI 工具调用)和内置目标声明类型。//build 项目的 .gni 文件中还有一些自定义模板。
Fuchsia 定义了许多自定义模板,以支持定义和构建 Fuchsia 特定的制品。
build 优化标志
使用 fx set 构建 Fuchsia 时,您可以指定 build 优化标志来控制编译时间、运行时性能和可调试性之间的权衡。build 优化标志包括 --debug、--balanced 和 --release。
选择合适的标志可显著影响您的开发工作流、构建时间和生成的映像的性能特征。
快速比较
--debug |
--balanced |
--release |
|
|---|---|---|---|
| 主要焦点 | 调试断言,经过优化,可与调试器搭配使用 | 编译速度快,运行时性能好。 | 最大限度提升运行时性能并尽可能缩小大小 |
| 编译时间 | 更快(增量) | 中等(对于某些目标,比发布版本快 2-4 倍) | 较慢 |
| 运行时性能 | 较慢 | 良好(适用于大多数开发场景) | 更快 |
| 二进制文件大小 | 变大 | 远小于调试 build,略大于发布 build | 变小 |
| 优化 | 最小 | 部分 | 完整 |
| 调试体验 | 完整 | 介于 debug 和 release 之间(可调试性略低于调试) |
最小 |
| 推荐使用场景 | 主动编码和调试 | 每日开发和更快迭代 | 制作、基准比较、性能分析、最终验证 |
设置编译模式
将所需标志附加到 fx set 命令:
fx set PRODUCT.BOARD [--debug | --balanced | --release]
例如:
fx set core.x64 --debugfx set core.x64 --balanced
为什么选择 --balanced?
引入 --balanced 标志是为了解决 --release build 的大量编译时间开销,尤其是对于大型 Rust 和 C++ 目标。通过选择性地启用优化并使用更快的替代方案(例如针对 C++ 使用 ThinLTO 而不是 Full LTO,以及针对 Rust 使用更多代码生成单元 [即编译时线程]),--balanced 可为需要优于调试性能的任务提供更好的开发者体验。
随着 Fuchsia 的发展,--release build 可能会纳入更激进(但编译速度可能更慢)的优化,例如 Rust Full LTO、PGO 和更高优化级别的性能关键型二进制文件。另一方面,如果您使用 --balanced,则可以进行性能感知开发,从而在保持良好运行时特征的同时,受益于持续的编译时改进。
build 优化标志的完整比较
本部分全面比较了构建优化标志:
--debug
- 主要目标:更快的增量编译速度,完全可调试。
- 优化:最少到无。代码编译后会尽可能接近源代码。
- 调试体验:包含完整的调试符号。
- 运行时性能:较慢。不适合进行性能测试或用于生产环境。
- 编译时间(完全重建):由于缺少优化传递,因此对于初始 build,通常比
--release和--balanced快。增量 build 通常是最快的。 - 应在以下情况下使用此功能:
- 积极开发和调试代码。
- 您需要使用调试程序逐步执行代码,并准确检查变量。
- 快速迭代比运行时性能更重要。
--balanced
- 主要目标:在编译速度和运行时性能之间取得平衡。
- 优化:一组精选的优化,可提供良好的运行时性能,而不会像
--release那样花费过多的编译时间。 - 调试体验:介于
--debug和--release之间,比发布版本略微更易于调试。某些优化可能会使精确调试比--debug更难。 - 运行时性能:良好。比完整的
--releasebuild 稍慢(在某些方面可能慢 10-20%),但比--debug快得多。 对于大多数开发和测试场景,性能通常可以接受。 - 编译时间:比
--release快得多。对于大型 Rust 目标,这可以快 2-4 倍。- 例如:
netstack3的编译速度快了 4 倍(70 秒对比 280 秒)。 - 例如:
component_manager的编译速度快了 2.6 倍(70 秒对 180 秒)。
- 例如:
- 应在以下情况下使用此功能:
- 如果您需要比
--debug更快的运行速度,但又想避免--release的长时间编译,则应将此模式设为默认编译模式。 - 一般开发和迭代,其中
--debug在运行时太慢。 - 当您需要测试性能合理的功能,但又不想等待完整发布版本时。
- 为了受益于持续的编译时改进,因为此模式正在积极优化速度。
- 如果您需要比
--release
- 主要目标:最大限度地提高运行时性能,并尽可能缩小二进制文件大小。
- 优化:已启用全面优化。这包括以下激进技术:
- 链接时优化 (LTO),通常是完整 LTO。
- 配置文件引导的优化 (PGO)(如适用)。
- 更高的编译器优化级别(例如,
-O3)。
- 调试体验:极简。调试可能非常困难。
- 运行时性能:最快。此模式适用于基准测试和生产部署。
- 编译时间:最慢,因为需要进行广泛的优化传递和 LTO。
- 应在以下情况下使用此功能:
- 为生产或部署构建。
- 运行性能基准。
- 您需要尽可能小的二进制文件大小和尽可能高的运行时速度,并且愿意接受较长的 build 时间。
执行 build
执行 build 的最简单方法是通过 fx 工具使用 fx set 来配置 build,然后使用 fx build,如 fx 工作流中所述。
配置 build
通过选择要构建的 board 和 product 来配置主要 build 工件:
fx set
fx set core.x64您还可以为此命令设置优化标志。请参阅build 优化标志。例如:
fx set core.x64 --balancedfx gn gen
fx gn gen $(fx get-build-dir) --args='import("//boards/x64.gni") import("//products/core.gni")'如需查看所有 GN build 实参的列表,请运行:
fx gn args $(fx get-build-dir) --list这会创建一个包含 Ninja 和 Bazel 文件的 build 目录(通常为 out/default)。
生成 build
使用 fx set 配置 build 制品后,您就可以构建 Fuchsia 了:
fx build
fx build这是 fx build 在底层运行的内容。
正在重新构建
如需在修改源代码后重新构建树,只需重新运行 fx build。如果您修改 BUILD.gn 文件,此规则也适用,因为 GN 会添加 Ninja 目标,以便在构建文件发生更改时更新 Ninja 目标。用于配置 build 的其他文件也是如此。
超全攻略
这些提示和技巧仅适用于使用 fx gn 命令。
检查 GN 目标的内容
fx gn desc $(fx get-build-dir) //path/to/my:target查找对 GN 目标的引用
fx gn refs $(fx get-build-dir) //path/to/my:target构建宿主的引用目标
各种主机工具(有些在 build 本身中使用)需要与最终映像一起构建。
如需从 BUILD.gn 文件中引用主机工具链的 build 目标,请执行以下操作:
//path/to/target($host_toolchain)
仅构建特定目标
如果目标在 GN build 文件中定义为 //foo/bar/blah:dash,则可以使用以下命令构建该目标(及其依赖项):
fx build
fx build //foo/bar/blah:dashfx build --host
fx build --host //foo/bar/blah:dash调试 build 时间问题
运行 build 时,Ninja 会保留可用于查看构建流程步骤的日志。如需分析特定 build 迭代的时序,请执行以下操作:
像往常一样运行 build。这会在输出目录中生成
.nina_log文件。使用
fx ninjatrace2json工具将 Ninja 日志转换为跟踪文件。例如:fx ninjatrace2json <your_output_directory>/.ninja_log > trace.json在兼容的跟踪记录查看器中加载生成的
trace.json文件。例如,在 Chrome 中,前往chrome://tracing,然后点击“加载”。
或者,您也可以使用 fx report-last-build。此命令会收集全面的 build 日志和时间信息。