envkernel activation costs 0.8 s, not 14 s -- the 14 s is a one-off apk add
scope: generic · severity: finding · confidence: proven · subsystem: build
The question — where-the-build-minutes-actually-go says every rung pays
14.3 s to source envkernel.sh, and names reusing that activation as the next
big win. Is that right?
No. Activation costs 0.80 s when the native chroot is warm. Measured in three separate fresh processes, 0.80 / 0.79 / 0.80.
The 14 s is real but it is not per build. initialize_chroot() in
envkernel.sh installs about thirty packages (abuild, bison, flex, rust,
clang…) and then touches
chroot_native/tmp/envkernel/<toolchain>_setup_done. Every later activation
sees that flag and returns immediately:
flag="$chroot/tmp/envkernel/${toolchain_name}_setup_done"[ -e "$flag" ] && returnSo the number you measure depends entirely on whether that flag survived. Both
14 s readings on record were taken just after the native chroot had been
re-created — which clears /tmp and with it the flag. Measure it twice: if
the second reading is under a second, the first one was the apk add.
What this kills. The whole design of caching the activation across builds — a state file, a replayed alias table, a token read back through the chroot to prove the bind is still the right tree. That probe alone costs 0.88 s, which is more than activating from scratch. It would have been a week of careful work on the script that flashes the phone, in exchange for negative speed. It was written, measured and reverted once already for a different reason; this is why it must not be written a third time.
It also kills the premise behind it: the bind does not survive a build
anyway. pmbootstrap build --envkernel returns with
chroot_native/mnt/linux at depth 0 — measured 1 → 0 across the call. Nothing
downstream could have reused it even if reuse were free. And envkernel does not
stack binds in the normal case: mount_kernel_source() unmounts first when
$chroot/mnt/linux/Kbuild exists, which it does in any kernel tree. Depth
stayed at 1 across three consecutive activations.
Where the time actually goes, warm, per shell invocation:
| phase | cost |
|---|---|
tkclean |
0.17 s |
source envkernel.sh |
0.75 s |
make <defconfig> |
4.92 s |
no-op make -j |
5.61 s |
pmbootstrap build --envkernel |
14.66 s |
Two of those are avoidable and neither is the mount handling. The defconfig
pass re-runs even when the config has not changed. The packaging step runs
inside _ph_make, which porthole build auto calls purely to see what make
rebuilt — and the router only reads .ko, .dtb and Image.gz under
.output, never the apk. See
the-auto-preview-builds-a-package-nobody-reads.
How it was established — date +%s.%N around each phase, in a fresh
bash per run so nothing carried over, on a tree with nothing to rebuild.
The control for “is the flag what matters” is the pair of readings: 16.60 s
with the flag absent, 0.80 s with it present, same host, same tree, same hour.
