deb: integrate ccache for content-keyed compile reuse

Fresh chroots also mean fresh compiles: nothing survived to make the
recompile-heavy middle of a run cheap. Every deb build now wires a
shared ccache — /var/tmp/pkh/ccache/<slug>/, bind-mounted at the
chroot's /var/cache/pkh-ccache — through a PATH shim rather than CC
environment variables: gcc/g++/cc/c++ symlinks in /usr/lib/pkh-ccache-
shim resolve to the ccache the essentials install, so rules that call
the plain compiler names are cached while explicit exotic compilers
stay untouched. CCACHE_COMPILERCHECK=content is critical — the default
is mtime-based and would never hit across fresh chroots, where every
toolchain's mtime is the extraction's — with CCACHE_BASEDIR=/tmp/pkh-
build and CCACHE_NOHASHDIR=true keying the staged tree's relative
paths, and CCACHE_MAXSIZE=10G (PKH_CCACHE_MAXSIZE overrides).

No mtime clamping anywhere: the tarball extraction preserves mtimes,
so the toolchain and libc headers stay older than carried objects and
make keeps them, while build-dependency reinstalls are newer and make
rebuilds their dependents — ccache turns those into hits, and a real
archive library change is a miss that rebuilds them, exactly the
signal clamping would silence. `pkh deb --no-ccache` skips the shim,
the env and the mount entirely: an escape hatch for rules that
mishandle compiler wrappers (kbuild-style flavour configs).
This commit is contained in:
2026-09-29 14:39:54 +02:00
parent 0e1e37b2e6
commit 6a8c301705
6 changed files with 287 additions and 8 deletions
+11 -1
View File
@@ -140,6 +140,16 @@ downloaded packages, and an `apt-get autoclean` at the end of each run
drops the debs the archive no longer serves). `pkh prune` removes the
caches untouched for a week.
Fresh chroots do not mean fresh compiles either: every run's chroot
gets a shared ccache (at `/var/tmp/pkh/ccache/<target>/`, mounted at
`/var/cache/pkh-ccache`) wired in through a compiler PATH shim —
`gcc`, `g++`, `cc` and `c++` resolve to ccache — with content-keyed
cache checks (`CCACHE_COMPILERCHECK=content`), so cache hits survive
the fresh toolchain of a new chroot. The cache is capped at 10G per
target (override with `PKH_CCACHE_MAXSIZE`); `pkh deb --no-ccache`
bypasses the shim and cache entirely, an escape hatch for rules that
mishandle compiler wrappers (kbuild-style flavour configs).
`--incremental` forks a previous record — a copy, the base is never
modified — so a failed run can never destroy the last-good state it was
built from. The staged tree is carried only when the base's recorded
@@ -163,7 +173,7 @@ pkh deb list # the records of this tree: id, outcome,
# version, fork lineage, staged-tree state, age
pkh deb log [-f] [<id>] # print a record's build log; -f follows a
# live build
pkh prune # garbage-collect records (7-day retention)
pkh deb --no-ccache # build without the shared compile cache
```
Each target keeps at most five staged trees: when a sixth is retained,