kache 0.17.0

Zero-copy, content-addressed build cache for Rust, C/C++ and more, with S3 and shared-filesystem remotes.
---
title: C/C++ caching
description: Cache supported GCC, Clang, and clang-cl object compilations
---

Kache caches conservative, single-source C and C++ object compilations. If it cannot prove that an invocation is safe to cache, it runs the real compiler unchanged.

## Cargo build scripts

`RUSTC_WRAPPER` wraps rustc only. To cache the objects a build script compiles through the `cc` crate, run `kache init` or put a shim on `PATH`.

`kache init` sets `HOST_CC` and `HOST_CXX` in Cargo's config (and `CC_KNOWN_WRAPPER_CUSTOM=kache`). It does not set `CC` or `CXX`, so `cargo build --target` keeps the cross compiler the `cc` crate would have found.

PATH shims also cover Cargo's C bits when the crate invokes `cc` or `gcc` from `PATH` without `HOST_CC`.

## Make, CMake, autotools, PKGBUILD

The Unix path is the same idea as ccache's masquerade method: put a directory of compiler-named symlinks first on `PATH`. `make`, CMake, autotools, and Arch PKGBUILDs that call `gcc` or `clang` by name then go through Kache. There is no `CC=` edit and no shell wrapper.

```bash
kache install-shims
export PATH="$HOME/.local/lib/kache/shims:$PATH"
```

`kache init` can create that directory. It does not edit your shell rc or `PATH`. Add the `export` to the shell you build from, or for `makepkg`:

```bash
# ~/.makepkg.conf
PATH="$HOME/.local/lib/kache/shims:$PATH"
```

The APT and AUR packages also install `/usr/lib/kache` with the same symlinks:

```bash
export PATH="/usr/lib/kache:$PATH"
```

Nix packages include the same symlinks in `${kache}/shims`, also available at `${kache}/lib/kache`. Add that directory to `PATH` using the [Nix configuration example](/docs/getting-started/installation#nix); no `kache install-shims` step is needed.

`kache install-shims` creates `cc`, `c++`, `gcc`, `g++`, `clang`, and `clang++`. Keep the real compilers later in `PATH`; Kache skips any entry that resolves back to itself.

Versioned and target-prefixed names (`gcc-13`, `x86_64-pc-linux-gnu-gcc`) work if you create them by hand or scan `PATH`:

```bash
kache install-shims --from-path
kache install-shims --force ~/.local/lib/kache/shims
```

Omitting the directory uses `~/.local/lib/kache/shims`. `--from-path` adds a symlink for every compiler-shaped name already on `PATH` that is not Kache itself.

This is a native symlink to the `kache` binary. Do not wrap Kache in a shell script; that would spawn a shell per compile.

Kache is a larger process than ccache. On a tree of many tiny `.c` files, measure both before replacing ccache.

`kache doctor` reports whether a compiler name on `PATH` is a Kache shim. The check is informational, so a Rust-only setup does not fail doctor for skipping it.

## Prefix method

For a single project that honors `CC` and `CXX`:

```bash
export CC="kache cc"
export CXX="kache c++"
export CC_KNOWN_WRAPPER_CUSTOM=kache
```

The `cc` crate needs `CC_KNOWN_WRAPPER_CUSTOM` so it keeps the real compiler argument. PATH shims do not need that variable, because the compiler name stays `gcc`.

For clang-cl driver mode:

```powershell
$env:CC = "kache clang-cl"
```

Windows has no `install-shims` generator yet. Use `CC`/`CXX`, or copy `kache.exe` to `gcc.exe` and put that directory first on `PATH`.

## Cached invocations

Supported shapes compile one source into one object:

```bash
cc -c src/foo.c -o build/foo.o
c++ -c src/foo.cpp -o build/foo.o
clang-cl /c foo.c /Fofoo.obj
```

The key includes preprocessor output, compiler identity, modeled code-generation options, and normalized paths. Header changes therefore invalidate the entry.

Kache recognizes GCC, Clang, Apple Clang, clang-cl, versioned names such as `gcc-13`, and target-prefixed compiler names. It can probe other wrapper names to identify the underlying compiler family.

## Portability

GCC and Clang entries can be reused across worktrees when source and build paths normalize cleanly. Set `KACHE_BASE_DIR` when the automatic roots do not cover a container mount or out-of-tree layout:

```bash
KACHE_BASE_DIR="$PWD" cmake --build build
```

A configured remote publishes GCC and Clang objects the same way it publishes Rust entries. clang-cl debug objects stay on the machine because CodeView records paths that clang-cl does not remap.

## Passthroughs

Kache currently passes through:

- link and whole-program steps
- multi-source or multi-architecture invocations
- response files
- precompiled headers and modules
- coverage and split-DWARF builds
- flags it has not classified

Inspect passthrough reasons in the monitor or logs:

```bash
kache monitor
KACHE_LOG=kache=debug make
```

You can opt a known-safe flag into the local model:

```toml title=".kache.toml"
[cc]
extra_allowlist_flags = ["-ffunction-sections"]
```

Kache folds the spelling into the key. Do not allow flags whose meaning depends on the host, such as `-march=native`.