C/C++ caching
kache can wrap C and C++ compilers in addition to rustc. This path is live for local object compiles and intentionally conservative: if kache cannot model an invocation safely, it passes through to the real compiler.
Setup
For Make, CMake, autotools, or build scripts that honor CC / CXX:
export CC="kache cc"
export CXX="kache c++"
For Cargo build scripts that use the Rust cc crate, also declare kache as a known wrapper so the crate keeps the real compiler argument:
export CC_KNOWN_WRAPPER_CUSTOM="kache"
For clang-cl / MSVC-driver mode:
set "CC=kache clang-cl"
kache recognizes cc, c++, gcc, g++, clang, clang++, versioned variants like gcc-13, target-prefixed cross compilers like arm-linux-gnueabihf-gcc, clang-cl, and clang --driver-mode=cl.
What Is Cached
kache caches single-source object compiles:
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
On a hit, kache restores the object file and dep-info sidecar without re-running the compiler. The key includes:
- preprocessor output, so header edits invalidate the object
- compiler identity and resolved target/codegen flags
- source path normalization for gcc/clang
- CodeView path inputs for clang-cl debug compiles (
/Z7,-Z7,-g)
For gcc/clang, keys are portable across worktrees when paths normalize cleanly. Use KACHE_BASE_DIR for checkout, container mount, or shared source/build prefixes the automatic detection cannot strip.
For clang-cl debug builds, keys are machine-local. clang-cl embeds CodeView paths in the .obj and does not honor -ffile-prefix-map, so kache keeps those paths literal instead of pretending the object is portable.
Out-of-tree builds
kache supports out-of-tree C/C++ builds, including sibling CMake-style layouts:
cmake -S source -B build
cmake --build build
The cache key normalizes both source and build roots when kache can derive them from the compiler invocation. If generated sources, configured headers, or __FILE__ paths point above those roots, set KACHE_BASE_DIR to the common parent so the same object can hit across fresh checkouts:
KACHE_BASE_DIR="$PWD" cmake --build build
What Passes Through
These shapes compile normally but are not cached yet:
- link or whole-program steps
- multi-source or multi-arch invocations
- response files (
@file) - precompiled headers and modules
- coverage and split-DWARF
- clang-cl
-bigobjand-showIncludes - flags kache has not classified
C/C++ artifacts are local-only today. S3 sync and remote sharing apply to Rust artifacts, not cc objects.
Diagnosing Passthroughs
Use kache monitor and open the Passthrough tab, or run with debug logging:
KACHE_LOG=kache=debug make
If a safe flag is missing from kache's built-in allow-list, opt it in locally:
[cc]
extra_allowlist_flags = ["-ffunction-sections", "-fdata-sections"]
The flag is folded into the key verbatim. Avoid host-dependent values like -march=native, because the same spelling can produce different objects on different CPUs.