blob: 4d9566fd45e8d453c54b1ecbcd80412fe20b3891 [file] [log] [blame] [view]
# Using `ccache` to build IREE
[`ccache`](https://ccache.dev/) is a compilation cache. In principle, just
prepending compiler invocations with `ccache` is all one needs to enable it,
e.g.
```shell
ccache clang foo.c -c -o foo.o
```
takes care of executing `clang` with these arguments and caches the output file
`foo.o`. The next invocation then skips executing `clang` altogether.
When the cache is hit, the speedup is such that the "compilation" becomes
essentially free. However, `ccache` only caches compilation, [not linking](https://stackoverflow.com/a/29828811).
Here a few scenarios where `ccache` helps:
* Incremental rebuilds. While `cmake` always tries to avoid unnecessary work in
incremental rebuilds, it can only make simple decisions based on file
timestamps. `ccache` sees deeper: if the raw source code isn't readily
a cache hit, it will then try again after preprocessing and discarding
comments.
* One pain point with `cmake` is having to start over from a clean build
directory from time to time, which by default means paying again the full cost
of a cold build. Thankfully `ccache` keeps its cache outside of any `cmake`
build directory, so the first build in the new clean build directory may be
very fast.
## Installing and setting up `ccache`
`ccache` is available on most platforms. On Debian-based Linux distributions,
do:
```shell
sudo apt install ccache
```
The one `ccache` setting that you probably need to configure is the maximum
cache size. The default `5G` is too small for our purposes. To set the cache max
size, do this once:
```shell
ccache --max-size=20G
```
**Tip:** At the moment (late 2020), most of the code we're building is
`third_party/llvm-project` so the fundamental limiting factor to how far we can
cache away rebuilds is how often that dependency gets updated. Given how
frequently it currently is updated, I'm finding that `20G` is enough to make the
`ccache` size not be the limiting factor.
## Telling CMake to use `ccache`
In the initial CMake configuration step, set the `IREE_ENABLE_CCACHE` and
`LLVM_CCACHE_BUILD` options, like this:
```shell
cmake -G Ninja \
-DIREE_ENABLE_CCACHE=ON \
-DLLVM_CCACHE_BUILD=ON \
... other options as usual
```
Notes:
* This approach only works with the `Ninja` and `Makefile` generators (`cmake
-G` flag). When using other generators, another approach is needed, based on
wrapping the compiler in a script that prepends `ccache`. See this
[article](https://crascit.com/2016/04/09/using-ccache-with-cmake/).
* We do need two separate options `IREE_ENABLE_CCACHE` and `LLVM_CCACHE_BUILD`,
because of how CMake leaves it up to each project to define how to control the
use of `ccache`, and `llvm-project` is a `third_party/` project in IREE. Note
that most of the compilation time is spent in `llvm-project`, so
`LLVM_CCACHE_BUILD` is the most important flag here.
## Ensuring that `ccache` is used and monitoring cache hits
The `ccache -s` command dumps statistics, including a cache hit count and ratio.
It's convenient to run periodically with `watch` in a separate terminal:
```shell
watch -n 0.1 ccache -s # update the stats readout every 0.1 seconds
```