From 5a1088d5ce4b98895575ee21447f6786dddde41c Mon Sep 17 00:00:00 2001 From: Sergio Date: Thu, 11 Jun 2026 02:21:18 +0000 Subject: [PATCH] =?UTF-8?q?bootstrap:=20fixes=20de=20la=20primera=20corrid?= =?UTF-8?q?a=20real=20de=20Stage=201=20(musl+busybox=20=E2=9C=93=20con=20z?= =?UTF-8?q?ig=20cc)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Primera ejecución del runbook en el host. El userland C builda end-to-end; el camino Rust queda bloqueado por una decisión de toolchain. Hallazgos verificados: recipes/busybox.toml — tres incompatibilidades GNU-toolchain ↔ zig, resueltas: - gcc hardcodeado (CC/HOSTCC = gcc con `=` ignora el env): pasar CC='zig cc' HOSTCC='zig cc' en línea de comando de make - flags GNU-ld que zig cc valida y rechaza (--warn-common, -Map, --verbose): quitarlos de scripts/trylink con sed Con esto musl 1.2.5 y busybox 1.36.1 compilan, linkean y se sellan. scripts/bootstrap-devfs.sh — añade rust+cargo al rootfs (las recetas Cargo corren cargo en el sandbox), con CAVEAT: el rust de Alpine es x86_64-alpine-linux-musl pero BuildSys::Cargo pide x86_64-unknown-linux-musl (no instalado, sin rustup) → bloquea hammerd/arje-zero. Decisión de toolchain abierta (plan C.2). docs/runbooks/stage1-vm-boot.md §8 — bitácora con la tabla de etapas, los fixes y las opciones para resolver el triple Rust. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/runbooks/stage1-vm-boot.md | 38 ++++++++++++++++++++++++++++++++- recipes/busybox.toml | 13 ++++++++--- scripts/bootstrap-devfs.sh | 9 +++++++- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/docs/runbooks/stage1-vm-boot.md b/docs/runbooks/stage1-vm-boot.md index 71ffe0af..d36ac3be 100644 --- a/docs/runbooks/stage1-vm-boot.md +++ b/docs/runbooks/stage1-vm-boot.md @@ -119,7 +119,43 @@ qemu-system-x86_64 -m 512 -nographic \ | `No working init` / sin `/dev/console` | kernel sin auto-mount de devtmpfs | crear el nodo en el cpio (`mknod -m 600 dev/console c 5 1` antes de empaquetar) o usar un kernel con `CONFIG_DEVTMPFS_MOUNT=y` | | `cargo vendor` / git clone falla | el fetch necesita red | correr Stage 1 con red; el sandbox de build sigue siendo `--offline` | -## 8. Cross-check opcional — `arje-packager` +## 8. Bitácora — primera corrida real (2026-06-11) + +Corrida en el host de desarrollo (Artix). **Resultado: el userland C builda end-to-end; el camino +Rust está bloqueado por una decisión de toolchain.** Hallazgos, en orden: + +| # | Etapa | Resultado | +|---|---|---| +| 1 | Lab (`bootstrap-devfs.sh`) | ✅ Alpine + zig 0.16.0 + 43 build-tools | +| 2 | Stage 0 (ingerir zig) | ✅ `seed_hash` sellado, idempotente | +| 3 | **musl 1.2.5** | ✅ cross-compila con zig cc y se sella — **el cross-compile C hermético funciona** | +| 4 | **busybox 1.36.1** | ✅ tras tres fixes (abajo); compila y **linkea** con zig cc, se sella | +| 5 | **hammerd** (Cargo) | ❌ bloqueado: triple de toolchain (abajo) | +| 6 | arje-zero (Cargo) | ⏸ no alcanzado (mismo bloqueo; además vendorea el monorepo entero) | + +**Fixes aplicados a `recipes/busybox.toml`** (incompatibilidades GNU-toolchain ↔ zig, esperadas): + +1. **`gcc` hardcodeado.** El Kbuild de busybox fija `CC = gcc` / `HOSTCC = gcc` con `=` (ignora el + env `CC` del sandbox). Fix: pasar `CC='zig cc' HOSTCC='zig cc'` en **línea de comando** de make. +2. **Flags GNU-ld que zig cc rechaza.** El link pasa `-Wl,--warn-common`, `-Wl,-Map,…`, + `-Wl,--verbose`; `zig cc` valida los `-Wl,` y aborta. Fix: quitarlos de `scripts/trylink` con sed. +3. (`gcc` para herramientas host como `fixdep` y `gcc-version.sh` lo cubre el mismo `HOSTCC`.) + +**Bloqueo del camino Rust — decisión de toolchain (plan C.2):** + +- El vendoring (Lote 6) corre OK en el fetch (host, con red). El `cargo build` corre en el sandbox. +- Se añadió `rust cargo` al rootfs (apk) — pero el rust de Alpine tiene host triple + **`x86_64-alpine-linux-musl`**, mientras `BuildSys::Cargo` pide **`--target x86_64-unknown-linux-musl`**. + Alpine no trae ese std y no hay rustup → `error[E0463]: can't find crate for core`. +- **Opciones (a decidir):** (A) construir nativo sin `--target` (el sandbox ya es x86_64 musl) — + cambio en `BuildSys::Cargo`; (B) recetas Cargo con `target = "x86_64-alpine-linux-musl"` — leakage + de Alpine; (C) rustup en el sandbox + `rustup target add` — pierde hermeticidad/pin. Es la misma + tensión de "pin de toolchain entra al hash" que el plan C.2 dejó abierta. + +**Conclusión:** el bootstrap C (musl+busybox+zig cc) está **validado**. Completar el rootfs y el boot +en QEMU requiere resolver el toolchain Rust (hammerd/arje-zero) y más disco (vendor del monorepo). + +## 9. Cross-check opcional — `arje-packager` arje trae su propio empaquetador (`03_ukupacha/arje/init/arje-packager`): `arje-packager --seed --out [--bin LABEL=PATH]…`. Útil para comparar diff --git a/recipes/busybox.toml b/recipes/busybox.toml index b7d4b3ea..3a44b97a 100644 --- a/recipes/busybox.toml +++ b/recipes/busybox.toml @@ -24,7 +24,14 @@ link = "static" # busybox usa Kconfig, no autotools: arrancamos de `defconfig` y forzamos CONFIG_STATIC=y. `tc` # no compila contra musl (gcc-ismos de red), así que lo desactivamos — es el ajuste mínimo # conocido para un build estático limpio con musl. -configure = "make defconfig && sed -i -e 's/^# CONFIG_STATIC is not set/CONFIG_STATIC=y/' -e 's/^CONFIG_TC=y/# CONFIG_TC is not set/' -e 's/^CONFIG_FEATURE_TC_INGRESS=y/# CONFIG_FEATURE_TC_INGRESS is not set/' .config" -compile = "make -j\"$(nproc)\"" +# +# CC='zig cc' HOSTCC='zig cc' EN LÍNEA DE COMANDO: el Kbuild de busybox fija `CC = gcc` y +# `HOSTCC = gcc` con `=` (hard), que ignora el env `CC` del sandbox; sólo un override de línea de +# comando gana. Apunta target (CC) y herramientas host (HOSTCC, p.ej. fixdep/gcc-version.sh) a +# `zig cc`, manteniendo la hermeticidad zig-only (ADR 0003) sin meter gcc al rootfs. +# El link final asume GNU ld y pasa flags que `zig cc` valida y rechaza (`--warn-common`, `-Map`, +# `--verbose`); los quitamos de scripts/trylink. Es la incompatibilidad GNU-ld↔zig/lld esperada. +configure = "make CC='zig cc' HOSTCC='zig cc' defconfig && sed -i -e 's/^# CONFIG_STATIC is not set/CONFIG_STATIC=y/' -e 's/^CONFIG_TC=y/# CONFIG_TC is not set/' -e 's/^CONFIG_FEATURE_TC_INGRESS=y/# CONFIG_FEATURE_TC_INGRESS is not set/' .config && sed -i -e 's/-Wl,--warn-common//g' -e 's/-Wl,-Map,[^ ]*//g' -e 's/-Wl,--verbose//g' scripts/trylink" +compile = "make -j\"$(nproc)\" CC='zig cc' HOSTCC='zig cc'" # busybox instala en CONFIG_PREFIX (no DESTDIR): bin/busybox + symlinks de cada applet. -install = "make CONFIG_PREFIX=/out install" +install = "make CC='zig cc' HOSTCC='zig cc' CONFIG_PREFIX=/out install" diff --git a/scripts/bootstrap-devfs.sh b/scripts/bootstrap-devfs.sh index 92b77532..b82b68c5 100755 --- a/scripts/bootstrap-devfs.sh +++ b/scripts/bootstrap-devfs.sh @@ -106,7 +106,14 @@ if [[ $SKIP_APK -eq 1 ]]; then else # `binutils` aporta ld/ar/ranlib/nm/strip: configure de autotools los inspecciona # incluso cuando el compilador real es zig cc. - NEEDED="make autoconf automake m4 patch coreutils libtool pkgconf bash binutils" + # + # `rust cargo`: las recetas Cargo (hammerd, arje-zero) corren `cargo build` DENTRO del + # sandbox. CAVEAT (primera corrida 2026-06-11): el rust de Alpine tiene host triple + # `x86_64-alpine-linux-musl`, pero `BuildSys::Cargo` pide `--target x86_64-unknown-linux-musl` + # y Alpine no trae ese std (no hay rustup). Falta resolver el toolchain Rust del lab (plan C.2) + # — ver docs/runbooks/stage1-vm-boot.md §8. Hasta entonces, los componentes C (musl, busybox) + # sí construyen end-to-end. + NEEDED="make autoconf automake m4 patch coreutils libtool pkgconf bash binutils rust cargo" missing="" for pkg in $NEEDED; do # apk info -e devuelve el paquete si está instalado, vacío si no.