Files
hammer/docs/14-mesa-stack.md
sergioandClaude Opus 4.8 673bdde69f Etapa G: mirada-compositor CONSTRUIDO — stack de sesión gráfica COMPLETO
mirada-compositor sellado (store/d8fd9ca…): el compositor Wayland teselante sobre smithay 0.7,
que maneja DRM/GBM/EGL/libseat/libinput directo y hospeda a mirada-greeter como cliente.
Compila ~255 crates incl. smithay para musl; PIE dinámico.

Cierra la cadena de sesión gráfica de tawasuyu sobre hammer: Mesa(iris) + wayland + stack de
entrada + compositor + greeter, todo sellado.

smithay (default features) enlaza por -sys: drm-sys→libdrm, gbm-sys→mesa, libseat-sys→seatd,
input-sys→libinput, libudev-sys→libudev-zero, + xkbcommon→libxkbcommon y pixman (link directo).
Dos libs nuevas para cerrar el link:
- libxkbcommon 1.7.0 (meson, sin x11/wayland/docs/tools): smithay la enlaza, no sólo dlopen.
- pixman 0.44.2 (meson, sin tests/demos): composición CPU de smithay.

foreign-av NO enlaza ffmpeg (spawnea el binario en runtime) ⇒ no hizo falta construir ffmpeg.
NEEDED del binario: libgbm/libseat/libudev/libinput/libpixman-1/libxkbcommon + musl (libdrm/EGL/
wayland se dlopen-ean).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 07:06:41 -04:00

10 KiB

SDD 14 — Stack gráfico (Mesa iris) para el escritorio tawasuyu

Estado: cola importada (2026-06-27). Contraparte en hammer del salto demo→producción de arje: el rootfs de producto necesita Mesa para que el greeter real de mirada (mirada-greeter-llimphi) tome el DRM tras el handoff del splash. Seed de producción: tawasuyu/03_ukupacha/arje/seeds/arje-tawasuyu.card.json (ente display-manager-mesa). Ver su contrato rootfs en seeds/README.md.

Por qué iris-only (sin LLVM, sin Vulkan) — y por qué Mesa 24.0.9

Pin de versión (2026-06-27): «iris sin LLVM» SÓLO vale hasta Mesa 24.0.x. Desde 24.1 el driver iris pasó a requerir intel-clc (kernels OpenCL-C internos compilados en build-time) ⇒ with_clc ⇒ libclc + clang/LLVM. Bisección confirmada: 24.0.9 = último con with_intel_clc = intel-clc=='enabled' (default disabled) ⇒ con iris-only y sin Vulkan/rusticl, with_clc=FALSE, nada de LLVM. Por eso la receta pinea 24.0.9 (no la 26.1.1 importada de Alpine). Para Mesa ≥24.1 habría que construir LLVM+clang+libclc primero — otra rama del track.

El target inmediato es una laptop Intel Iris Xe. En Mesa ≤24.0 el driver gallium iris NO necesita LLVM (eso es radeonsi/llvmpipe). Recortando el build de Alpine (que trae el kitchen-sink) a iris-only se elimina la cola pesada — clang, llvm, libclc, spirv-llvm-translator, rust-bindgen, Vulkan, X11/glx:

-Dgallium-drivers=iris   -Dvulkan-drivers=   -Dllvm=disabled
-Dplatforms=wayland      -Dglx=disabled      -Dexpat=enabled

Eso deja un Mesa que sólo arrastra deps que hammer ya tiene o son chicas. (Para AMD/NVIDIA-nouveau más adelante: radeonsi/nouveau sí piden LLVM → otra rama del track.)

DAG de dependencias (estado contra el corpus actual)

Tier Receta meson? Estado en hammer Notas
build python3 🟢 en store meson/mako lo usan
build meson 🟡 incoming importada de Alpine 1.11.1; pyproject, necesita python3
build samurai (≡ninja) 🟡 incoming 1.3, clon C de ninja (lo que usa Alpine)
build pkgconf 🟢 receta sustituto de pkg-config
build bison / flex 🟢 receta mesa genera parsers
build mako (módulo py) por verificar templating de codegen de mesa; pip/source sobre python3
lib expat zlib zstd libffi 🟢 receta deps de wayland/mesa
lib libdrm 🟡 incoming 2.4.134; fijar -Dgallium? no — libdrm es agnóstico; link=dynamic
lib wayland 🟡 incoming 1.25.0; deps expat+libffi; -Ddocumentation=false
lib wayland-protocols 🟡 incoming 1.48; sólo datos (XML) + meson; dep wayland
lib seatd (→libseat) 🟡 incoming la sesión de mirada abre el DRM vía libseat
top mesa 🟡 incoming 26.1.1; recortar a iris-only (arriba); deps: libdrm, wayland, wayland-protocols, expat, zlib, zstd, python3+mako

