Fuchsia build 利用 GN 的新 root_patterns
功能大量
减小了 GN 和 Ninja 构建图的大小。这使得
gn gen
速度更快,Ninja 启动时间更短。
不过,此功能会更改 GN 在解析 BUILD.gn
文件时的默认行为
可能出人意料。本文介绍了具体操作方法。
GN 默认行为
由于历史原因,GN 将实例化 BUILD.gn
文件中定义的每个目标
在默认工具链环境中对后者进行评估时,即使
非常依赖它们。
例如,请考虑以下三个 BUILD.gn
文件,它们分别定义两个目标:
之间有一些依赖关系:
_//BUILD.gn____ _//foo/BUILD.gn__ _//bar/BUILD.gn_
| | | | | |
| A | | D -------------> E |
| | | | | |
| B --------------> C | | F |
|_______________| |_________________| |________________|
当 GN 解析此构建计划时,会发生以下情况:
GN 首先加载
//BUILD.gn
并对其进行评估。因为 则默认工具链会为 Cloud Storage 中的所有条目创建目标, 即//:A
和//:B
。GN 遵循其刚创建的目标的依赖项,因为
//:B
依赖于//foo:C
,它首先加载//foo/BUILD.gn
, 进行评估。由于它仍在默认工具链中,因此它会实例化所有 目标,从而创建
//foo:C
和//foo:D
, 尽管后者不是//:A
或//:B
的依赖项它再次遵循依赖项,并将加载
//bar/BUILD.gn
, 评估并创建此处定义的所有目标,因此//bar:E
和//bar:F
这会导致最终的构建图包含比其他目标
但前提是 //BUILD.gn
表示
图表。
GN root_patterns
您可以更改此默认行为
.gn
文件中的 root_patterns
,
或使用 --root-pattern=<pattern>
命令行选项(一次或
)。
这些参数定义了一个目标标签模式列表,
非依赖项目标,存在于评估的 BUILD.gn
文件中
默认工具链中。
例如,对同一 build 使用 gn gen --root-pattern=//:*
计划将通过以下方式改变 GN 的行为:
GN 首先加载
//BUILD.gn
并对其进行评估。因为这是 创建的文件中的任何目标 因为它们与模式匹配(//:*
实际上表示“任何目标//BUILD.gn
”)。因此,它会像之前一样创建//:A
和//:B
。GN 遵循依赖项,然后加载
//foo/BUILD.gn
并评估 。它会创建//foo:C
,因为这是 之前创建的其中一个定位条件但是,它不会 创建//foo:D
,因为它的标签与模式//:*
不匹配。GN 就到此为止,因为它没有创建
//foo:D
,所以没有原因 以加载//bar:BUILD.gn
因此,GN 会创建 3 个目标,而不是最终 build 图中的 6 个目标。
实际结果
在实践中,使用此功能可以减小
大幅缩短 gn gen
的时间。对于
使用 fx set minimal.x64
配置:
Default --root-pattern=//:* Reduction
Target count 183761 48375 -73%
Ninja files size (MiB) 571.7 180.2 -68%
`fx set` peak RAM (GiB) 5.02 2.89 -42%
`gn gen` time (s) 14.9 6.15 -58%
`fx set` time (s) 16.0 6.77 -57%
//:root_targets
目标。
//BUILD.gn
文件现在定义了一个名为 root_targets
的顶级目标
可用于将依赖项添加到
会包含在构建图中,即使没有任何其他操作依赖于它们。
在少数情况下,这一点至关重要:
使用其输出的一些特殊
generated_file()
目标 作为隐式输入被其他目标使用,但无法依赖 。一些始终需要构建硬编码基础架构工具的目标 。
一些构建器配置所需的一些目标 没有将它们列入
universe_package_labels
, 只是由于存在其他必要的目标而假定存在 定义同一个BUILD.gn
文件。
向此列表添加的内容应最小化。总是最好能找到
来自其他任何顶级来源的真正传递依赖项
//BUILD.gn
目标,如果您确实需要始终保持
。