Files
SergioandClaude Opus 5 c5a27d9b4c busybox recortado: 401 -> 277 applets, con vigía y cinco indultos medidos
Paso 1 de docs/plan-botar-busybox.md. 124 applets fuera del defconfig: los 105 que
no se reemplazan (dpkg, rpm, httpd, telnetd, ubi*, nand*, i2c*) y 19 cuya función ya
hace otro componente (init/runit -> arje-zero, syslogd/klogd/logread -> hammerd).
Binario de 1.230.976 a 977.096 bytes.

CORRIGE UN ERROR DEL PLAN: arje-zero y hammerd reemplazan la FUNCIÓN, no el COMANDO
-- son un binario cada uno. Por eso 5 indultos: setuidgid (la card de gitea lo
ejecuta), switch_root (el /init del instalador, antes de que arje exista) y
poweroff/halt/reboot (nada más en el corpus apaga la máquina).

scripts/busybox-vigia.py falla si alguien invoca un applet retirado; lee la lista de
la propia receta para que no haya dos que se desincronicen. Su primera versión daba
91 hits y ninguno real: las cuatro reglas que lo bajaron a 0 están documentadas.

El mapa applet->símbolo sale de las líneas //applet: del fuente, no de poner el
nombre en mayúsculas: eso falla en 6 casos medidos, dos de ellos en la lista.

Verificado: 277 applets exactos, los 5 indultados presentes, y zlib-ng, jq y
logrotate reconstruidas y selladas con el busybox recortado -- el sandbox sigue en
pie. Son 3 de las 24 dependientes, no las 24, y el boot de la imagen no se probó.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-21 18:26:01 +00:00

67 lines
5.4 KiB
TOML

# busybox 1.36.1 — coreutils + shell + init del userland mínimo del Stage 1 (SDD 11 §3).
#
# Es la "balsa desechable" (ADR 0008): se sustituye por el userland multi-call nativo en
# Rust/Zig más adelante; mientras tanto da `sh`, las utilidades de manipulación de texto que el
# pipeline asume, y su propio `init` (PID 1 provisional, vía /etc/inittab que ensambla Stage 1).
#
# Estático con `zig cc` cross al target: el binario es autocontenido, sin loader del host. El
# `install` de busybox crea los symlinks de applets (sh, mount, init, …) bajo CONFIG_PREFIX, que
# el ensamblado del rootfs hidrata tal cual.
name = "busybox"
version = "1.36.1"
license = "GPL-2.0-only"
[source]
tarball = "https://busybox.net/downloads/busybox-1.36.1.tar.bz2"
sha256 = "b8cc24c9574d809e7279c3be349795c5d5ceb6fdf19ca709f80cde50e47de314"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "static"
[deps]
build = ["make"]
[build.phases]
# 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.
#
# CC='zig cc -mcpu=baseline' HOSTCC='zig cc -mcpu=baseline' 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.
#
# ── EL RECORTE (docs/plan-botar-busybox.md, paso 1) ──────────────────────────────────────────────
# `RETIRADOS` apaga 124 de los 401 applets que `defconfig` instala. No es adelgazar por adelgazar:
# cada uno o NO SE REEMPLAZA (dpkg, rpm, httpd, telnetd, ubi*, nand*, i2c*: 105) o su función ya la
# hace otro componente del producto (init/runit -> arje-zero, syslogd/klogd/logread -> hammerd: 19).
#
# ⚠ Y 5 se INDULTARON a propósito, porque arje-zero y hammerd reemplazan la FUNCIÓN pero no instalan
# un COMANDO con ese nombre — son un binario cada uno:
# setuidgid la card de gitea hace `setuidgid gitea` (recipes/gitea.toml:89)
# switch_root el /init del instalador lo ejecuta (scripts/takana-live-install.sh:375)
# poweroff/halt/reboot nada más en el corpus apaga la máquina: arje-zero es PID 1, no una CLI
#
# El mapa applet->símbolo sale de las líneas `//applet:` del fuente, NO de poner el nombre en
# mayúsculas: eso falla en 6 casos medidos (`[`->TEST1, `[[`->TEST2, arch->BB_ARCH, sh->SH_IS_ASH…).
# Está en la columna `simbolo_kconfig` de docs/state/busybox-applets.tsv.
#
# ⚠ Tocar esta lista RE-HASHEA busybox, y con él las 24 recetas que lo declaran build-dep.
# `scripts/busybox-vigia.py` falla si alguien invoca un applet retirado — sin él esto se deshace
# solo, porque quitar un applet no rompe nada hasta que arranca una máquina, semanas después.
#
# `yes '' | make oldconfig` tras editar .config: sin esto, el compile corre `silentoldconfig`, que
# al ver opciones NEW (p.ej. WERROR) **prompea interactivamente** leyendo stdin — build
# no-determinista y flaky (lo destapó la verificación de reproducibilidad de Stage 2). `yes ''`
# acepta el default de cada NEW ⇒ config resuelta y determinista (busybox 1.36.1 no tiene el target
# `olddefconfig`, así que usamos `oldconfig` alimentado por `yes`).
configure = "make CC='zig cc -mcpu=baseline' HOSTCC='zig cc -mcpu=baseline' 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 && RETIRADOS='ACPID ADJTIMEX ASCII BEEP BOOTCHARTD CHAT CHPST CONSPY CRC32 DEVMEM DHCPRELAY DNSD DNSDOMAINNAME DOS2UNIX DPKG DPKG_DEB ED ENVDIR ENVUIDGID ETHER_WAKE FAKEIDENTD FATATTR FBSET FBSPLASH FDFLUSH FDFORMAT FREERAMDISK FSYNC FTPD FTPGET FTPPUT HDPARM HEXEDIT HTTPD I2CDETECT I2CDUMP I2CGET I2CSET I2CTRANSFER IFPLUGD INETD INIT IOSTAT IPCALC KLOGD LINUXRC LOGGER LOGREAD LPD LPQ LPR LSSCSI LZOP MAKEMIME MICROCOM MIM MPSTAT MT NANDDUMP NANDWRITE NBDCLIENT NMETER PIPE_PROGRESS POPMAILDIR POWERTOP PSCAN RAIDAUTORUN RDEV READAHEAD REFORMIME RESIZE RESUME RPM RPM2CPIO RUNLEVEL RUNSV RUNSVDIR RUN_INIT RX SEEDRNG SENDMAIL SETCONSOLE SETFATTR SETLOGCONS SETSERIAL SHA3SUM SMEMCAP SOFTLIMIT SSL_CLIENT START_STOP_DAEMON SV SVC SVLOGD SVOK SYSLOGD TCPSVD TELNET TELNETD TEST2 TFTP TFTPD TIME TREE TS TTYSIZE UBIATTACH UBIDETACH UBIMKVOL UBIRENAME UBIRMVOL UBIRSVOL UBIUPDATEVOL UDHCPD UDPSVD UNIX2DOS UNZIP USLEEP UUDECODE UUENCODE VOLNAME WATCHDOG WHICH WHOIS ZCIP' && for s in $RETIRADOS; do sed -i \"s/^CONFIG_$s=y$/# CONFIG_$s is not set/\" .config; done && yes '' | make CC='zig cc -mcpu=baseline' HOSTCC='zig cc -mcpu=baseline' oldconfig && 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 -mcpu=baseline' HOSTCC='zig cc -mcpu=baseline'"
# busybox instala en CONFIG_PREFIX (no DESTDIR): bin/busybox + symlinks de cada applet.
install = "make CC='zig cc -mcpu=baseline' HOSTCC='zig cc -mcpu=baseline' CONFIG_PREFIX=/out install"