Summary
kache is a content-addressed Rust build cache that plugs in as a RUSTC_WRAPPER.
0.5.0 designed a correct cache key; 0.6.0 makes that key portable across machines and
checkouts and extends caching to the C/C++ that crates compile in build scripts.
Why
A shared cache only helps if two checkouts of the same source hit the same entry — and
they usually don't, because absolute build paths leak into the key. 0.6.0 closes that gap,
and pulls the C/C++ half of many build times (ring, openssl-sys, Firefox) under the
same cache.
What's new
- Cross-checkout sharing.
KACHE_BASE_DIRnormalizes the build root; opt-in
[cache] path_only_env_vars(orKACHE_PATH_ONLY_ENV_VARS) marks build-location env
vars so they normalize instead of poisoning the key. - C/C++ via clang-cl (incl. Windows/MSVC). kache now caches MSVC-style
cl/clang-cl,
not just gcc/clang — no extra config if kache is already your wrapper. KACHE_LOCAL_ONLY— disable all remote I/O for air-gapped/private builds.KACHE_VERIFY_RESTORES— opt-in re-hash of restored blobs before use.
Hardening for shared use: length-prefixed key fields (cache v16), file metadata folded
into the dedup hash, and a cross-process gc.lock.
These notes were drafted with LLM assistance and edited by the maintainers (@jleni, @emmanuelm41).
Changelog
- bench(firefox): cross-clone cache convergence — 119→2 diverging, 8.45× speedup by @jleni in #258
- deps: drop aws-lc-sys (use ring) — unblocks aarch64-pc-windows-msvc by @jleni in #257
- Use guppy for build intent discovery by @jleni in #262
- Unify e2e and benchmark scenarios by @jleni in #261
- Fix Windows full compiler path detection by @jleni in #264
- Use guppy crate order for prefetch planning by @jleni in #263
- Improve build report diagnostics by @jleni in #265
- chore: bump release to 0.5.1-rc.1 by @jleni in #266
- Separate hit, dup, and miss cache outcomes by @jleni in #267
- Document report cache outcomes by @jleni in #268
- Bound Windows daemon IPC reads by @jleni in #269
- Guard OUT_DIR dual-pattern cache keys by @jleni in #270
- Refuse to cache rustc @argfile invocations (false-hit fix) by @jleni in #282
- Validate untrusted cache_key/crate_name before path/key interpolation by @jleni in #283
- Reclaim orphaned blob files via a GC + doctor sweep by @jleni in #284
- fix(rustc): recognize clippy-driver.exe under cargo clippy on Windows by @emmanuelm41 in #289
- fix(daemon): wake accept loop immediately on stop (#288) by @emmanuelm41 in #291
- Forward cc-crate family probe to the real compiler (fixes #286) by @emmanuelm41 in #290
- chore(release): bump version to 0.5.1-rc.2 by @emmanuelm41 in #292
- chore(release): bump version to 0.5.1-rc.3 by @emmanuelm41 in #294
- Robustness quick wins: list_keys loop, blob dir fsync, RUSTC_BOOTSTRAP key, spawn-failure fallback by @jleni in #293
- chore(release): bump version to 0.5.1-rc.4 by @emmanuelm41 in #296
- fix(cc): pre-clean read-only restored objects before recompiling on a cache miss by @emmanuelm41 in #297
- clang-cl support — Layers 0/1/2/4: dialect tables, /EP probe, cacheable cl + Firefox flags (#285) by @emmanuelm41 in #295
- fix(#298): keep restored Rust --test executables executable + regression coverage by @emmanuelm41 in #302
- fix(cc): splice -ffile-prefix-map flags before the
--separator (#300) by @emmanuelm41 in #305 - test(cc): guard #299 — clang-cl invocations get zero injected flags by @emmanuelm41 in #306
- chore(release): bump version to 0.6.0-rc.1 by @emmanuelm41 in #307
- Daemon + remote robustness hardening (bounded reads, HEAD retry, download guard, GC perf) by @jleni in #308
- monitor: Live Build as a table + surface the build action/outcome by @jleni in #309
- fix(#311): binstall pkg-url derives extension from pkg-fmt — Windows ships .zip by @emmanuelm41 in #313
- feat(cc): cache clang-cl debug compiles (#312) by @emmanuelm41 in #315
- fix(cc): Windows-aware -### path sentinel for gnu/clang (#312 follow-up) by @emmanuelm41 in #316
- docs: audit + correct the docs against the codebase (and fix the monitor dedup metric) by @jleni in #317
- fix(cc): map the Apple SDK path to a sentinel for portable cc keys (#78) by @jleni in #318
- fix(store,remote): harden the remote-import + store-removal seam (#212, #276, #211, #213) by @jleni in #320
- feat(config): strict local-only mode (KACHE_LOCAL_ONLY / [cache] local_only) by @jleni in #321
- fix(daemon): offload Gc/Stats/HashFiles + periodic GC to spawn_blocking (#281) by @jleni in #322
- fix(daemon): hash files outside the store mutex in HashFiles (#281) by @jleni in #338
- fix(store): fold inode into the file-hash memo key (#324) by @jleni in #341
- fix(store): fold name/size/exec-bit into the content-dedup hash (#324) by @jleni in #340
- fix(cache): never cache a degraded dep-info pre-pass (#323) by @jleni in #339
- feat(cache): opt-in too-new-input guard — refuse to store racy compiles (#324) by @jleni in #342
- feat(cache): length-prefix free-text key fields, bump to v16 (#324) by @jleni in #343
- feat(store): opt-in content verification on local restore (#332) by @jleni in #344
- ci: pin mise CLI to dodge v2026.6.10 Windows regression (+ bounded e2e retry) by @jleni in #346
- feat(store): cross-process gc.lock so concurrent GC drivers don't double-scan (#326) by @jleni in #345
- Fix GC lock contention follow-ups by @jleni in #347
- chore(release): bump version to 0.6.0 by @emmanuelm41 in #349
Full Changelog: v0.5.0...v0.6.0