Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

oven: persistent /kernel-build volume + skip no-op .config rewrites

Previously every native build copied the whole linux-$KVER tree from
/cache into an ephemeral $BUILD dir, so ccache helped per-file but every
link, modpost, kallsyms, and bzImage assembly pass ran fresh. Now the
kernel tree lives on a named Docker volume (ac-os-kbuild) mounted at
/kernel-build; docker-build.sh seeds it from /cache on first run and
keeps the .o files between oven runs. A .kver sentinel wipes the tree
when the kernel version bumps.

Also: cmp .config against the repo copy before overwriting — the blind
`cp` was touching .config's mtime every run, invalidating kbuild's own
dependency graph even when the config hadn't changed.

Expected win: code-only changes drop from ~10 min kernel rebuild to
~1-2 min (only changed .c files recompile + bzImage re-links with new
initramfs). Config changes still do the full rebuild.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+36 -7
+35 -6
fedac/native/docker-build.sh
··· 627 627 # Step 4: Build kernel with embedded initramfs 628 628 # ══════════════════════════════════════════════ 629 629 log "Step 4/4: Building kernel..." 630 - LINUX_DIR="$BUILD/linux-$KVER" 630 + 631 + # Persistent kernel build tree lives on a Docker volume mounted at /kernel-build. 632 + # This preserves object files between oven runs so ccache + kbuild's own 633 + # dependency tracker produce true incremental rebuilds. Fall back to ephemeral 634 + # $BUILD when the volume isn't present (e.g. running docker-build.sh locally 635 + # without the oven wrapper). 636 + if [ -d /kernel-build ] && [ -w /kernel-build ]; then 637 + KBUILD_ROOT="/kernel-build" 638 + log " Using persistent kernel build tree at $KBUILD_ROOT" 639 + else 640 + KBUILD_ROOT="$BUILD" 641 + log " No persistent volume — kernel tree at $KBUILD_ROOT (ephemeral)" 642 + fi 643 + LINUX_DIR="$KBUILD_ROOT/linux-$KVER" 644 + 645 + # Version sentinel: if the persisted tree is for a different kernel version, 646 + # wipe it before reinitializing from the Docker image's cached source. 647 + SENTINEL="$KBUILD_ROOT/.kver" 648 + if [ -f "$SENTINEL" ] && [ "$(cat "$SENTINEL")" != "$KVER" ]; then 649 + log " Kernel version changed ($(cat "$SENTINEL") → $KVER), wiping build tree" 650 + rm -rf "$KBUILD_ROOT/linux-"* 651 + rm -f "$SENTINEL" 652 + fi 631 653 632 654 # Use cached kernel source or download 633 655 if [ ! -f "$LINUX_DIR/Makefile" ]; then 634 656 if [ -d "/cache/linux-$KVER" ]; then 635 - log " Using cached Linux $KVER..." 636 - cp -a "/cache/linux-$KVER" "$BUILD/" 657 + log " Initializing $KBUILD_ROOT from cached Linux $KVER..." 658 + cp -a "/cache/linux-$KVER" "$KBUILD_ROOT/" 637 659 else 638 660 log " Downloading Linux $KVER..." 639 - cd "$BUILD" 661 + cd "$KBUILD_ROOT" 640 662 curl -sL "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KVER}.tar.xz" | tar xJ 641 663 fi 664 + echo "$KVER" > "$SENTINEL" 642 665 fi 643 666 644 - # Copy config 645 - cp "$NATIVE/kernel/config-minimal" "$LINUX_DIR/.config" 667 + # Copy config only if it differs — overwriting touches mtime and invalidates 668 + # large swaths of kbuild's dependency graph, forcing full rebuilds. 669 + if ! cmp -s "$NATIVE/kernel/config-minimal" "$LINUX_DIR/.config"; then 670 + log " Config changed, updating .config" 671 + cp "$NATIVE/kernel/config-minimal" "$LINUX_DIR/.config" 672 + else 673 + log " Config unchanged, preserving existing build tree" 674 + fi 646 675 647 676 # Stage built-in firmware blobs referenced by CONFIG_EXTRA_FIRMWARE 648 677 # into a container-local directory and rewrite CONFIG_EXTRA_FIRMWARE_DIR.
+1 -1
oven/native-builder.mjs
··· 471 471 addLogLine(job, "stdout", "Phase 2: Compiling C kernel in Docker..."); 472 472 const cidFile = `/tmp/oven-cid-${job.id}`; 473 473 await runPhase(job, "build", "bash", ["-c", [ 474 - `CID=$(docker create -e AC_BUILD_NAME=${buildName} -e AC_GIT_HASH=${buildGitHash} -e AC_BUILD_TS=${buildTs} -v ac-os-ccache:/ccache ac-os-builder)`, 474 + `CID=$(docker create -e AC_BUILD_NAME=${buildName} -e AC_GIT_HASH=${buildGitHash} -e AC_BUILD_TS=${buildTs} -v ac-os-ccache:/ccache -v ac-os-kbuild:/kernel-build ac-os-builder)`, 475 475 `echo $CID > ${cidFile}`, 476 476 `docker start -a $CID`, 477 477 ].join(" && ")], repoDir);