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 目标,如果您确实需要始终保持
。