From 1940a94a118f7040e26f2c2872764c06e601bd1d Mon Sep 17 00:00:00 2001 From: Sergio Date: Wed, 12 Aug 2026 00:55:01 +0000 Subject: [PATCH] =?UTF-8?q?lab:=20los=20-dev=20al=20rootfs=20=E2=80=94=20e?= =?UTF-8?q?s=20el=20unico=20sitio=20donde=20=5Fcurses=20se=20puede=20resol?= =?UTF-8?q?ver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Decision del usuario. CPython construye sus modulos opcionales como .so COMPARTIDOS y las .a del corpus NO son PIC («relocation R_X86_64_PC32 against symbol 'stdscr'»), asi que declararlas en [deps] NO funciona: se probo una por una. Las libs del rootfs son compartidas y si sirven. Añadidos: libffi-dev ncurses-dev readline-dev sqlite-dev bzip2-dev xz-dev expat-dev. Resultado VERIFICADO: el guardian de python3 importa los OCHO modulos (_ctypes _curses readline sqlite3 bz2 lzma zlib pyexpat) y pasa. De paso `libffi` sale de [deps]: ya lo aporta el lab. openssl-dev NO va, deliberado: se de-Alpinizo porque el host-tool del kernel enlaza el openssl del corpus desde el overlay; devolverlo podria cambiar el artefacto del kernel. python3 sigue sin `ssl`. Y SE CIERRA EL AGUJERO QUE ESTO ABRIA. Esas libs del rootfs ahora entran en el CONTENIDO de un artefacto, asi que su version es parte de su identidad ⇒ van a TOOLCHAIN_PREFIXES. Sin eso habriamos reabierto en pequeño el mismo fallo que 58d3161 cerro: instalar los -dev subio ncurses 6.5→6.6 y readline 8.3.1→8.3.3 —sin tocar gcc/rust/musl, lo confirmo el lock— y ese salto habria cambiado el python3 producido SIN mover su direccion. Coste: la huella del lab cambia ⇒ el corpus se re-hashea otra vez. Se hace AHORA a proposito, con 194 artefactos, no con el corpus a medio construir. Co-Authored-By: Claude Opus 5 (1M context) --- crates/hammer-core/src/lab.rs | 16 ++++++++++++++++ docs/state/lab-toolchain.lock | 21 ++++++++++++++++++--- recipes/python3.toml | 4 ++-- scripts/bootstrap-devfs.sh | 18 +++++++++++++++++- 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/crates/hammer-core/src/lab.rs b/crates/hammer-core/src/lab.rs index c8dbb063..4e3a7df3 100644 --- a/crates/hammer-core/src/lab.rs +++ b/crates/hammer-core/src/lab.rs @@ -76,6 +76,22 @@ pub const TOOLCHAIN_PREFIXES: &[&str] = &[ "mpfr4", "musl", "rust", + // ── librerías del rootfs que los artefactos ENLAZAN (añadidas 2026-08-12) ────────────────── + // Normalmente una receta toma sus libs de `[deps]` (el corpus), no del rootfs, y por eso esta + // lista era sólo el toolchain. `python3` es la excepción forzada: CPython construye sus módulos + // opcionales como `.so` y las `.a` del corpus no son PIC, así que sus headers TIENEN que venir + // del lab. En cuanto una lib del rootfs entra en el CONTENIDO de un artefacto, su versión es + // parte de la identidad del build — dejarla fuera reabriría, en pequeño, el mismo agujero que + // este módulo existe para cerrar: mismo hash, distintos bytes. + // Comprobado en la misma pasada: instalar los `-dev` subió ncurses 6.5→6.6 y readline + // 8.3.1→8.3.3 sin tocar gcc/rust/musl. Si no estuvieran aquí, ese salto habría cambiado el + // python3 producido SIN mover su dirección. + "bzip2", + "expat", + "ncurses", + "readline", + "sqlite", + "xz", ]; /// Huella del toolchain del lab. Opaca a propósito: sólo se compara y se mete al hash. diff --git a/docs/state/lab-toolchain.lock b/docs/state/lab-toolchain.lock index cda331c7..5cadec8a 100644 --- a/docs/state/lab-toolchain.lock +++ b/docs/state/lab-toolchain.lock @@ -15,6 +15,7 @@ brotli-libs-1.2.0-r1 bubblewrap-0.11.2-r0 busybox-1.37.0-r30 busybox-binsh-1.37.0-r30 +bzip2-dev-1.0.8-r6 c-ares-1.34.8-r0 ca-certificates-bundle-20260413-r0 cargo-1.97.0-r0 @@ -29,6 +30,8 @@ coreutils-env-9.8-r1 coreutils-fmt-9.8-r1 coreutils-sha512sum-9.8-r1 curl-8.21.0-r0 +expat-2.8.2-r0 +expat-dev-2.8.2-r0 fortify-headers-3.0.2-r0 g++-15.2.0-r8 gcc-15.2.0-r8 @@ -48,12 +51,18 @@ libcrypto3-3.5.6-r0 libcurl-8.21.0-r0 libexpat-2.8.2-r0 libffi-3.5.2-r1 +libffi-dev-3.5.2-r1 +libformw-6.6_p20260516-r0 libgcc-15.2.0-r2 libgcc-static-15.2.0-r8 libgomp-15.2.0-r8 +libhistory-8.3.3-r1 libidn2-2.3.8-r0 libltdl-2.5.4-r2 -libncursesw-6.5_p20251123-r0 +libmenuw-6.6_p20260516-r0 +libncurses++-6.6_p20260516-r0 +libncursesw-6.6_p20260516-r0 +libpanelw-6.6_p20260516-r0 libpsl-0.21.5-r3 libssh2-1.11.1-r3 libssl3-3.5.6-r0 @@ -73,7 +82,8 @@ mpfr4-4.2.2-r0 musl-1.2.6-r2 musl-dev-1.2.6-r2 musl-utils-1.2.5-r23 -ncurses-terminfo-base-6.5_p20251123-r0 +ncurses-dev-6.6_p20260516-r0 +ncurses-terminfo-base-6.6_p20260516-r0 nghttp2-libs-1.70.0-r0 patch-2.8-r0 pcre2-10.47-r1 @@ -81,14 +91,19 @@ perl-5.42.2-r0 perl-error-0.17030-r0 perl-git-2.55.0-r1 pkgconf-2.5.1-r0 -readline-8.3.1-r0 +readline-8.3.3-r1 +readline-dev-8.3.3-r1 rust-1.97.0-r0 scanelf-1.3.8-r2 scudo-malloc-22.1.8-r0 skalibs-libs-2.14.4.0-r0 +sqlite-3.53.4-r0 +sqlite-dev-3.53.4-r0 sqlite-libs-3.53.4-r0 ssl_client-1.37.0-r30 utmps-libs-0.1.3.1-r0 +xz-5.8.3-r0 +xz-dev-5.8.3-r0 xz-libs-5.8.3-r0 zlib-1.3.2-r0 zlib-dev-1.3.2-r0 diff --git a/recipes/python3.toml b/recipes/python3.toml index 691e4945..54b4b93b 100644 --- a/recipes/python3.toml +++ b/recipes/python3.toml @@ -70,7 +70,7 @@ zig_version = "0.13.0" # NO trae `sqlite3`, `bz2`, `lzma` ni `readline`. Ninguna receta del corpus los necesita para # construir; habilitarlos pide recetas PIC de esas libs, que es un frente aparte. # Se declara sólo lo que arregla un fallo MEDIDO: libffi (_ctypes) y ncurses (_curses). -build = ["zlib", "pkgconf", "libffi"] +build = ["zlib", "pkgconf"] [build.phases] configure = "./configure --prefix=/usr --without-ensurepip --disable-test-modules --with-ensurepip=no CFLAGS=\"-Wno-error=date-time\"" @@ -81,4 +81,4 @@ compile = "make -j\"$(nproc)\"" # Importarlos aquí convierte eso en un fallo de build, en la receta correcta y en el momento correcto. # Se usa el intérprete recién instalado en /out, no el del rootfs, o no probaría nada. install = '''make install DESTDIR=/out && \ -LD_LIBRARY_PATH=/out/usr/lib /out/usr/bin/python3 -c "import _ctypes, zlib; print('modulos opcionales: OK')"''' +LD_LIBRARY_PATH=/out/usr/lib /out/usr/bin/python3 -c "import _ctypes, _curses, readline, sqlite3, bz2, lzma, zlib, pyexpat; print('modulos opcionales: OK')"''' diff --git a/scripts/bootstrap-devfs.sh b/scripts/bootstrap-devfs.sh index 63b93d49..b0cd7c8a 100755 --- a/scripts/bootstrap-devfs.sh +++ b/scripts/bootstrap-devfs.sh @@ -218,7 +218,23 @@ else # con clang exige llvm-ar y llvm-objdump ⇒ sin esto configure aborta "Cannot find ar/llvm-objdump". # Alpine deja los binarios en /usr/lib/llvm22/bin SIN symlinkear a /usr/bin (multi-versión); el paso # 3a-ter de abajo los expone en el PATH estándar, igual que Alpine ya hace con `clang`. - NEEDED="make autoconf automake m4 patch coreutils libtool pkgconf bash binutils g++ zlib-dev rust cargo clang-dev clang-libs llvm22 linux-headers bubblewrap git curl kmod" + # `libffi-dev ncurses-dev readline-dev sqlite-dev bzip2-dev xz-dev expat-dev`: los HEADERS que + # CPython necesita para sus módulos opcionales. Sin ellos `configure` los omite EN SILENCIO y + # sella un intérprete mutilado que arranca bien; el fallo aparece días después en otra receta + # (`ModuleNotFoundError: No module named '_ctypes'` en gjs, `_curses` en gdm — 2026-08-11), y + # **310 recetas dependen de python3**. + # + # POR QUÉ EN EL ROOTFS Y NO COMO `[deps]` DE LA RECETA, que sería lo habitual: se intentó y NO + # FUNCIONA. CPython construye sus módulos opcionales como `.so` COMPARTIDOS y las `.a` del corpus + # NO son PIC ⇒ `ld.lld: relocation R_X86_64_PC32 cannot be used against symbol 'stdscr'; + # recompile with -fPIC`. Las libs del rootfs son compartidas y sí sirven. Mientras no existan + # recetas PIC de esas libs, el lab es el único sitio donde esto se resuelve. + # + # ⚠ `openssl-dev` NO va, y es deliberado: se de-Alpinizó a `recipes/openssl.toml` porque el + # host-tool del kernel enlaza el openssl del corpus desde la capa overlay. Devolverlo al rootfs + # podría hacer que el kernel linkee el de Alpine y cambiar su artefacto. ⇒ python3 sigue sin + # módulo `ssl`; ninguna receta lo necesita para construir, `pip` sí lo necesitaría. + NEEDED="make autoconf automake m4 patch coreutils libtool pkgconf bash binutils g++ zlib-dev rust cargo clang-dev clang-libs llvm22 linux-headers bubblewrap git curl kmod libffi-dev ncurses-dev readline-dev sqlite-dev bzip2-dev xz-dev expat-dev" missing="" for pkg in $NEEDED; do # apk info -e devuelve el paquete si está instalado, vacío si no.