From 099e84703f378bc10638983434b9208f1b049f4e Mon Sep 17 00:00:00 2001 From: Sergio Date: Thu, 3 Sep 2026 20:16:51 +0000 Subject: [PATCH] imagen: inyectar libffi/expat/bzip2 COMPARTIDAS desde el store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El cierre hidratado sólo trae los .a de estas tres (sus recetas canónicas son --disable-shared), pero libgobject, libgirepository, libwayland-{client,server}, libp11-kit y libgjs salen con símbolos ffi_*, mesa entero (iris/swrast/kms_swrast, libEGL, libgbm) con XML_* y freetype con BZ2_*. En el host eso resuelve contra el sysroot Alpine del LAB —así que el artefacto sella y el perfil da 100%— y en la imagen el loader de musl aborta: Error relocating /usr/lib/libgobject-2.0.so.0: ffi_call: symbol not found gnome-shell moría con código 127 antes de exponer wayland-0, y con él login1, Accounts, UPower, colord y wireplumber. Es el punto ciego que documenta scripts/vigia-sonames.py, visto desde el lado de la imagen. Con la inyección: 'compositor OK (wayland-0)' y el shell pinta (evidencia adjunta). Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_0164nrZWZc78Mr2srrsnoM8U --- ...shell-qemu-2026-09-03-libs-compartidas.png | Bin 0 -> 5898 bytes scripts/gnome/qemu-desktop-image.sh | 2 + scripts/kde/qemu-desktop-image.sh | 2 + scripts/lib/libs-compartidas-desde-store.sh | 43 ++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 docs/evidencia/gnome-shell-qemu-2026-09-03-libs-compartidas.png create mode 100644 scripts/lib/libs-compartidas-desde-store.sh diff --git a/docs/evidencia/gnome-shell-qemu-2026-09-03-libs-compartidas.png b/docs/evidencia/gnome-shell-qemu-2026-09-03-libs-compartidas.png new file mode 100644 index 0000000000000000000000000000000000000000..c4cf2509ebcc1fd2f265036a58c102175bd18597 GIT binary patch literal 5898 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 Y`_?`xyzRl-FBx#u$@LKVKtSr>0Oh{4Y5)KL literal 0 HcmV?d00001 diff --git a/scripts/gnome/qemu-desktop-image.sh b/scripts/gnome/qemu-desktop-image.sh index 9e482248..a29ccb40 100755 --- a/scripts/gnome/qemu-desktop-image.sh +++ b/scripts/gnome/qemu-desktop-image.sh @@ -32,7 +32,9 @@ cp -al "$BASE" "$MERGED" cp -al --remove-destination "$GNOME"/. "$MERGED"/ . "$ROOT/scripts/lib/pid1-desde-store.sh" +. "$ROOT/scripts/lib/libs-compartidas-desde-store.sh" inyectar_pid1 "$MERGED" "$BASE" +inyectar_libs_compartidas "$MERGED" echo "==> parcheando mesa software desde $MESA" # El cierre GNOME trae mesa con SÓLO iris_dri.so (Intel real). En QEMU no hay GPU: hace falta diff --git a/scripts/kde/qemu-desktop-image.sh b/scripts/kde/qemu-desktop-image.sh index 98c5dd94..eb87860f 100755 --- a/scripts/kde/qemu-desktop-image.sh +++ b/scripts/kde/qemu-desktop-image.sh @@ -35,7 +35,9 @@ cp -al "$BASE" "$MERGED" cp -al --remove-destination "$KDE"/. "$MERGED"/ . "$ROOT/scripts/lib/pid1-desde-store.sh" +. "$ROOT/scripts/lib/libs-compartidas-desde-store.sh" inyectar_pid1 "$MERGED" "$BASE" +inyectar_libs_compartidas "$MERGED" echo "==> parcheando mesa (software GL) desde $MESA (llvmpipe=$LLVMPIPE)" # el artefacto trae usr/lib/{dri/*swrast*,libEGL,libgbm,libglapi,libGLESv2}; copiamos SIN --remove para diff --git a/scripts/lib/libs-compartidas-desde-store.sh b/scripts/lib/libs-compartidas-desde-store.sh new file mode 100644 index 00000000..d57e42f4 --- /dev/null +++ b/scripts/lib/libs-compartidas-desde-store.sh @@ -0,0 +1,43 @@ +# libs-compartidas-desde-store.sh — helper compartido por los scripts de imagen: poner en el rootfs +# fundido las librerías COMPARTIDAS que el cierre hidratado NO trae, tomándolas de su artefacto +# sellado (`-shared`). +# +# ── POR QUÉ EXISTE ────────────────────────────────────────────────────────────────────────────── +# La receta canónica de libffi/expat/bzip2 es `--disable-shared`: su artefacto publica sólo el `.a`. +# Pero libgobject, libgirepository, libwayland-{client,server}, libp11-kit y libgjs salen con +# `NEEDED`/símbolos `ffi_*`, y mesa entero (iris_dri, swrast_dri, kms_swrast_dri, libEGL, libgbm) +# con `XML_*`. En el HOST eso resuelve contra el sysroot Alpine DEL LAB, así que el artefacto sella, +# el perfil reporta 100% y nadie se entera. En la imagen no hay lab: el loader de musl aborta con +# +# Error relocating /usr/lib/libgobject-2.0.so.0: ffi_call: symbol not found +# +# y el escritorio muere con código 127 antes de pintar. Es el mismo punto ciego que documenta +# `scripts/vigia-sonames.py` («mesa y wayland pidiendo expat y libffi»), visto desde el lado de la +# imagen: el cierre de BUILD no es el cierre de RUNTIME. +# +# El artefacto se elige por `hammer hash` sobre la receta —el de la receta de HOY—, no por el más +# reciente del store: con dos artefactos del mismo paquete conviviendo, la fecha no dice cuál rige. +# Mismo criterio que `pid1-desde-store.sh` y que los inyectores de arje-*-compat. +# +# ABORTA si falta un artefacto. Deliberado: seguir sin él produce una imagen que arranca hasta el +# escritorio y muere ahí, que es el modo de falla que este helper existe para cerrar. +# +# Uso: . scripts/lib/libs-compartidas-desde-store.sh ; inyectar_libs_compartidas "$MERGED" +# Var: LIBS_COMPARTIDAS="libffi-shared expat-shared bzip2-shared" (override de la lista) + +inyectar_libs_compartidas() { + local merged="$1" recetas hash dir n + recetas="${LIBS_COMPARTIDAS:-libffi-shared expat-shared bzip2-shared}" + echo "==> libs compartidas del store (el cierre sólo trae los .a)" + for n in $recetas; do + hash=$(./target/release/hammer --store store hash "recipes/$n.toml" 2>/dev/null | tail -1 | sed 's/^b3://') + dir="store/$hash-$n" + if [ -n "$hash" ] && [ -d "$dir" ]; then + cp -a --remove-destination "$dir"/usr/lib/*.so* "$merged"/usr/lib/ 2>/dev/null || true + echo " ✓ $n $(echo "$hash" | cut -c1-12)" + else + echo " ✗ falta $n sellado en store/ — el escritorio morirá con 'symbol not found'" >&2 + return 1 + fi + done +}