🟢 listo · 🟡 importada, falta adaptar (traducir abuild-meson/_abuild_phase de Alpine a fases hammer + meson/samurai directos, como hizo elfutils) · por crear.

Trabajo de adaptación por receta (lo real)

Las recetas en recipes/incoming/ son puntos de partida de import-alpine: traen los parches musl de Alpine (lo valioso) pero usan los helpers de abuild que el lab de hammer no tiene. Cada una necesita, mínimo:

  1. Reemplazar abuild-meson por meson setup output --prefix=/usr --buildtype=release <-Dflags> y _abuild_phase/DESTDIR=/out por las fases configure/compile/install de hammer.
  2. compiler = "zig-cc", target = "x86_64-linux-musl", link = "dynamic" (son libs compartidas).
  3. Declarar las deps de build en el grafo de hammer (no como makedepends de Alpine).
  4. Verificar zig_version si zig 0.14 miscompila (patrón de elfutils/binutils/flex: fijar 0.13.0).

Orden de build (hojas→raíz): meson+samurailibdrm,waylandwayland-protocols,seatdmesa.

Estado de build (2026-06-27)

Construidas y selladas en el store (hammer --store store build recipes/<x>.toml):

Receta Estado Nota de adaptación
samurai 🟢 built zig_version=0.13.0 (el default miscompila → reallocarray falla en runtime)
meson 🟢 built Python puro: copia mesonbuild/+wrapper, sin wheel/gpep517; python3 runtime-dep
libdrm 🟢 built core-only (todas las GPU helper disabled) → evita libpciaccess; iris usa libdrm core
seatd 🟢 built -Dwerror=false (musl CMSG_NXTHDR dispara -Wsign-compare); logind disabled, backend seatd
libffi 🟢 built --with-pic: el .a lleva objetos PIC ⇒ enlazable dentro de .so (lo exige libwayland-server/Mesa; sin PIC: R_X86_64_PC32 ... recompile with -fPIC)
wayland 🟢 built link=dynamic (Mesa liga las .so). Root cause del bloqueo RESUELTO (2026-06-27): los headers de protocolo salían vacíos NO por bug del scanner ni del XML, sino porque el wayland-scanner in-tree se compila enlazado dinámico contra la musl (zig cc nativo no hace estático acá) y bajo musl-dinámico freopen(@OUTPUT@,"w",stdout) queda roto por la copy-relocation de stdout → trunca el archivo y manda el header a stdout. FIX: wayland-scanner-dup2-output.patch redirige con dup2(fd, STDOUT_FILENO) (nivel descriptor) en vez de freopen. Verificado byte-a-byte: salida idéntica a la del scanner estático (217484 B).
wayland-protocols 🟢 built sólo instala XML + .pc; build-dep wayland (su meson chequea wayland-scanner)
markupsafe mako packaging 🟢 built módulos Python puros (copia a site-packages, sin pip/wheel). mako=codegen de Mesa; markupsafe=dep de mako (cae a _native); packaging porque el chequeo de versión de mako usa packaging.version y Python 3.12 ya no trae distutils
zlib zstd expat 🟢 built (PIC) -fPIC/--with-pic para enlace dentro de .so (como libffi). Mesa al final ligó libz/libzstd compartidas de la base Alpine; libexpat.a (PIC) sí se enlazó estática
mesa 🟢 built iris-only, Mesa 24.0.9 (no 26.1: desde 24.1 iris exige intel-clc→LLVM; ver arriba). -Dllvm=disabled -Dintel-clc=disabled, sin Vulkan/glx/rusticl/codecs. Instala dri/iris_dri.so + libEGL/libgbm/libGLESv2/libglapi + egl/gbm/glesv2 .pc. Fixes: PYTHONPATH al site-packages (configure+compile) para mako; libffi en deps (lo pide wayland-client.pc); mesa-version-script-comma.patch (version-script en forma coma, que zig cc no reordena). Runtime: el rootfs necesita libz.so.1/libzstd.so.1/libexpat(o estático) + libdrm/wayland

