No CCACHE_ export reaches a cross compile, because crossdirect execs with a literal environment
scope: generic · severity: trap · confidence: proven · subsystem: build
Symptom — you export CCACHE_MAXSIZE, CCACHE_DIR or CCACHE_BASEDIR
before a package build, the build runs normally, and the setting has no effect
at all. No error, no warning, nothing in the log. Setting it in
pmbootstrap’s environment, in porthole’s config, or in the APKBUILD makes no
difference either.
The mechanism
Section: The mechanismcrossdirect is the shim pmbootstrap puts in front of the compiler in a cross
build. It does not add to the environment it was called with – it replaces
it, with three entries:
// crossdirect.c:114char *env[] = { "LD_PRELOAD=", "LD_LIBRARY_PATH=/native/lib:/native/usr/lib", "CCACHE_PATH=/native/usr/bin", NULL };...// crossdirect.c:135if (execve(newExecutable, newargv, env) == -1) {execve with an explicit env argument discards the caller’s environment
entirely. Those three strings are the whole environment the cross compiler
– and therefore ccache – is given. Nothing porthole exports, nothing
pmbootstrap exports, and nothing an APKBUILD exports is present by the time
ccache reads its settings.
What does work
Section: What does workccache’s own config file, inside the cache directory, which is what
ccache -M <size> writes. It has to be run in the chroot that owns that
arch’s cache:
porthole build ccache --max 25GThat is why the verb exists rather than a documented environment variable, and
why porthole sandbox up sets the ceiling rather than exporting one.
lib/porthole_cmd_build.py::_ccache is the implementation.
What this does not cover
Section: What this does not coverThe link half. A link never reaches this code at all: crossdirect
re-executes it as /usr/bin/<name>, a target-arch ELF that binfmt hands to
qemu-<arch>-static, several lines earlier and before this environment is
ever built. Deliberate, to dodge a broken cross-ld. That is a different note:
crossdirect-hands-the-linker-to-qemu-on-purpose.
So the rule to carry: for a cross build, a compiler setting is a file, not a variable. If a knob has no config file, there is no way to set it from outside, and the answer is usually the APKBUILD’s own flags rather than the environment.
Related: two-pmbootstrap-builds-destroy-each-other for what else is true of the buildroot these caches live in.
