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>
This commit is contained in:
2026-06-27 00:52:16 -04:00
co-authored by Claude Opus 4.8
parent 5126a8b679
commit 6fb7fd36d0
5 changed files with 87 additions and 19 deletions
+6 -5
View File
@@ -66,12 +66,13 @@ Construidas y selladas en el store (`hammer --store store build recipes/<x>.toml
| `meson` | 🟢 **built** | Python puro: copia `mesonbuild/`+wrapper, sin wheel/gpep517; `python3` runtime-dep | | `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 | | `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 | | `seatd` | 🟢 **built** | `-Dwerror=false` (musl `CMSG_NXTHDR` dispara `-Wsign-compare`); logind disabled, backend seatd |
| `wayland` | 🔴 **bloqueada — root cause confirmado** | `wayland-scanner` genera headers de protocolo **vacíos**`WL_SHM_FORMAT_*`/`wl_*` undeclared. **Confirmado (2026-06-27):** la fuente extraída `work/sources/wayland-*/protocol/wayland.xml` está COMPLETA (165075 B), expat OK, no es ordenamiento de samurai (`-j1` falla igual). El scanner recibe el XML completo pero **emite vacío, sale 0** (por stdin expat: «no element found» = lee 0 bytes). ⇒ **bug de runtime del wayland-scanner compilado static-musl** (falla con zig default Y 0.13.0). **FIX:** el scanner es herramienta de build-time (no se shippea) ⇒ construirlo **nativo (host/glibc)** y apuntar libwayland al scanner externo; construir sólo libwayland-{client,server} con musl/zig. Alt: patchear la lectura de input del scanner para musl. | | `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-protocols` | ⏸ **bloqueada** | build-depende de wayland (necesita wayland-scanner) | | `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). |
| `mesa` | 🟡 **pendiente** | recortar a iris-only (sin LLVM/Vulkan/X11); depende de libdrm✓+wayland+wayland-protocols+expat✓+zlib✓+zstd✓+python3✓+mako(⚪) | | `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 y seatd. El cuello real meson anda con zig cc (clang 21) sobre proyectos meson — validado con libdrm/seatd/wayland. El cuello
restante es **wayland** (scanner) y luego **mesa**. real restante es **mesa** (recorte iris-only + PIC de sus deps C estáticas).
## Lado tawasuyu (recetas Cargo, después de Mesa) ## Lado tawasuyu (recetas Cargo, después de Mesa)
+4 -1
View File
@@ -1,5 +1,8 @@
# libffi 3.5.2 — interfaz de llamada a función foránea (C). Lib base: python, muchos -sys crates. # libffi 3.5.2 — interfaz de llamada a función foránea (C). Lib base: python, muchos -sys crates.
# De-Alpinizada: compiler=gcc, configure-split, estático. # De-Alpinizada: compiler=gcc, configure-split, estático.
# --with-pic: el .a estático lleva objetos PIC ⇒ se puede enlazar dentro de bibliotecas COMPARTIDAS
# (libwayland-server.so / Mesa lo exigen; sin PIC: «R_X86_64_PC32 ... recompile with -fPIC»). PIC
# es superset: sigue sirviendo para el enlace estático de exes. (2026-06-27, stack gráfico tawasuyu.)
name = "libffi" name = "libffi"
version = "3.5.2" version = "3.5.2"
[source] [source]
@@ -11,6 +14,6 @@ target = "x86_64-linux-musl"
link = "static" link = "static"
flags = [] flags = []
[build.phases] [build.phases]
configure = './configure --build=$CBUILD --host=$CHOST --prefix=/usr --disable-shared --enable-static --disable-exec-static-tramp' configure = './configure --build=$CBUILD --host=$CHOST --prefix=/usr --disable-shared --enable-static --with-pic --disable-exec-static-tramp'
compile = 'make' compile = 'make'
install = 'make DESTDIR=/out install' install = 'make DESTDIR=/out install'
+24
View File
@@ -0,0 +1,24 @@
# samurai 1.3 — clon C de ninja (lo que usa Alpine como `ninja`). Build-tool del stack meson
# (libdrm/wayland/mesa lo invocan como backend). Provee /usr/bin/samu + symlink /usr/bin/ninja.
# zig 0.13.0: con el zig default (0.16/clang21) el binario musl miscompila y falla en runtime
# con "reallocarray: No error information" — el patrón conocido (binutils/elfutils/flex).
name = "samurai"
version = "1.3"
[source]
tarball = "https://github.com/michaelforney/samurai/releases/download/1.3/samurai-1.3.tar.gz"
sha256 = "1bc020a9e133432df51911ac71cc34322f828934d9a2282ba2916d88c15976af"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "static"
zig_version = "0.13.0"
[build.phases]
compile = 'make CFLAGS="-O2"'
install = '''
set -e
make install PREFIX="/usr" DESTDIR="/out"
ln -s samu /out/usr/bin/ninja
'''
+42
View File
@@ -0,0 +1,42 @@
Redirige la salida del scanner al @OUTPUT@ a nivel de descriptor (dup2) en vez de freopen(stdout).
En hammer el wayland-scanner se compila ENLAZADO DINÁMICO contra la musl del sandbox (zig cc
nativo no produce estático aquí), y bajo musl-dinámico `freopen(argv[2], "w", stdout)` queda roto
por la copy-relocation de `stdout`: trunca/crea el archivo de salida PERO no redirige el fd que usa
`printf()`, así que el header generado sale por stdout y el @OUTPUT@ queda VACÍO. Resultado: al
compilar libwayland, `WL_SHM_FORMAT_*` / `wl_*_interface` / `wl_callback_*` aparecen «undeclared»
(headers de protocolo vacíos). Verificado a fondo: el binario ESTÁTICO escribe bien al archivo; el
DINÁMICO no — mismo source, flags y config.h.
`dup2(outfd, STDOUT_FILENO)` redirige el descriptor 1 a nivel de kernel: TODAS las escrituras a
stdout (cualquiera sea el objeto FILE por la copy-reloc) terminan en el archivo. Robusto frente al
modo de enlace. La salida queda idéntica byte-a-byte a la del scanner estático.
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -36,6 +36,8 @@
#include <getopt.h>
#include <limits.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
#if HAVE_LIBXML
#include <libxml/parser.h>
@@ -2138,11 +2140,14 @@ int main(int argc, char *argv[])
strerror(errno));
exit(EXIT_FAILURE);
}
- if (freopen(argv[2], "w", stdout) == NULL) {
+ int outfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (outfd < 0 || dup2(outfd, STDOUT_FILENO) < 0) {
fprintf(stderr, "Could not open output file: %s\n",
strerror(errno));
fclose(input);
exit(EXIT_FAILURE);
}
+ if (outfd != STDOUT_FILENO)
+ close(outfd);
}
/* initialize protocol structure */
+11 -13
View File
@@ -1,26 +1,24 @@
# wayland 1.25.0 — libwayland-client/server + wayland-scanner. Lo enlaza mirada (smithay) y Mesa # wayland 1.25.0 — libwayland-client/server + wayland-scanner. Lo enlaza mirada (smithay) y Mesa
# (plataforma wayland). Proyecto meson. Sin docs/tests; sin dtd_validation para no arrastrar # (plataforma wayland). Proyecto meson. Sin docs/tests; sin dtd_validation para no arrastrar
# libxml2. Core enlaza libffi; wayland-scanner usa expat (ambos ya en hammer). zig 0.13.0 por el # libxml2. Core enlaza libffi; wayland-scanner usa expat (ambos ya en hammer). zig 0.13.0 por el
# patrón musl (evita miscompilación del zig default). link=dynamic: shared libs. # patrón musl (evita miscompilación del zig default). link=dynamic: shared libs (Mesa las liga).
# #
# ⚠ BLOQUEADA (2026-06-27) — ROOT CAUSE CONFIRMADO: el build de libwayland falla porque # ROOT CAUSE RESUELTO (2026-06-27) — el build de libwayland fallaba con `WL_SHM_FORMAT_*`/`wl_*`
# wayland-scanner genera headers de protocolo VACÍOS (`WL_SHM_FORMAT_ARGB8888`, … undeclared). # «undeclared»: los headers de protocolo salían VACÍOS. NO es bug del scanner ni del XML (ambos
# Verificado: la fuente extraída `work/sources/wayland-*/protocol/wayland.xml` está COMPLETA # OK). Causa real: en el sandbox el `wayland-scanner` in-tree se compila ENLAZADO DINÁMICO contra
# (165075 bytes), expat está OK (estático, sin símbolos glibc-only), y NO es ordenamiento de # la musl (zig cc nativo no hace estático acá), y bajo musl-dinámico `freopen(@OUTPUT@, "w", stdout)`
# samurai (-j1 falla igual). El scanner recibe el XML completo pero emite vacío y sale 0; por # queda roto por la copy-relocation de `stdout` → trunca el archivo pero manda el header a stdout,
# stdin expat dice «no element found» = lee 0 bytes. ⇒ es un BUG DE RUNTIME del wayland-scanner # dejando el @OUTPUT@ vacío. FIX: `wayland-scanner-dup2-output.patch` redirige la salida con
# compilado static-musl en el lab (falla con zig default Y 0.13.0 — no es la regresión de zig). # `dup2(fd, STDOUT_FILENO)` (a nivel de 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). Ver
# FIX recomendado: wayland-scanner es herramienta de BUILD-TIME (no se shippea al rootfs) ⇒ # docs/14 §Estado de build y el encabezado del .patch.
# construirlo NATIVO (host/glibc) y apuntar el build de libwayland al scanner externo
# (`find_program('wayland-scanner')` / wrap de meson), construyendo sólo libwayland-{client,server}
# con musl/zig. Alternativa: patchear la lectura de input del scanner para musl. Ver docs/14 §Estado.
name = "wayland" name = "wayland"
version = "1.25.0" version = "1.25.0"
[source] [source]
tarball = "https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.25.0/downloads/wayland-1.25.0.tar.xz" tarball = "https://gitlab.freedesktop.org/wayland/wayland/-/releases/1.25.0/downloads/wayland-1.25.0.tar.xz"
sha256 = "c065f040afdff3177680600f249727e41a1afc22fccf27222f15f5306faa1f03" sha256 = "c065f040afdff3177680600f249727e41a1afc22fccf27222f15f5306faa1f03"
patches = ["wayland-scanner-dup2-output.patch"]
[build] [build]
compiler = "zig-cc" compiler = "zig-cc"