# Importada de Alpine aports por `takana import-alpine` (Etapa G). PUNTO DE PARTIDA — pero # YA trae los parches de musl de Alpine (lo que un import de nix pierde). Adaptada al tarball # limpio de GNU (5.3 base, sin los parches upstream), build estático musl. name = "bash" version = "5.3" license = "GPL-3.0-or-later" [source] tarball = "https://ftp.gnu.org/gnu/bash/bash-5.3.tar.gz" sha256 = "0d5cd86965f869a26cf64f4b71be7b96f90a3ba8b3d74e27e8e9d9d5550f31ba" [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" # Split de la info de depuración (SDD 23 etapa 4, tanda de HOJAS). Entra en `hash_inputs`. strip_debug = true flags = [] # ── POR QUÉ ESTÁTICO, Y QUÉ CUESTA (audit 2026-08-31) ───────────────────────────────────────── # La receta decía `link = "static"` y el binario salía DINÁMICO contra `libncursesw.so.6` y # `libc.so`. No era purismo: **NINGÚN artefacto del corpus provee esas dos** —el de `ncurses` sólo # empaqueta `.a`— así que el bash sellado sólo corría dentro del sandbox de Alpine y **no dentro de # una imagen de takana**, estando en los perfiles `base`, `cli`, `escritorio-cosmic` y # `escritorio-sway`. Un shell del sistema base que no arranca en el sistema base. # # EVIDENCIA de que no arrancaba, ejecutando el binario sellado anterior en el host: # Error relocating /lib/libncursesw.so.6: __vfprintf_chk: symbol not found # El mismo síntoma que curl en su día. El nuevo sale `statically linked`, dice # `5.3.0(1)-release (x86_64-pc-linux-musl)` y pasa arrays, asociativos, aritmética, sustitución # de comandos y `=~`. # # ⚠ EL PRECIO, medido: **el artefacto pasa de 122 a 16 ficheros**. No es una pérdida accidental # sino el acoplamiento de upstream: `configure.ac:981` salta `AC_CHECK_LIB(dl, dlopen)` y # `AC_CHECK_FUNCS(dlopen …)` cuando `opt_static_link=yes`, y sin `HAVE_DLOPEN` bash no construye # ni instala los ~40 cargables de `usr/lib/bash/` (`enable -f`), sus 62 headers de # `usr/include/bash/`, ni `usr/lib/pkgconfig/bash.pc`. Es correcto: **un binario estático no puede # `dlopen`**, así que instalarlos sería publicar una capacidad que no existe — el fallo silencioso # de CLAUDE.md §3. Y lo que se pierde no funcionaba igual: dinámico no eran «cargables que # funcionan», era «un bash que no arranca». # Nadie depende de ellos: `yupana radio bash` da 0 dependientes directos y 0 transitivos. # Si algún día se quieren de vuelta, la decisión es de imagen —bash dinámico + hidratar la `.so` # de ncurses— y no de esta línea. # # Es la misma causa que htop y e2fsprogs, y NO es libtool: es el `-rdynamic` de upstream contra la # regla del wrapper. Ver la nota en `compile`. [build.phases] # de build() de Alpine (traducido; el lab provee $CBUILD/$CHOST — Etapa G Fase 3): compile = ''' _abuild_phase() { ./configure \ --build=$CBUILD \ --host=$CHOST \ --prefix=/usr \ --bindir=/bin \ --mandir=/usr/share/man \ --infodir=/usr/share/info \ --disable-nls \ --enable-readline \ --without-bash-malloc \ --without-installed-readline \ --enable-static-link # parallel build workarounds # `LOCAL_LDFLAGS=`: `configure.ac:1223` pone `LOCAL_LDFLAGS=-rdynamic` en linux*, y el wrapper # de cc del lab (`sandbox.rs:597`) tira el `-static` inyectado ante `-rdynamic` ⇒ bash salía # DINÁMICO contra `libncursesw.so.6` y `libc.so`. **`--enable-static-link` SOLO NO ALCANZA**: # pone `STATIC_LD=-static` (`Makefile.in:170`) pero queda en la misma línea que el `-rdynamic` # de `BASE_LDFLAGS`, y el wrapper mira la línea entera. Van los dos. make y.tab.c && make builtins/libbuiltins.a && make LOCAL_LDFLAGS= } _abuild_phase ''' # de package() de Alpine (traducido $pkgdir→/out); sin bashrc/profile (ficheros ausentes): install = ''' _abuild_phase() { mkdir -p "/out"/etc/bash make DESTDIR="/out" install LOCAL_LDFLAGS= rm -rf "/out"/usr/share/locale } _abuild_phase ''' [deps] build = ["binutils", "ncurses", "readline", "linux-headers", "make"]