Fuchsia 构建系统

概览

Fuchsia 构建系统旨在为各种设备构建启动映像和可更新的软件包。为此,它使用 GN,这是一种元构建系统,可生成供 Ninja 使用的构建文件,并由后者执行实际构建。

请注意,Zircon 使用的是不同的构建系统,不过仍使用 GN 和 Ninja。

使用入门

如果您不熟悉 Fuchsia 的构建系统和 GN,请参阅使用 GN build,其中概述了 GN 构建系统的基本原则。

面板和产品

生成的映像的内容由主板和产品的组合控制,这些组合是 Fuchsia build 的最低初始配置。开发板和产品定义了依赖项集,这些依赖项集用于定义映像、更新和软件包代码库中包含的软件包。开发板和产品记录了这些 build 配置的结构和用法。

套装

软件包是源代码树的某一部分(例如所有工具或所有测试)内相关软件包的分组。软件包中提供了软件包概览。//bundles 中定义了一组顶级软件包。

编译目标

构建目标在分散在整个源代码树中的 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 的工件。

执行构建

最简单的方法是使用 fx 工具,如 fx 工作流中所述。请继续阅读,了解 fx 在后台执行的操作。

本文档的其余部分假定 PATH 中提供了 gnninja 命令。这些命令可分别在 prebuilt/third_party/gn/<platform>prebuilt/third_party/ninja/<platform> 中找到。或者,如果您想避免修改 PATH,则可以为所有调用添加 fx 前缀,即 fx gnfx ninja

生成步骤

首先,选择要构建的开发板和产品,配置主要构建工件:

fx gn gen $(fx get-build-dir) --args='import("//boards/x64.gni") import("//products/core.gni")'

这将创建一个包含 Ninja 文件的 build 目录(通常为 out/default)。

等效的 fx set 命令为:

fx set core.x64

如需查看所有 GN build 参数的列表,请运行以下命令:

fx gn args $(fx get-build-dir) --list

如需查看有关 select_variant 参数的文档,请参阅变体

构建步骤

下一步是使用 Ninja 运行实际 build:

fx ninja -C $(fx get-build-dir)

这是 fx build 在后台运行的内容。

正在重新构建

如需在修改某些源代码后重新构建树,只需重新运行构建步骤即可。即使您修改了 BUILD.gn 文件,当 build 文件发生更改时,GN 也会添加 Ninja 目标以更新 Ninja 目标,这一点也适用!这同样适用于配置 build 的其他文件。任何需要手动重新调用生成步骤的源代码更改都是 build bug,应予以报告。

提示和技巧

检查 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 本身中使用)需要与最终映像一起构建。

如需从模块文件引用主机工具链的构建目标,请执行以下操作:

//path/to/target(//build/toolchain:host_x64)

如需从 BUILD.gn 文件中引用主机工具链的构建目标,请执行以下操作:

//path/to/target($host_toolchain)

仅构建特定目标

如果目标在 GN build 文件中定义为 //foo/bar/blah:dash,则可以使用以下代码构建该目标(及其依赖项):

fx ninja -C $(fx get-build-dir) -j64 foo/bar/blah:dash

请注意,这仅适用于默认工具链中的目标。

探索忍者目标

GN 提供了大量文档,记录了 Ninja 生成的目标。该文档可通过以下途径访问:

fx gn help ninja_rules

您还可以使用以下命令浏览输出目录中当前定义的 Ninja 目标集:

fx ninja -C $(fx get-build-dir) -t browse

请注意,Ninja 目标的存在并不意味着要构建它,因为它需要依赖于“默认”目标。

了解 Ninja 的实现方式

-d explain 添加到 Ninja 命令,以说明其执行的每个步骤。

调试构建时间问题

运行构建时,Ninja 会保留日志,以用于生成构建流程的可视化效果:

  1. 删除输出目录 - 这是为了确保日志仅表示您要运行的构建迭代;
  2. 像平常一样运行构建;
  3. 获取 https://github.com/nico/ninjatracing
  4. 运行 ninjatracing <output directory>/.ninja_log > trace.json
  5. 在 Chrome 中的 about:tracing 中加载生成的 JSON 文件。

问题排查

我的 GN 目标未在构建中!

请确保将其汇总到模块文件中定义的某个标签,否则构建系统会忽略该标签。

GN 抱怨缺少 sysroot

您可能忘记同时运行 Build 步骤中的这两个命令。

TODO(pylaligand):显示默认目标的路径的命令

内部 GN 设置

TODO(pylaligand):.gn、默认目标、GN 标签插入