kde/mesa: cadena llvmpipe soberana — LLVM18+mesa-llvmpipe from source, GBM cruzado
mesa-llvmpipe con gcc/libstdc++ (matchea el ABI de libLLVM; zig-cc usaba libc++ ⇒ undefined symbols en el JIT). qemu-desktop-image inyecta libLLVM.18+libgcc_s+libstdc++. HITO: kwin toma DRM master de virtio-gpu, crea el GBM device (llvmpipe, ya no softpipe), expone compositor y ACEPTA clientes. Muro restante: kwin segfaultea (139) al componer la 1ra superficie con llvmpipe — necesita backtrace (gdb) para diagnosticar. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,10 +36,15 @@ export GALLIUM_DRIVER=llvmpipe
|
||||
export MESA_LOADER_DRIVER_OVERRIDE=kms_swrast
|
||||
export LIBGL_DRIVERS_PATH=/usr/lib/dri
|
||||
export QT_QUICK_BACKEND=software
|
||||
# KWIN_COMPOSE=Q ⇒ compositor QPainter (software puro, SIN OpenGL/EGL): antes kwin exponía wayland-0 y
|
||||
# MORÍA al montar la salida GL sobre softpipe/virtio (EGL de software inestable ⇒ pantalla negra). El
|
||||
# backend QPainter pinta con CPU directo al framebuffer DRM, sin contexto GL — el camino para VM sin GPU.
|
||||
export KWIN_COMPOSE=Q
|
||||
# LP_NUM_THREADS=1: llvmpipe SINCRÓNICO (sin pool de threads del rasterizador) — el JIT multi-thread de
|
||||
# llvmpipe segfaultea al componer la 1ra superficie en esta VM. KWIN_DRM_NO_AMS=1: desactiva atomic
|
||||
# modesetting (algunos virtio-gpu lo rompen). Ambos son fixes conocidos de kwin/llvmpipe en VMs.
|
||||
export LP_NUM_THREADS=1
|
||||
export KWIN_DRM_NO_AMS=1
|
||||
# KWIN_COMPOSE: con llvmpipe (GL de software COMPLETO) dejamos que kwin use su compositor OpenGL por
|
||||
# defecto — forzar QPainter (=Q) sobre una salida DRM/EGL con GL disponible segfaultea al componer la
|
||||
# 1ra superficie. Si el GL-llvmpipe resultara inestable, KWIN_COMPOSE=Q es el fallback.
|
||||
# export KWIN_COMPOSE=Q
|
||||
export QT_QPA_PLATFORM=wayland
|
||||
export QT_QPA_PLATFORMTHEME=kde
|
||||
export QT_QPA_FONTDIR=/usr/share/fonts/dejavu
|
||||
|
||||
@@ -17,28 +17,47 @@ ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
||||
|
||||
BASE="${BASE:-work/metal-rootfs}"
|
||||
KDE="${KDE:-work/kde-metal-rootfs}"
|
||||
SWRAST="${SWRAST:-$(ls -dt store/*-mesa-swrast 2>/dev/null | head -1)}"
|
||||
# mesa-llvmpipe (GBM/EGL completo, lo que kwin exige) si está sellado; si no, cae a mesa-swrast (softpipe).
|
||||
MESA="${MESA:-$(ls -dt store/*-mesa-llvmpipe 2>/dev/null | head -1)}"
|
||||
[ -n "$MESA" ] && [ -d "$MESA" ] || MESA="$(ls -dt store/*-mesa-swrast 2>/dev/null | head -1)"
|
||||
LLVM="${LLVM:-$(ls -dt store/*-llvm18 2>/dev/null | head -1)}"
|
||||
MERGED="${MERGED:-work/qemu-desktop-rootfs}"
|
||||
IMG="${IMG:-work/hammer-kde-qemu.img}"
|
||||
|
||||
[ -d "$BASE" ] || { echo "falta $BASE" >&2; exit 1; }
|
||||
[ -d "$KDE" ] || { echo "falta $KDE" >&2; exit 1; }
|
||||
[ -n "$SWRAST" ] && [ -d "$SWRAST" ] || { echo "falta artefacto mesa-swrast en store/" >&2; exit 1; }
|
||||
[ -n "$MESA" ] && [ -d "$MESA" ] || { echo "falta artefacto mesa-llvmpipe/mesa-swrast en store/" >&2; exit 1; }
|
||||
case "$MESA" in *mesa-llvmpipe) LLVMPIPE=1;; *) LLVMPIPE=0;; esac
|
||||
|
||||
echo "==> fundiendo rootfs por hardlinks (base + KDE)"
|
||||
rm -rf "$MERGED"
|
||||
cp -al "$BASE" "$MERGED"
|
||||
cp -al --remove-destination "$KDE"/. "$MERGED"/
|
||||
|
||||
echo "==> parcheando swrast (software GL) desde $SWRAST"
|
||||
echo "==> parcheando mesa (software GL) desde $MESA (llvmpipe=$LLVMPIPE)"
|
||||
# el artefacto trae usr/lib/{dri/*swrast*,libEGL,libgbm,libglapi,libGLESv2}; copiamos SIN --remove para
|
||||
# no pisar sonames del metal salvo lo que falte, pero swrast_dri debe entrar sí o sí.
|
||||
cp -a "$SWRAST"/usr/lib/dri/. "$MERGED"/usr/lib/dri/ 2>/dev/null || true
|
||||
for so in libglapi libgbm libEGL libGLESv2; do
|
||||
cp -a "$SWRAST"/usr/lib/$so* "$MERGED"/usr/lib/ 2>/dev/null || true
|
||||
cp -a "$MESA"/usr/lib/dri/. "$MERGED"/usr/lib/dri/ 2>/dev/null || true
|
||||
for so in libglapi libgbm libEGL libGLESv2 libgallium; do
|
||||
cp -a "$MESA"/usr/lib/$so* "$MERGED"/usr/lib/ 2>/dev/null || true
|
||||
done
|
||||
ls "$MERGED"/usr/lib/dri/*swrast* >/dev/null 2>&1 && echo " ✓ swrast_dri instalado" || { echo " ✗ swrast no entró" >&2; exit 1; }
|
||||
|
||||
if [ "$LLVMPIPE" = 1 ]; then
|
||||
echo "==> inyectando libLLVM.18 + libgcc_s (llvmpipe JIT-linkea libLLVM; ésta NEEDea libgcc_s)"
|
||||
[ -n "$LLVM" ] && [ -d "$LLVM" ] || { echo " ✗ falta artefacto llvm18 en store/ (set LLVM=)" >&2; exit 1; }
|
||||
cp -a "$LLVM"/usr/lib/libLLVM.so.18.1 "$MERGED"/usr/lib/
|
||||
ln -sf libLLVM.so.18.1 "$MERGED"/usr/lib/libLLVM.so.18
|
||||
ln -sf libLLVM.so.18.1 "$MERGED"/usr/lib/libLLVM.so
|
||||
# libgcc_s del sandbox (libLLVM.so lo NEEDea; el -static-libgcc no aplica full a un DYLIB)
|
||||
GCCS="${GCCS:-.dev-fs/alpine/usr/lib/libgcc_s.so.1}"
|
||||
[ -r "$GCCS" ] && cp -a "$GCCS" "$MERGED"/usr/lib/libgcc_s.so.1 || echo " ⚠ sin libgcc_s ($GCCS)"
|
||||
# mesa-llvmpipe se construye con gcc/libstdc++ (para matchear el ABI de libLLVM) ⇒ NEEDea libstdc++.so.6
|
||||
STDCXX="${STDCXX:-.dev-fs/alpine/usr/lib/libstdc++.so.6}"
|
||||
[ -r "$STDCXX" ] && cp -a "$STDCXX"* "$MERGED"/usr/lib/ 2>/dev/null || echo " ⚠ sin libstdc++ ($STDCXX)"
|
||||
echo " ✓ libLLVM.18 ($(du -h "$MERGED"/usr/lib/libLLVM.so.18.1 | cut -f1)) + libgcc_s + libstdc++ inyectados"
|
||||
fi
|
||||
|
||||
echo "==> inyectando musl (loader + libc) — los binarios KDE son dinámicos"
|
||||
# La base metal es 100% ESTÁTICA (arje-zero+busybox) y el KDE-rootfs no trae libc ⇒ el merge no tiene
|
||||
# loader musl. Los binarios KDE piden interp /lib/ld-musl-x86_64.so.1 + NEEDED libc.so (única lib base
|
||||
|
||||
Reference in New Issue
Block a user