# autoconf 2.72 — el generador de `configure`. Entra porque su AUSENCIA ya costó trabajo real. # # ══ POR QUÉ ENTRA AHORA, Y NO «algún día» ══════════════════════════════════════════════════════ # El censo lo marca en «construcción C clásica», pero el argumento no es la fila del censo: es que # **este hueco se pisó tres veces en una sola tarde** (2026-10-20). Cada vez que un paquete publica # sólo `configure.ac` y no un tarball de release, el lab no puede construirlo: # # · `pcaudiolib` se salvó usando el asset del release en vez del archive del tag # · `speech-dispatcher` lo mismo # · `brltty` lo mismo # · `dotconf` **NO se salvó**: upstream no publica releases (el asset da 404), así que # hubo que compilar sus dos `.c` a mano. Funciona, pero es una receta que # no se parece a ninguna otra del repo # # O sea que la regla «mirá si publica un tarball de release antes de escribir el autoconf» es una # mitigación, no una solución: el día que haga falta un paquete que sólo tenga `configure.ac` y sea # más grande que dos ficheros, no hay salida. ⇒ con autoconf en el corpus, `autoreconf -fi` pasa a # ser una opción normal. # # ⚠ **Lo que NO cambia:** las recetas existentes que usan el tarball del release **se quedan como # están**. Usar el `configure` que upstream publicó es MÁS reproducible que regenerarlo —el nuestro # saldría de nuestra versión de autoconf/automake, que es un input más—, así que esto abre una # puerta, no manda rehacer nada. # # ══ ES BARATO PORQUE `perl` Y `m4` YA ESTÁN ════════════════════════════════════════════════════ # autoconf es un puñado de scripts de perl más una biblioteca de macros m4; no compila nada. Los dos # ya están en el corpus, así que el coste es esta receta y nada más. # # ⚠ **`m4` y `perl` van también en `[deps] runtime`, y eso NO es redundancia.** autoconf los invoca # **al ejecutarse**, no al construirse: sin ellos en la imagen es un script que no puede trabajar — # la figura del «subcomando sin driver» que este repo tiene documentada. Un `[deps] build` solo los # pondría en el sandbox y los dejaría fuera de la clausura. name = "autoconf" version = "2.72" license = "GPL-3.0-or-later" [source] tarball = "https://ftp.gnu.org/gnu/autoconf/autoconf-2.72.tar.xz" sha256 = "ba885c1319578d6c94d46e9b0dceb4014caafe2490e437a0dbca3f270a223f5a" [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" flags = [] [build.phases] configure = './configure --build=$CBUILD --host=$CHOST --prefix=/usr --sysconfdir=/etc' compile = 'make -j"$(nproc)"' # ⚠ EL GUARDIÁN CORRE LA HERRAMIENTA DE VERDAD, y es el punto de esta receta. # # autoconf no es un binario: son scripts de perl con rutas —a `perl`, a `m4`, a su propio # directorio de macros— **horneadas al configurar**. Un artefacto puede quedar completo, sellado y # reproducible, y ser un script que muere en la primera línea porque su intérprete no está donde # dice. Comprobar que los ficheros existen no distingue esos dos casos; ejecutarlo, sí. # # ⇒ Se genera un `configure` desde un `configure.ac` mínimo y se comprueba que SALGA y que sea un # script ejecutable de verdad. Es la prueba de extremo a extremo más corta posible. install = ''' set -e make install DESTDIR=/out for b in autoconf autoreconf autoheader autom4te autoscan autoupdate ifnames; do [ -x "/out/usr/bin/$b" ] || { echo "autoconf: falta /usr/bin/$b" >&2; ls /out/usr/bin 2>/dev/null >&2; exit 1; } done n=$(find /out/usr/share/autoconf -name '*.m4*' 2>/dev/null | wc -l) [ "$n" -gt 20 ] || { echo "autoconf: sólo $n fichero(s) de macros m4 — sin su biblioteca no puede expandir nada" >&2; exit 1; } # PRUEBA FUNCIONAL. `AC_INIT`+`AC_OUTPUT` es el `configure.ac` más corto que produce algo. # # ⚠⚠ **Y LA PRIMERA VERSIÓN DE ESTA PRUEBA ERA INVÁLIDA: usaba los datos DEL LAB.** # `bin/autoconf` resuelve su directorio de macros así (líneas 32 y 47-48): # # my $pkgdatadir = $ENV{'autom4te_perllibdir'} || '/usr/share/autoconf'; # my $autom4te = $ENV{'AUTOM4TE'} || '/usr/bin/autom4te'; # my $trailer_m4 = $ENV{'trailer_m4'} || '/usr/share/autoconf/autoconf/trailer.m4'; # # o sea rutas ABSOLUTAS al destino final. Yo sólo exportaba `AUTOCONF` y `PATH`, así que el script # leía `/usr/share/autoconf`… **que EXISTE en el lab**: la imagen base trae `autoconf`, # `automake-1.18` y sus macros (medido en `.dev-fs/alpine`). El `configure` que salió era correcto y # no probaba nada de NUESTRO artefacto — habría salido igual con `/out` vacío de macros. # # ⇒ Ahora cada ruta se apunta a `/out` explícitamente. Si el artefacto no es autosuficiente, falla. # # ⚠ **Y el corolario importa más que esta receta:** cualquier receta que invoque `autoreconf` o # `autoconf` SIN fijar estas variables usará **el autoconf del lab**, y el lab **no entra en # `hash_inputs`** — o sea que dos labs distintos sellarían bytes distintos y el build parecería # correcto en los dos. Es exactamente la razón por la que estas dos recetas entran al corpus: no # para «tener autoconf», sino para poder usarlo de forma reproducible. t=$(mktemp -d) printf 'AC_INIT([prueba],[1])\nAC_OUTPUT\n' > "$t/configure.ac" ( cd "$t" && env \ PATH="/out/usr/bin:$PATH" \ AUTOCONF="/out/usr/bin/autoconf" \ AUTOM4TE="/out/usr/bin/autom4te" \ autom4te_perllibdir="/out/usr/share/autoconf" \ AC_MACRODIR="/out/usr/share/autoconf" \ trailer_m4="/out/usr/share/autoconf/autoconf/trailer.m4" \ /out/usr/bin/autoconf ) || { echo "autoconf: NO PUDO generar un configure usando SÓLO sus propios datos — el artefacto está completo y no es autosuficiente" >&2 exit 1 } [ -s "$t/configure" ] || { echo "autoconf: corrió sin error y no dejó ningún ./configure" >&2; ls -la "$t" >&2; exit 1; } head -1 "$t/configure" | grep -q '^#!' || { echo "autoconf: el configure generado no empieza por un shebang — no es un script ejecutable" >&2; head -3 "$t/configure" >&2; exit 1; } echo "autoconf: 7 herramientas + $n macro(s) + genera un configure de $(wc -l < "$t/configure") líneas" ''' [deps] build = ["make", "perl", "m4"] # Ver la nota de arriba: autoconf los invoca al EJECUTARSE. runtime = ["perl", "m4"]