diff --git a/recipes/incoming-kde/zlib-shared.toml b/recipes/incoming-kde/zlib-shared.toml new file mode 100644 index 00000000..45106ccb --- /dev/null +++ b/recipes/incoming-kde/zlib-shared.toml @@ -0,0 +1,30 @@ +# zlib-shared 1.3.1 — variante DINÁMICA de zlib para el escritorio KDE. +# +# El zlib canónico (recipes/zlib.toml) es `--static` (sólo libz.a, para el toolchain rust/mrustc). Pero +# el stack GUI dinámico (Qt/KDE/libpng/Mesa) linkea `libz.so.1` por SONAME en runtime, y ese `.so` no lo +# provee ningún artefacto sellado ⇒ el rootfs hidratado caía a la libz.so.1 del sysroot Alpine (fuga de +# soberanía, deuda static↔dinámico de Capa 0). Esta variante sella el `libz.so.1` soberano: los `.so` de +# KDE ya tienen NEEDED libz.so.1 (mismo soname), así que basta hidratar este artefacto — sin rebuild de KDE. +# +# Build shared: el configure a mano de zlib genera libz.so.1.3.1 + symlinks libz.so.1/libz.so por defecto +# (sin --static). -fPIC/-O2/-fno-sanitize=undefined igual que la canónica (evita el runtime UBSan de zig). + +name = "zlib-shared" +version = "1.3.1" + +[source] +tarball = "https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz" +sha256 = "9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "dynamic" + +# zlib configure a-mano no construye el .so con el CC multi-palabra de zig ⇒ fabricamos libz.so.1 del +# libz.a PIC con --whole-archive (truco documentado de Capa 0). El soname libz.so.1 es el que NEEDED todo +# el stack KDE. Symlinks libz.so.1→.1.3.1 y libz.so→.1 para el loader y el linker. +[build.phases] +configure = "CFLAGS='-fPIC -O2 -fno-sanitize=undefined' ./configure --prefix=/usr --static" +compile = "make -j\"$(nproc)\" && ${CC:-zig cc} -shared -Wl,-soname,libz.so.1 -Wl,--whole-archive libz.a -Wl,--no-whole-archive -o libz.so.1.3.1" +install = "make install DESTDIR=/out && install -Dm755 libz.so.1.3.1 /out/usr/lib/libz.so.1.3.1 && ln -sf libz.so.1.3.1 /out/usr/lib/libz.so.1 && ln -sf libz.so.1 /out/usr/lib/libz.so" diff --git a/scripts/kde/complete-closure.sh b/scripts/kde/complete-closure.sh new file mode 100644 index 00000000..572f386e --- /dev/null +++ b/scripts/kde/complete-closure.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# complete-closure.sh — completa el cierre RUNTIME de un FHS hidratado: escanea los `NEEDED` (DT_NEEDED) +# de cada ELF del rootfs y, por cada soname AUSENTE, proyecta del store SELLADO el artefacto que lo +# provee (`hammer hydrate`). Itera hasta punto fijo. Resuelve las deps runtime que el índice del repo NO +# lista (p.ej. libmount.so.1 de util-linux, dep de build de kcoreaddons pero .so runtime de libKF6CoreAddons). +# +# Sonames del SUSTRATO base (musl libc, loader, libgcc) NO se hidratan: los provee la base soberana del +# sistema destino. El resto se toma del store (mtime artefacto (hash) del store, sólo mtime indexando sonames del store (mtime<$(date -d @$CUTOFF 2>/dev/null||echo $CUTOFF))…" +declare -A PROV +while IFS= read -r d; do + hash="${d##*/}"; hash="${hash%%-*}" + while IFS= read -r so; do + b="${so##*/}" + [ -z "${PROV[$b]:-}" ] && PROV[$b]="$hash" + done < <(find "$d" -name "*.so*" -printf '%f\n' 2>/dev/null) +done < <(find "$STORE" -maxdepth 1 -type d -name "*-*" -printf '%T@ %p\n' 2>/dev/null | awk -v c="$CUTOFF" '$1/dev/null) + # NEEDED de todos los ELF del rootfs + declare -A NEED=() + while IFS= read -r bin; do + while IFS= read -r n; do NEED["$n"]=1; done < <(readelf -d "$bin" 2>/dev/null | grep NEEDED | grep -oE '\[[^]]+\]' | tr -d '[]') + done < <(find "$RFS" -type f \( -name "*.so*" -o -path "*/bin/*" -o -path "*/libexec/*" \) 2>/dev/null) + # faltantes + missing=(); for n in "${!NEED[@]}"; do + [ -n "${HAVE[$n]:-}" ] && continue + is_base "$n" && continue + missing+=("$n") + done + if [ ${#missing[@]} -eq 0 ]; then echo "==> ronda $round: cierre COMPLETO, 0 sonames faltantes"; break; fi + echo "==> ronda $round: ${#missing[@]} sonames faltantes" + did=0; declare -A HYDRATED=() + for n in "${missing[@]}"; do + h="${PROV[$n]:-}" + if [ -z "$h" ]; then printf " ? %-32s (ningún artefacto lo provee)\n" "$n"; continue; fi + [ -n "${HYDRATED[$h]:-}" ] && continue + if "$HAMMER" --store "$STORE" hydrate "$h" --into "$RFS" --link "$LINK" >/dev/null 2>&1; then + printf " + %-32s ← %s\n" "$n" "${h:0:12}"; HYDRATED[$h]=1; did=$((did+1)) + else + printf " ✗ %-32s hydrate falló (%s)\n" "$n" "${h:0:12}" + fi + done + unset HAVE NEED + [ $did -eq 0 ] && { echo "==> ronda $round: nada nuevo hidratado (faltantes irresolubles), corto"; break; } +done +echo "==> .so totales: $(find "$RFS" -name '*.so*'|wc -l); binarios: $(find "$RFS" -path '*/bin/*' -type f|wc -l)"