特定于 Fuchsia 的 Ninja 改进

Fuchsia 构建系统使用自定义 Ninja 二进制文件,可改进开发者体验。本页介绍了这些功能。

设计初衷

RFC-0153 详细介绍了为 Fuchsia 自定义 Ninja 的动机。

总而言之,有许多功能对 Fuchsia 开发者来说非常有用,但在源代码上游版本中很难获得。

所有特定于 Fuchsia 的更改都将在本地 Ninja git 镜像的本地 fuchsia-rfc-0153 分支上执行,并定期重新建立基准,以便轻松将其作为 GitHub 拉取请求发送到上游项目,如 RFC 的“策略”部分中所述。

功能:正在运行的命令的状态

将环境中的 NINJA_STATUS_MAX_COMMANDS 设置为一个严格正整数,以便在智能终端中运行时,Ninja 会在状态行下方输出一个表格,其中包含运行时间最长的命令及其经过的时间。例如,使用 export NINJA_STATUS_MAX_COMMANDS=4 时,状态可能如下所示:

[0/28477](260) STAMP host_x64/obj/tools/configc/configc_sdk_meta_generated_file.stamp
  0.4s | STAMP obj/sdk/zircon_sysroot_meta_verify.stamp
  0.4s | CXX obj/BUILD_DIR/fidling/gen/sdk/fidl/fuchsia.me...chsia.media/cpp/fuchsia.media_cpp_common.common_types.cc.o
  0.4s | CXX obj/BUILD_DIR/fidling/gen/sdk/fidl/fuchsia.me...fuchsia.media/cpp/fuchsia.media_cpp.natural_messaging.cc.o
  0.4s | CXX obj/BUILD_DIR/fidling/gen/sdk/fidl/fuchsia.me...dia/cpp/fuchsia.media_cpp_natural_types.natural_types.cc.o

下方的动画图片展示了实际效果:

Ninja 多行状态示例

请注意:

  • 在 Ninja 的模拟运行或详细调用(即使用 -n--verbose 标志)中,此功能会自动停用。

  • 当 Ninja 未在 Interactive / Smart 终端中运行时,此功能会自动停用。

  • 运行控制台命令时,此功能也会暂停(在上述运行 Bazel 操作的示例中可见)。

  • 借助此功能,您可以轻松直观地查看构建过程中的瓶颈,即导致其他命令无法并行运行的长时间运行的命令。

默认情况下,命令表每秒更新 10 次,这对于了解哪些耗时的命令会拖慢构建速度非常有用。您可以通过将 NINJA_STATUS_REFRESH_MILLIS 设置为以毫秒为单位的十进制值来更改刷新周期(请注意,系统会忽略低于 100 的值,因为经过的时间只会以小数点后一位的形式显示)。

功能:持久模式可缩短启动时间

在环境中设置 NINJA_PERSISTENT_MODE=1 可加快连续调用 Ninja 的速度。此功能可让 Ninja 启动后台服务器进程来读取 build 清单一次,然后在连续 build 之间将 build 图表保留在内存中。

请注意:

  • 此功能应完全透明,并且不应影响 Ninja 的行为。如果您发现问题或差异,请通过 fuchsia-build-team@google.com 与我们联系!

  • 系统会自动检测输入 .ninja 文件中的任何更改。在这种情况下,现有服务器将关闭,系统会自动启动新的服务器。更改 GN build 文件或执行 jiri update 后,无需用户进行额外互动。

  • 服务器进程会在空闲 5 分钟后正常关闭。在您的环境中设置 NINJA_PERSISTENT_TIMEOUT_SECONDS=<count> 以更改此延迟时间。

  • 使用 fx build -t server status 检索当前 build 目录的服务器状态。

  • 使用 fx build -t server stop 明确停止服务器的任何正在运行的实例。

  • 设置 NINJA_PERSISTENT_LOG_FILE=<path> 以将与持久模式相关的日志发送到给定文件路径。

  • 每个服务器进程目前会占用大约 1 GiB 的 RAM 来处理 core.x64 build 配置。具体数字取决于 Ninja 图的大小,而这又取决于您的 args.gn 配置。

  • 每个 Ninja build 目录最多只能由一个服务器进程提供服务。但是,使用多个 build 目录时,可能会有多个进程。

  • Ninja 工具(例如 ninja -C <dir> -t commands <target>)尚未在服务器上运行,因此仍会使用缓慢的启动方式。我们日后会修复此问题,以加快查询速度。

已知 bug / 注意事项,我们会加以解决:

  • 目前,在同一目录中混合使用永久性 build 和非永久性 build 可能会使服务器感到困惑,因为系统无法正确检测对 Ninja build 和依赖项日志的独立更改。我们会解决此问题。

    解决方法:在环境中取消设置 NINJA_PERSISTENT_MODE 之前,使用 -t server stop 停止服务器。

  • “快速启动”需要几秒钟的时间。目前,每个增量 build 仍需要对 build 图中的所有文件调用 stat(),这目前需要几秒钟的时间。我们日后会通过使用主机操作系统基于 inotify / kqueue 的文件系统监控功能来解决此问题,以便在仅修改了少数文件时立即启动。

  • 不适用于 Windows(暂时不支持)。这是由于 Win32 存在技术限制,该限制会阻止将控制台句柄复制到其他进程。这对上游 Ninja 团队来说是一个主要问题,因为 Fuchsia 开发并非在 Windows 上进行。