blob: 165fcf00d9d514fe130395f302e0c7564c851bfe [file] [view] [edit]
# Bazel disk cache
This document describes how to configure and use a local disk cache for Bazel
artifacts in your Fuchsia development environment.
## Overview {:#overview}
The Fuchsia build system uses Bazel for building certain parts of the system.
By default, Bazel stores its cache inside the build directory (e.g.,
`out/default/bazel-*`). If you clean your build directory (for example, by
running `fx clean-build` or `rm -rf out`), this cache is lost, and Bazel
must rebuild everything from scratch.
You can configure a persistent, shared disk cache that survives build
directory cleans and can be shared across multiple Fuchsia checkouts and/or
build directories on the same machine.
## Benefits of a shared disk cache {:#benefits-of-a-shared-disk-cache }
* **Faster Clean Builds:** When you run a clean build, Bazel can retrieve
previously built actions and artifacts from the disk cache instead of
rebuilding them.
* **Shared Across Checkouts:** If you work with multiple Fuchsia checkouts
on the same machine, they can all share the same disk cache. Artifacts
built in one checkout can be reused in another, saving time and disk
space.
* **Shared Across Build Directories:** If you switch between different
build directories in the same checkout, actions that are identical between
them (including input contents) will automatically benefit from the
cache too.
* **Shared Across Branches:** If you frequently switch between branches,
while using the same build directory, incremental builds will also
benefit from the disk cache.
* **Complements Remote Caching (RBE):** Bazel's disk cache is compatible with
remote caching. Even when Remote Build Execution (RBE) is enabled, a local
disk cache is often faster because it avoids network latency when retrieving
cached artifacts. It also allows you to work offline for targets you have
already built.
## Enabling the Bazel disk cache {:#enabling-the-bazel-disk-cache}
To enable the disk cache, set the `FUCHSIA_BAZEL_DISK_CACHE` environment
variable to an **absolute path** of a directory where you want to store the
cache.
For example, add the following line to your shell startup script
(e.g., `~/.bashrc` or `~/.zshrc`):
```bash
export FUCHSIA_BAZEL_DISK_CACHE="$HOME/.fuchsia_bazel_cache"
```
The build system will automatically create the directory if it does not exist.
Tip: Place the cache directory on the **same filesystem** as your Fuchsia
checkouts. This allows Bazel to use hard-links or reflinks (on supported
filesystems) to reference cached artifacts, which significantly reduces
disk space usage and improves build performance.
Important: The path specified in `FUCHSIA_BAZEL_DISK_CACHE` must be an absolute
path. Relative paths will cause the build to fail.
## Managing cache size (Garbage Collection) {:#managing-cache-size}
By default, the disk cache will grow indefinitely. To prevent it from
consuming too much disk space, you can enable automatic garbage collection by
setting the `FUCHSIA_BAZEL_DISK_CACHE_SIZE` environment variable.
This variable specifies the maximum size of the cache. Bazel will periodically
clean up older cached items in the background when it is idle to stay under
this limit.
Add the following line to your shell startup script, specifying the desired
limit (e.g., `40G` for 40 Gigabytes):
```bash
export FUCHSIA_BAZEL_DISK_CACHE_SIZE="40G"
```
The size can be specified in bytes, or optionally followed by `K`, `M`, `G`,
or `T`.
If `FUCHSIA_BAZEL_DISK_CACHE_SIZE` is not set, you must manage the cache size
manually (e.g., by deleting the directory contents when it grows too large).
## Avoiding caching for large artifacts {:#avoiding-caching-large-artifacts}
Caching is not always beneficial; for example, for targets that generate
large artifacts which change often, such as product assembly. Bazel provides
several ways to avoid caching these artifacts.
For individual target definitions, the
[`tags` attribute][tags-attribute]{:.external}, common to all rules, can be
used. For example:
```py
genrule(
name = "create_large_archive",
...
# No need to run this remotely, nor cache the archive.
tags = ["no-cache", "no-remote"],
)
```
For custom rules, the implementation function should invoke
`ctx.actions.run()` with an `execution_requirements` attribute set to
a dictionary mapping tag strings to the string literal `"1"`. Note that using
`True` or the integer `1` will not work, which is not properly documented.
For example:
```py
def _my_rule_impl(ctx):
...
ctx.actions.run(
...,
execution_requirements = {
"no-cache": "1",
"no-remote": "1",
},
)
...
my_rule = rule(
implementation = _my_rule_impl,
...
)
```
In this case, all `my_rule()` target artifacts will automatically not be
cached (or remoted).
[tags-attribute]: https://bazel.build/reference/be/common-definitions#common-attributes