#!/usr/bin/env bash # hydrate-fhs.sh — hidrata un FHS runtime KDE desde el repo firmado, instalando el CIERRE completo. # # `takana install --prefix P` sólo hidrata los archivos de , NO de su cierre. Para un # rootfs runtime usable (que capture todas las `.so`), hay que instalar cada paquete del cierre en el # MISMO prefix (igual que product-userland-from-repo.sh). El store del worker está caliente ⇒ cache-hit. # # Las recetas de LIBS KDE declaran `target_bin=/usr/bin/` que no existe (son libs, no binarios): # `install` hidrata los ficheros y LUEGO falla la aserción con exit 1. Lo toleramos: contamos éxito si # el paquete dejó ficheros en el prefix. # # Uso: TARGET=qt6-qtdeclarative ./hydrate-fhs.sh (default) set -uo pipefail ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT" REPO="${REPO:-work/repo-kde}"; TRUST="${TRUST:-dist/keys}"; STORE="${STORE:-./store}" RFS="${RFS:-work/kde-rootfs}" # TARGETS = uno o varios paquetes tope (unión de cierres). TARGET (singular) sigue soportado. TARGETS="${TARGETS:-${TARGET:-qt6-qtdeclarative}}" HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}" DB="$RFS/var/lib/hammer/installed.json" # cierre transitivo de TODOS los targets, leído del índice (deps + aliases ya resuelven). Excluimos # herramientas puramente de build (no aportan runtime) para acelerar; si algo falta lo delata ldd. CLOSURE=$(python3 - "$REPO/index.json" $TARGETS <<'PY' import json,sys idx=json.load(open(sys.argv[1])); targets=sys.argv[2:] by={p['name']:p for p in idx['packages']} BUILD_ONLY={'cmake','samurai','meson','ninja','bison','flex','gperf','util-macros','xorgproto', 'xcb-proto','wayland-protocols','pkgconf','mako','markupsafe','packaging','python3','extra-cmake-modules', 'qttools','qt6-qttools','intltool','perl','perl-xml-parser','gettext-tiny','m4','autoconf','automake', 'libtool','util-macros'} # PREFERIR el nombre real qt6-* sobre el alias qt-corto: install nombra el artefacto por la clave del # índice, y sólo `-qt6-qtdeclarative` está sellado (no `-qtdeclarative`) ⇒ instalar el alias # fuerza cache-miss+rebuild. El alias existe sólo para resolver deps DENTRO del .swm, no para instalar. def canon(n): if n.startswith('qt') and not n.startswith('qt6-') and ('qt6-'+n) in by: return 'qt6-'+n return n if n in by else ('qt6-'+n if 'qt6-'+n in by else n) seen=set(); order=[] def visit(n): n=canon(n) if n in seen or n not in by: return seen.add(n) for d in by[n].get('deps',[]): visit(d) order.append(n) for t in targets: visit(t) for n in order: if n not in BUILD_ONLY: print(n) PY ) mkdir -p "$(dirname "$DB")" echo "==> hidratando cierre runtime de [$TARGETS] → $RFS ($(echo "$CLOSURE"|wc -w) pkgs)" ok=0; fail=0 for pkg in $CLOSURE; do before=$(find "$RFS" -type f 2>/dev/null | wc -l) NO_PROXY=localhost NIX_STORE="${NIX_STORE:-$HOME/.nixstore}" \ "$HAMMER" --store "$STORE" install "$pkg" --repo "$REPO" --prefix "$RFS" \ --trust "$TRUST" --require-signed --db "$DB" >"$RFS/.h-$pkg.log" 2>&1 rc=$? after=$(find "$RFS" -type f 2>/dev/null | wc -l) if [ "$after" -gt "$before" ] || grep -q "hidratados" "$RFS/.h-$pkg.log"; then printf " ✓ %-22s (+%s ficheros%s)\n" "$pkg" "$((after-before))" \ "$([ $rc -ne 0 ] && echo ', target_bin tolerado')" ok=$((ok+1)) else printf " ✗ %-22s rc=%s (ver %s)\n" "$pkg" "$rc" "$RFS/.h-$pkg.log"; fail=$((fail+1)) fi done echo "==> $ok hidratados, $fail fallaron; .so totales: $(find "$RFS" -name '*.so*'|wc -l)"