Files
takana/docs/14-mesa-stack.md
T
sergioandClaude Opus 4.8 6fb7fd36d0 Etapa G: wayland + wayland-protocols CONSTRUIDAS (scanner desbloqueado)
Root cause real del bloqueo de wayland: NO era bug del wayland-scanner ni del XML
(ambos verificados OK). En el sandbox el scanner in-tree se compila ENLAZADO DINÁMICO
contra la musl (zig cc nativo no produce estático acá), y bajo musl-dinámico
`freopen(@OUTPUT@,"w",stdout)` queda roto por la copy-relocation de `stdout`: trunca el
archivo de salida pero manda el header generado a stdout → @OUTPUT@ vacío → `WL_SHM_FORMAT_*`
/ `wl_*` «undeclared» al compilar libwayland.

Fix: wayland-scanner-dup2-output.patch redirige la salida con `dup2(fd, STDOUT_FILENO)`
(nivel descriptor) en vez de `freopen` → robusto al modo de enlace. Verificado byte-a-byte:
salida idéntica a la del scanner estático (217484 B al archivo).

Segundo blocker (libwayland-server.so): libffi.a era no-PIC → `R_X86_64_PC32 ... recompile
with -fPIC` al ligarlo dentro de una .so. libffi ahora con --with-pic (superset; sigue
sirviendo para enlace estático). Mesa necesitará lo mismo en zlib/zstd/expat.

Restaura recipes/samurai.toml (lo necesita el stack adaptado de recipes/: libdrm/seatd/
wayland; las otras build-deps —meson/pkgconf/python3/expat/libffi— ya viven en recipes/).

Sellados: wayland (libwayland-{client,server,cursor,egl}.so + scanner + .pc),
wayland-protocols (XML + .pc). Queda mesa (iris-only).

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

95 lines
6.4 KiB
Markdown

# 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)
El target inmediato es una laptop **Intel Iris Xe**. 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` | sí | 🟡 incoming | 2.4.134; **fijar `-Dgallium`? no** — libdrm es agnóstico; `link=dynamic` |
| lib | `wayland` | sí | 🟡 incoming | 1.25.0; deps expat+libffi; `-Ddocumentation=false` |
| lib | `wayland-protocols` | sí | 🟡 incoming | 1.48; sólo datos (XML) + meson; dep wayland |
| lib | `seatd` (→`libseat`) | sí | 🟡 incoming | la sesión de mirada abre el DRM vía libseat |
| **top** | `mesa` | sí | 🟡 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`+`samurai``libdrm`,`wayland``wayland-protocols`,`seatd``mesa`.
## 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) |
| `mesa` | 🟡 **pendiente** | recortar a iris-only (sin LLVM/Vulkan/X11); depende de libdrm✓+wayland✓+wayland-protocols✓+expat✓+zlib✓+zstd✓+python3✓+mako(⚪). Anticipá PIC en zlib/zstd/expat (como libffi) al ligar las `.so` de Mesa. |
meson anda con zig cc (clang 21) sobre proyectos meson — validado con libdrm/seatd/wayland. El cuello
real restante es **mesa** (recorte iris-only + PIC de sus deps C estáticas).
## 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/lib/arje/mirada-greeter-llimphi` | **dynamic** | EGL/GLES/GBM (mesa) + wayland + libseat |
`mirada-greeter` es el único que enlaza Mesa dinámico ⇒ **bloqueado por el tier `mesa`**.
Los otros dos pueden construirse e instalarse ya (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.