Bazel 磁盘缓存

本文档介绍了如何在 Fuchsia 开发环境中为 Bazel 工件配置和使用本地磁盘缓存。

概览

Fuchsia 构建系统使用 Bazel 来构建系统的某些部分。 默认情况下,Bazel 将其缓存存储在构建目录(例如 out/default/bazel-*)中。如果您清理构建目录(例如,通过运行 fx clean-buildrm -rf out),此缓存将丢失,Bazel 必须从头开始重建所有内容。

您可以配置持久性共享磁盘缓存,该缓存在清理构建目录后仍然存在,并且可以在同一台机器上的多个 Fuchsia 检出和/或构建目录之间共享。

共享磁盘缓存的优势

  • 更快的整洁构建: 运行整洁构建时,Bazel 可以从磁盘缓存中检索之前构建的操作和工件,而无需重新构建它们。

  • 跨检出共享: 如果您在同一台机器上使用多个 Fuchsia 检出,它们可以共享同一个磁盘缓存。在一个检出中构建的工件可以在另一个检出中重复使用,从而节省时间和磁盘空间。

  • 跨构建目录共享: 如果您在同一检出中切换到不同的构建目录,则它们之间相同的操作(包括输入内容)也会自动受益于缓存。

  • 跨分支共享: 如果您在使用同一构建目录时经常在分支之间切换,增量构建也会受益于磁盘缓存。

  • 补充远程缓存 (RBE): Bazel 的磁盘缓存与远程缓存兼容。即使启用了远程构建执行 (RBE),本地磁盘缓存通常也会更快,因为它避免了在检索缓存工件时的网络延迟。它还允许您离线处理已构建的目标。

启用 Bazel 磁盘缓存

如需启用磁盘缓存,请将 FUCHSIA_BAZEL_DISK_CACHE 环境变量设置为您要存储缓存的目录的绝对路径

例如,将以下行添加到 shell 启动脚本(例如 ~/.bashrc~/.zshrc):

export FUCHSIA_BAZEL_DISK_CACHE="$HOME/.fuchsia_bazel_cache"

如果该目录不存在,构建系统会自动创建该目录。

管理缓存大小(垃圾回收)

默认情况下,磁盘缓存会无限增长。为防止其占用过多磁盘空间,您可以通过设置 FUCHSIA_BAZEL_DISK_CACHE_SIZE 环境变量来启用自动垃圾回收。

此变量指定缓存的最大大小。Bazel 会在空闲时定期在后台清理较旧的缓存项,以保持在此限制范围内。

将以下行添加到 shell 启动脚本,并指定所需的限制(例如,40G 表示 40 GB):

export FUCHSIA_BAZEL_DISK_CACHE_SIZE="40G"

大小可以以字节为单位指定,也可以选择后跟 KMGT

如果未设置 FUCHSIA_BAZEL_DISK_CACHE_SIZE,您必须手动管理缓存大小(例如,在目录内容过大时将其删除)。

避免缓存大型工件

缓存并不总是有益的;例如,对于生成经常更改的大型工件的目标(例如产品组装),缓存可能并不适用。Bazel 提供了多种方法来避免缓存这些工件。

对于各个目标定义,可以使用所有规则通用的 tags属性。例如:

genrule(
    name = "create_large_archive",
    ...

    # No need to run this remotely, nor cache the archive.
    tags = ["no-cache", "no-remote"],
)

对于自定义规则,实现函数应使用 ctx.actions.run()属性调用execution_requirements,该属性设置为 将标记字符串映射到字符串字面量"1"的字典。请注意,使用 True 或整数 1 将不起作用,但文档中未正确说明这一点。 例如:

def _my_rule_impl(ctx):
    ...
    ctx.actions.run(
        ...,
        execution_requirements = {
            "no-cache": "1",
            "no-remote": "1",
        },
    )
    ...

my_rule = rule(
    implementation = _my_rule_impl,
    ...
)

在这种情况下,所有 my_rule() 目标工件将自动不被缓存(或远程缓存)。