本页介绍了如何在重复运行 Bazel 时优化 Bazel 的构建性能。
Bazel 的运行时状态
Bazel 调用涉及多个相互作用的部分。
bazel命令行界面 (CLI) 是面向用户的前端工具 ,用于接收来自用户的命令。CLI 工具会为每个不同的 输出库启动一个 Bazel 服务器 。 Bazel 服务器通常是持久的,但会在空闲一段时间 后关闭,以免浪费资源。
Bazel 服务器会针对给定的命令 (
build,run,cquery, 等)执行加载和分析步骤,并在内存中构建构建图的必要部分 。生成的数据结构会保留在 Bazel 服务器中,作为分析缓存的一部分。Bazel 服务器还可以执行操作,或者,如果已设置为执行远程操作,则可以将 操作发送以进行远程执行。操作执行的 结果也会被缓存,即在操作缓存(或 执行缓存)中,该缓存可以是本地缓存,也可以是远程缓存,并且可以在 Bazel 服务器之间共享。
Bazel 调用的结果可在输出树中找到。
以迭代方式运行 Bazel
在典型的开发者工作流中,重复构建(或运行)一段代码
是很常见的,而且通常频率非常高(例如,为了解决一些编译
错误或调查失败的测试)。在这种情况下,重要的是,
重复调用 bazel 的开销应相对于
底层重复操作(例如调用编译器或执行测试)尽可能小。
考虑到这一点,我们再次查看 Bazel 的运行时状态:
分析缓存是一项关键数据。在冷启动(即在 Bazel 服务器启动后或分析缓存被舍弃时运行)的加载和分析阶段,可能会花费大量时间。 对于一次成功的冷构建(例如,对于生产版本),此费用是 可以接受的,但对于重复构建同一目标,重要的是此 费用应分摊,而不是在每次调用时重复。
分析缓存相当不稳定。首先,它是 Bazel 服务器的进程内
状态的一部分,因此丢失服务器会丢失缓存。但缓存
也很容易失效:例如,许多 bazel 命令行标志
会导致缓存被舍弃。这是因为许多标志会影响构建
图(例如,由于
可配置的属性)。某些标志
更改还可能导致 Bazel 服务器重启(例如,更改
启动选项)。
良好的执行缓存对于构建性能也很有价值。执行 缓存可以保存在本地 磁盘上,也可以 保存在远程。缓存可以在 Bazel 服务器之间共享,实际上也可以在开发者之间共享。
避免舍弃分析缓存
如果分析缓存被舍弃或 服务器重启,Bazel 将打印警告。在迭代使用期间,应避免出现以下任一情况:
请注意在迭代 工作流中间更改
bazel标志。例如,将bazel build -c opt与bazel cquery混合使用会导致每个命令舍弃另一个命令的分析缓存。一般来说, 请尝试在特定工作流的整个过程中使用一组固定的标志。丢失 Bazel 服务器会丢失分析缓存。Bazel 服务器具有 可配置空闲 时间,超过此时间后,它会关闭。您可以通过 bazelrc 文件配置此时间,以满足您的需求。当启动 标志更改时,服务器也会重启,因此,同样,请尽可能避免更改这些标志。
请注意,如果在 Bazel 运行时重复按 Ctrl-C,Bazel 服务器会被终止。您可能会想通过中断不再需要的正在运行的构建来节省时间 ,但请注意,只需按一次 Ctrl-C 即可请求正常结束当前调用。
如果您想在同一工作区中使用多组标志,可以 使用多个不同的输出库,并使用
--output_base标志进行切换。每个输出库都有自己的 Bazel 服务器。