meson anda con zig cc (clang 21) sobre proyectos meson — validado con libdrm/seatd/wayland/mesa. El stack gráfico está COMPLETO. Lo que falta es el lado tawasuyu (mirada-greeter dinámico contra Mesa) y el ensamblado del rootfs de producto con las .so compartidas (libz/libzstd/libdrm/wayland/mesa).

Lado tawasuyu (recetas Cargo, después de Mesa)

Modeladas sobre recipes/arje-zero.toml (fuente = monorepo tawasuyu a commit fijado, build hermético):

Receta bin link dep gráfica
arje-splash /usr/lib/arje/arje-splash static-musl sólo DRM dumb-buffer (sin Mesa)
net-bring-up /usr/lib/arje/net-bring-up static-musl ninguna
mirada-greeter /usr/bin/mirada-greeter dynamic 🟢 built dlopen: EGL/GLES/GBM (mesa) + wayland; link: libpam
mirada-compositor /usr/bin/mirada-compositor dynamic 🟢 built link: gbm/seat/udev/input/pixman/xkbcommon; dlopen: EGL/wayland/drm

mirada-greeter 🟢 CONSTRUIDO Y SELLADO (Cargo, 314 crates incl. todo el stack wgpu/winit/llimphi para musl; PIE dinámico). DT_NEEDED real = sólo libpam.so.0 + musl; EGL/GLES/GBM/wayland/iris se dlopen-ean en runtime (wgpu/winit) ⇒ el rootfs debe TENERLAS presentes pero no son NEEDED. Fixes de la receta:

  • atspi/accesskit (a11y, vía accesskit_winit): zbus-lockstep-macros #[validate] PANICA («File has no extension.») porque escanea xml/ de atspi-common y hace .extension().expect() en el SUBDIR xml/schemas/ (zbus-lockstep-macros/src/lib.rs:147). Fix = fase compile custom que apunta LOCKSTEP_XML_PATH a un dir con sólo los .xml. (Más limpio a futuro: hacer accesskit OPCIONAL en llimphi-ui — el greeter no necesita a11y.)
  • PAM: auth-core → pam/pam-sys hace bindgen sobre security/pam_appl.h ⇒ nueva receta linux-pam 1.6.1 (libpam.so + headers, build limpio en musl con gcc de Alpine).

mirada-compositor 🟢 CONSTRUIDO Y SELLADO (Cargo, ~255 crates incl. smithay 0.7 para musl; PIE dinámico). Es el compositor que maneja DRM/GBM/EGL/libseat/libinput directo y dentro del cual corre mirada-greeter como cliente. smithay (default features) enlaza drm-sys→libdrm, gbm-sys→mesa, libseat-sys→seatd, input-sys→libinput, libudev-syslibudev-zero (libudev sin udevd, encaja con el no-systemd de arje), + xkbcommonlibxkbcommon y pixman (link, no dlopen). Por eso el stack de entrada nuevo: libinput + libevdev + mtdev (config.sub viejo parcheado al moderno) + libudev-zero + libxkbcommon + pixman. foreign-av NO enlaza ffmpeg (spawnea el binario en runtime) ⇒ no hizo falta construir ffmpeg. NEEDED del binario: libgbm/libseat/libudev/libinput/ libpixman-1/libxkbcommon + musl.

El stack de sesión gráfica está COMPLETO: Mesa(iris) + wayland + el stack de entrada + mirada-compositor + mirada-greeter, todo sellado. Falta el ensamblado del rootfs (todas las .so + config/módulos PAM + datos xkb de xkeyboard-config) y arrancar la sesión.

Los otros dos (arje-splash, net-bring-up) no dependen de Mesa.

Hecho cuando

hammer bootstrap product produce un rootfs que, con la seed arje-tawasuyu, arranca arje-zero → splash → mirada-greeter toma el DRM con Mesa/iris, sin caer a texto. Verificación: boot en QEMU (con virgl/GPU) o metal en la laptop Iris Xe.