| # 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 |
| |