libglvnd b3:e27d3b2833a6aa6a6b4a4caad5ef2121e7be31a3c7ae59d0db22b01d696ffc99 obs-studio b3:29d95ddf50ef79692b48cae493758def564202ef81eba236b6cb279757621403 ── libglvnd: se apagan egl, gles1, gles2 y headers ───────────────────────────────────────────── La receta se escribió para la campaña completa —glvnd toma libEGL y mesa pasa a ser vendor detrás— y la campaña NO SE HIZO: las tres mesa siguen con -Dglvnd=false. El resultado, medido en /mnt/cosecha/escritorios/kde-rootfs ya hidratado, era el cuadro que la propia receta anunciaba: /usr/lib/libEGL.so.1 -> libEGL.so.1.0.0 1.440.624 B (mesa: el driver) /usr/lib/libEGL.so.1.1.0 323.144 B (glvnd: despacho, HUÉRFANO) Dos libEGL.so.1 distintos en la MISMA ruta, más libGLESv2.so.2 y los headers GL/, EGL/ y GLES2/ duplicados y con BYTES DISTINTOS (gl.h: 79.877 vs 80.393). Quién gana depende del orden de hidratación y nada lo guarda. Y no hacía falta: OBS, que es la razón de que la receta exista, NO usa glvnd en runtime. libobs-opengl.so sale con NEEDED libEGL.so.1 y nada más, y sus indefinidos son todos egl* —ni un gl[A-Z] sin resolver— o sea que su glad resuelve por eglGetProcAddress contra la EGL de mesa. Lo único que glvnd le da es satisfacer el OpenGL::GL de CMake AL ENLAZAR. Ahora sella libGLdispatch.so.0 + libOpenGL.so.0 + opengl.pc y nada más: CERO ficheros en común con mesa. Radio medido: 1 dependiente. ⚠ Esto quita el DAÑO, no cierra el muro: libOpenGL.so.0 enlaza y en runtime sigue sin haber vendor (no hay libEGL_mesa.so.0 ni egl_vendor.d). Cerrarlo es re-sellar las TRES mesa con -Dglvnd=true en un movimiento, y el precio está medido: `yupana radio mesa` = 148 directos, 154 transitivos, 153 sellados que caen a deuda, las CINCO imágenes. Decisión de distro, no arreglo de paso. ── obs-studio: el cache-hit tapaba una regresión ─────────────────────────────────────────────── Al forzar su rebuild, el configure murió pidiendo `qrcodegencpp`, que no es receta de ninguna cola. La causa NO era libglvnd. La receta dice «[source] de takana NO clona submódulos ⇒ sus directorios llegan VACÍOS» y por eso hacía `touch plugins/obs-websocket/CMakeLists.txt`. Esa premisa dejó de ser cierta: los submódulos YA se materializan, así que `touch` no vacía nada —sólo toca la mtime de un fichero que existe— y el CMakeLists de verdad entra pidiendo su dependencia. Corregido a `mkdir -p` + `: >` (truncar), que funciona con submódulos y sin ellos: la receta deja de depender de una premisa que puede cambiarle bajo los pies. Construye y sella en el hub.
119 lines
7.0 KiB
TOML
119 lines
7.0 KiB
TOML
# libglvnd 1.7.0 — la capa de DESPACHO de OpenGL (GL Vendor Neutral Dispatch).
|
|
#
|
|
# ══ POR QUÉ ENTRA: EL MURO DEL GL DE ESCRITORIO ════════════════════════════════════════════════
|
|
# Hasta hoy NINGUNA cola publicaba `libGL.so`, `libGL.so.1` ni `gl.pc` (medido con
|
|
# `scripts/provee.py`): mesa va `-Dglx=disabled -Dglvnd=false`, así que sólo hay `libEGL.so` y
|
|
# `libGLESv2.so`. Consecuencia: **toda app que pida GL de escritorio compila y muere al LIGAR** —
|
|
# mesa SÍ instala `GL/gl.h`, así que el error llega tarde y disfrazado.
|
|
#
|
|
# El caso que lo destapó es OBS: `deps/glad/CMakeLists.txt` linkea `PUBLIC OpenGL::GL`, que en CMake
|
|
# ES `libGL.so`. No es un gate de configure que se pueda desactivar: es un link.
|
|
#
|
|
# ══ SIN GLX Y SIN X11 — LA DECISIÓN QUE HACE ESTO COHERENTE ════════════════════════════════════
|
|
# glvnd parte el `libGL.so.1` histórico en dos piezas, y esa partición es justo lo que necesita una
|
|
# distro Wayland-only:
|
|
# · `libGL.so.1` GL **+ GLX** en una sola lib (la de siempre) ⇒ implica X11.
|
|
# · `libOpenGL.so.0` GL de escritorio PELADO, sin ventana ni plataforma ⇒ no implica nada.
|
|
# Vamos por la segunda: `-Dglx=disabled -Dx11=disabled`. Un consumidor que pida `OpenGL::GL` se
|
|
# apunta a `libOpenGL.so.0` con `-DOPENGL_gl_LIBRARY=`, y el contexto lo crea por EGL.
|
|
#
|
|
# Esto NO es una limitación que arrastremos: es la decisión de X11-al-tacho aplicada al stack de GL.
|
|
# Encender glx acá metería libX11/libxcb/xorgproto —hoy sólo en `incoming-kde/`— en el CORPUS, o sea
|
|
# en las cinco imágenes, para servir a una sola app.
|
|
#
|
|
# ══ QUÉ QUEDA INSTALADO ════════════════════════════════════════════════════════════════════════
|
|
# libGLdispatch.so.0 la tabla de despacho; el corazón, todos los demás la usan
|
|
# libOpenGL.so.0 GL de escritorio (lo que faltaba)
|
|
# libEGL.so.1 EGL, ahora como DESPACHO: el vendor real lo pone mesa (libEGL_mesa.so.0)
|
|
# libGLESv1_CM.so.1 / libGLESv2.so.2
|
|
#
|
|
# ══ 2026-09-13 · SÓLO DESPACHO DE GL: `egl/gles/headers` APAGADOS, Y ES UN ARREGLO ════════════
|
|
# Esta receta se escribió pensando en la campaña completa —glvnd toma libEGL y mesa pasa a ser
|
|
# vendor detrás— y la campaña NO SE HIZO: las tres mesa siguen con `-Dglvnd=false`. El resultado
|
|
# medido, en `/mnt/cosecha/escritorios/kde-rootfs` ya hidratado, era el cuadro que el propio párrafo
|
|
# de abajo anunciaba:
|
|
#
|
|
# /usr/lib/libEGL.so.1 -> libEGL.so.1.0.0 1.440.624 B (mesa: el driver)
|
|
# /usr/lib/libEGL.so.1.1.0 323.144 B (glvnd: despacho, HUÉRFANO)
|
|
#
|
|
# Dos `libEGL.so.1` distintos en la MISMA ruta, más `libGLESv2.so.2` y los headers `GL/`, `EGL/` y
|
|
# `GLES2/` duplicados y **con bytes distintos** (`gl.h`: 79.877 vs 80.393). Quién gana depende del
|
|
# orden de hidratación y nada lo guarda — la enfermedad de las dos glib, otra vez.
|
|
#
|
|
# Y no hacía falta para nada: **OBS, que es la razón de que esta receta exista, no usa glvnd en
|
|
# runtime.** `libobs-opengl.so` sale con `NEEDED libEGL.so.1` y nada más, y sus símbolos indefinidos
|
|
# son todos `egl*` — ni un `gl[A-Z]` sin resolver — o sea que su `glad` resuelve los punteros por
|
|
# `eglGetProcAddress` contra la EGL de mesa. Lo único que glvnd le da es satisfacer el
|
|
# `OpenGL::GL` de CMake **al ENLAZAR**.
|
|
#
|
|
# ⇒ Se apagan `egl`, `gles1`, `gles2` y `headers`. Queda lo que de verdad se usa:
|
|
# libGLdispatch.so.0 libOpenGL.so.0 opengl.pc
|
|
# Cero ficheros en común con mesa ⇒ cero colisión. Radio: **1 dependiente** (obs-studio).
|
|
#
|
|
# ⚠ ESTO NO ES LA CAMPAÑA, ES QUITAR EL DAÑO MIENTRAS LA CAMPAÑA NO SE DECIDE. Hoy
|
|
# `libOpenGL.so.0` enlaza y **en runtime no hay vendor** (no existe `libEGL_mesa.so.0` ni
|
|
# `/usr/share/glvnd/egl_vendor.d/`): una app que llame de verdad por ahí encuentra una tabla vacía.
|
|
# Cerrarlo es re-sellar las TRES mesa con `-Dglvnd=true` en un solo movimiento, y el precio está
|
|
# medido: `yupana radio mesa` = **148 dependientes directos, 154 transitivos, 153 sellados que caen
|
|
# a deuda, las CINCO imágenes**. Es decisión de distro, no un arreglo de paso.
|
|
#
|
|
# ⚠ EL CAMBIO DE DUEÑO DE libEGL NO ES MENOR. Hoy `libEGL.so.1` la instala mesa directo; con glvnd
|
|
# la instala glvnd y mesa pasa a ser un VENDOR detrás (`-Dglvnd=true` ⇒ `libEGL_mesa.so.0` + su JSON
|
|
# en `/usr/share/glvnd/egl_vendor.d/`). Mismo soname, otro fichero y otro dueño: si mesa se
|
|
# reconstruye con glvnd y algo sigue hidratando el libEGL viejo, hay DOS libEGL en la ruta — el
|
|
# cuadro de las dos glib con otra cara. Por eso mesa se reconstruye en la MISMA campaña, no después.
|
|
#
|
|
# Fuente por commit (ADR 0006): los `/archive/` de las forjas se generan al vuelo y su sha256 cambia
|
|
# cuando el servidor actualiza git/gzip. `v1.7.0` es un tag LIGERO (una sola ref en `ls-remote`, sin
|
|
# `^{}`) ⇒ este sha ES el commit.
|
|
name = "libglvnd"
|
|
version = "1.7.0"
|
|
license = "MIT"
|
|
|
|
[source]
|
|
repo = "https://gitlab.freedesktop.org/glvnd/libglvnd.git"
|
|
commit = "faa23f21fc677af5792825dc30cb1ccef4bf33a6"
|
|
|
|
[build]
|
|
compiler = "zig-cc"
|
|
target = "x86_64-linux-musl"
|
|
# DINÁMICO y no negociable: el punto entero de glvnd es que el vendor se resuelve en RUNTIME por
|
|
# dlopen. Una glvnd estática no despacha a nadie.
|
|
link = "dynamic"
|
|
flags = []
|
|
|
|
# ══ EL WRAPPER: `-Wl,--version-script` SEPARADO DE SU RUTA ═════════════════════════════════════
|
|
# meson emite `-Wl,--version-script /src/…/export_list_tls.ver` (con ESPACIO, no con `=`). Con gcc
|
|
# eso anda de casualidad: `-Wl,--version-script` le pasa la opción al linker y el `.ver` queda como
|
|
# argumento suelto del DRIVER, que gcc reenvía al linker porque no sabe qué es. zig-cc es estricto y
|
|
# lo rechaza: `error: /src/…/export_list_tls.ver: unrecognized file extension`.
|
|
#
|
|
# El wrapper une el par en `-Wl,--version-script=<ruta>`, que es la forma que zig sí entiende. No se
|
|
# parchea el meson.build de upstream: el defecto no es de glvnd, es del contrato entre meson y el
|
|
# driver, y un wrapper es reversible y no toca la fuente.
|
|
[build.phases]
|
|
configure = '''
|
|
ZW="$PWD/.zwrap"; mkdir -p "$ZW"
|
|
cat > "$ZW/cc" <<'W'
|
|
#!/bin/sh
|
|
a=""
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
-Wl,--version-script) shift; a="$a -Wl,--version-script=$1" ;;
|
|
*) a="$a $1" ;;
|
|
esac
|
|
shift
|
|
done
|
|
exec hammer-zig-cc $a
|
|
W
|
|
chmod +x "$ZW/cc"
|
|
CC="$ZW/cc" PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release \
|
|
-Dx11=disabled -Dglx=disabled -Degl=false -Dgles1=false -Dgles2=false \
|
|
-Dasm=enabled -Dtls=true -Dheaders=false
|
|
'''
|
|
compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
|
|
install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild"
|
|
|
|
[deps]
|
|
build = ["meson", "samurai", "python3", "pkgconf"]
|