gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1346Shell 97Rust 63Markdown 571650 Sutichaykuna

⎇ main recipes/incoming-kde/obs-studio.toml TOML · 155 siq'ikuna · 10.8 KB Ñawpa willay ch'uya

libglvnd: sólo despacho de GL — muere la colisión de libEGL. Y obs-studio llevaba meses sin construir 0cd3e6282 · Sergio ·

1# OBS Studio 32.2.2 — captura y streaming. Segunda app gráfica de usuario final del catálogo,
2# después de mpv (montón A del ADR 0015: sin muro estructural, falta escribirla).
3#
4# ══ POR QUÉ VIVE EN `incoming-kde` Y NO EN EL CORPUS ═══════════════════════════════════════════
5# mpv fue al corpus porque un reproductor lo quieren las cuatro imágenes. OBS no puede: su frontend
6# es **Qt6**, y las 13 recetas Qt viven sólo en `incoming-kde`. Una receta resuelve sibling-first y
7# después el catálogo PADRE, nunca una cola hermana ⇒ desde el corpus no se alcanza Qt.
8#
9# Subir Qt al corpus se MIDIÓ antes de descartarlo, no se supuso:
10#   · `qtbase` sin la cadena X11 cierra en 26 nodos y los 26 YA están en el corpus (cero recetas
11#     nuevas). Tentador.
12#   · Pero el `qtbase` de la cola va `-DQT_FEATURE_xcb=ON`. Un `qtbase` de corpus con xcb OFF tendría
13#     OTRO hash y el MISMO nombre de artefacto (`qt6-qtbase`) ⇒ **dos Qt peleando por
14#     `/usr/lib/libQt6Core.so`** en cualquier imagen que tenga a la vez una app KDE y OBS. Es el
15#     cuadro de las dos glib, y es la trampa que este repo ya pagó dos veces.
16#   · Unificar en un solo Qt Wayland-only obligaría a apagarle xcb a KDE: `yupana radio qtbase` = 119
17#     recetas. Eso es una campaña propia, no un paso de esta receta.
18# Acá, además, la cadena X11 que OBS exige (abajo) ya está, porque la trajo el propio qtbase.
19#
20# ══ MURO 1: EL RENDERER PEDÍA GLX EN RUNTIME ═══════════════════════════════════════════════════
21# `deps/glad/src/glad.c` hacía `dlopen("libGL.so.1")` y buscaba `glXGetProcAddressARB`; si no está,
22# `open_gl()` devuelve 0 y el renderer no arranca. En esta distro NADIE publica `libGL.so.1` (mesa va
23# `glx=disabled`) y el `libglvnd` del corpus se construye sin GLX a propósito, para no meter
24# libX11/libxcb en el catálogo compartido. `obs-glad-egl-loader.patch` cambia la carga a
25# `libEGL.so.1` + `eglGetProcAddress`, que es lo que OBS ya usa para las extensiones en
26# `gl-egl-common.c`. La firma del puntero es la misma, así que el resto de glad no se toca.
27#
28# El muro de LINK es otro y se resuelve aparte: `deps/glad/CMakeLists.txt` linkea `OpenGL::GL`, que
29# en CMake ES `libGL.so`. Se apunta `-DOPENGL_gl_LIBRARY` al `libOpenGL.so.0` de libglvnd — GL de
30# escritorio pelado, sin GLX ni X11.
31#
32# ══ MURO 2: X11/XCB SON INCONDICIONALES ════════════════════════════════════════════════════════
33# `libobs-opengl/CMakeLists.txt` pone `find_package(X11 REQUIRED)`, `XCB` y `X11_XCB` **fuera** del
34# `if(ENABLE_WAYLAND)`: OBS 32 exige la cadena X11 para CONFIGURAR aunque sólo se compile Wayland.
35# No se parchea: en esta cola las libs están (las trajo qtbase) y arrancar una pelea con el CMake de
36# upstream por un `find_package` que se satisface es peor negocio que declarar tres deps.
37#
38# ══ `-lssl -lcrypto` A MANO: EL `.pc` LO DICE Y CMake NO LO LEE ════════════════════════════════
39# El link final moría con `undefined symbol: i2d_SSL_SESSION`, `SSL_CTX_set_cert_store`… referidos
40# desde `libcurl.a(libcurl_la-openssl.o)`. **No falta openssl** —está declarada en `[deps]`— y su
41# `libcurl.pc` incluso trae `Libs.private: -lssl -lcrypto`. Lo que pasa es que OBS resuelve curl con
42# el `FindCURL` de CMake, que localiza `libcurl.a` por fichero y NO consulta el `.pc`: un archivo
43# estático no arrastra sus dependencias, así que nadie pone `-lssl -lcrypto` en la línea.
44#
45# Es el mismo cuadro que `-lfts` en dolphin, y la misma familia que el error de `XML_*` «en
46# libfontconfig.a» que en realidad era expat sin propagar: **el símbolo indefinido nombra a la
47# librería que lo USA, no a la que falta**.
48#
49# `-lz` va por lo mismo, y salió DESPUÉS: al resolver ssl apareció `inflateInit_` — el `.pc` de curl
50# también declara `-lz` en `Libs.private`. Los símbolos indefinidos se destapan por CAPAS, uno por
51# librería no propagada, así que conviene leer la lista entera del `.pc` en vez de ir de a uno.
52#
53# ══ SUBMÓDULOS AUSENTES: EL `touch` NO ES UN TRUCO ═════════════════════════════════════════════
54# `[source]` de takana NO clona submódulos (sólo repo+commit). `obs-browser` y `obs-websocket` son
55# submódulos ⇒ sus directorios llegan VACÍOS, y `plugins/CMakeLists.txt` los agrega si existe el
56# `CMakeLists.txt` de adentro. Crear uno vacío los convierte en subdirectorios válidos que no hacen
57# nada. Es lo mismo que hace el APKBUILD de Alpine, y es honesto: no hay navegador embebido (CEF es
58# un binario ajeno, y eso es territorio de qorpa) ni websocket.
59#
60# ══ LO QUE SE APAGA Y POR QUÉ ══════════════════════════════════════════════════════════════════
61#   ENABLE_BROWSER      CEF es un prebuilt glibc ⇒ montón B (qorpa), no se construye desde fuente.
62#   ENABLE_WEBRTC       pide libdatachannel, que no está en ninguna cola.
63#   ENABLE_VLC          pide vlc, que no está.
64#   ENABLE_LIBFDK       pide fdk-aac, que no está; el AAC de ffmpeg alcanza.
65#   ENABLE_JACK         el servidor de audio de la distro es PipeWire (decisión firme).
66#   ENABLE_QSV11        pide libvpl (Intel), que no está.
67#   ENABLE_NVENC/       NVIDIA: los headers ffnvcodec no están y la distro no trae driver propietario.
68#   ENABLE_FFMPEG_NVENC
69#   ENABLE_AJA/DECKLINK hardware de captura profesional; sin él no se pierde nada en un escritorio.
70#   ENABLE_VST          los plugins VST son binarios ajenos.
71#   ENABLE_SCRIPTING    apagado en esta primera vuelta: luajit está en el corpus pero swig no, y
72#                       swig es un generador que merece su propia receta y su propio turno.
73#   ENABLE_NEW_MPEGTS_  ⚠ HUECO CONOCIDO: apaga la salida MPEG-TS (SRT/RIST), los transportes de
74#   OUTPUT              contribución. `librist` y `libsrt` no están en ninguna cola. Grabar a fichero
75#                       y publicar por RTMP —lo que hace el 99% de los usos— NO pasa por acá. El
76#                       propio CMake nombra esta perilla en su mensaje de error.
77#   ENABLE_V4L2         ⚠ HUECO CONOCIDO, no un descarte: apaga la captura de WEBCAM. `libv4l2.so`
78#                       no lo publica NINGUNA cola y v4l-utils es una receta propia. Lo central de
79#                       OBS —capturar la pantalla— NO pasa por acá sino por `linux-pipewire`, que
80#                       queda ENCENDIDO. Escrito para que no se descubra en la mano del usuario.
81#
82# Fuente por commit (ADR 0006): `32.2.2` es un tag ANOTADO ⇒ esto es el `^{}` pelado.
83name    = "obs-studio"
84version = "32.2.2"
85license = "GPL-2.0-or-later"
86
87[source]
88repo    = "https://github.com/obsproject/obs-studio.git"
89commit  = "ba2f32bdf791005443988a4955e963663e16b1ed"
90patches = ["obs-glad-egl-loader.patch"]
91
92[build]
93compiler = "zig-cc"
94target   = "x86_64-linux-musl"
95# DINÁMICO y no negociable: OBS es `libobs.so` más una decena de plugins `.so` cargados por dlopen.
96# Un OBS estático no carga un plugin.
97link  = "dynamic"
98flags = []
99
100[build.phases]
101configure = '''
102# ⚠ `: >` (TRUNCAR), NO `touch` — CORREGIDO 2026-09-13. El comentario de arriba dice que
103# «`[source]` de takana NO clona submódulos ⇒ sus directorios llegan VACÍOS», y **eso dejó de ser
104# cierto**: los submódulos YA se materializan. Con el árbol real de `obs-websocket` presente,
105# `touch` no lo vacía —sólo actualiza la mtime de un fichero que ya existe— así que su CMakeLists
106# de verdad entra y el configure muere pidiendo `qrcodegencpp`, que no es receta de ninguna cola.
107# `: >` lo trunca exista o no, y el `mkdir -p` hace que funcione en los dos mundos: con submódulos
108# y sin ellos. La receta ya no depende de una premisa que puede cambiar bajo sus pies.
109#
110# Se descubrió porque `libglvnd` cambió y forzó el rebuild: el artefacto sellado tapaba la
111# regresión desde que los submódulos empezaron a materializarse. Un cache-hit congela regresiones.
112for d in plugins/obs-browser plugins/obs-websocket; do mkdir -p "$d"; : > "$d/CMakeLists.txt"; done
113cmake -B build -G Ninja -Wno-dev \
114  -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib \
115  -DCMAKE_SKIP_INSTALL_RPATH=ON -DOBS_VERSION_OVERRIDE=32.2.2 -DCALM_DEPRECATION=ON \
116  -DCMAKE_COMPILE_WARNING_AS_ERROR=OFF \
117  -DCMAKE_EXE_LINKER_FLAGS="-lssl -lcrypto -lz" -DCMAKE_SHARED_LINKER_FLAGS="-lssl -lcrypto -lz" \
118  -DOpenGL_GL_PREFERENCE=GLVND -DOPENGL_gl_LIBRARY=/usr/lib/libOpenGL.so.0 \
119  -DENABLE_WAYLAND=ON -DENABLE_FRONTEND=ON \
120  -DENABLE_BROWSER=OFF -DENABLE_WEBRTC=OFF -DENABLE_VLC=OFF -DENABLE_LIBFDK=OFF \
121  -DENABLE_JACK=OFF -DENABLE_QSV11=OFF -DENABLE_NVENC=OFF -DENABLE_FFMPEG_NVENC=OFF \
122  -DENABLE_AJA=OFF -DENABLE_DECKLINK=0 -DENABLE_VST=OFF -DENABLE_SCRIPTING=OFF -DENABLE_V4L2=OFF -DENABLE_NEW_MPEGTS_OUTPUT=OFF
123'''
124compile = 'cmake --build build'
125install = 'DESTDIR=/out cmake --install build'
126
127[deps]
128build = [
129  "cmake", "samurai", "pkgconf", "python3", "extra-cmake-modules",
130  "qtbase", "qtsvg",
131  "ffmpeg", "x264", "libva",
132  "jansson", "nlohmann-json", "uthash", "simde",
133  # obs-outputs (streaming RTMP) hace find_package(MbedTLS REQUIRED) y NO acepta OpenSSL.
134  "mbedtls",
135  # openssl va porque `libcurl.a` la referencia (Curl_ossl_add_session → i2d_SSL_SESSION y compañía):
136  # el `.a` no arrastra sus deps transitivas, así que el link final las pide sueltas. Patrón
137  # `.pc Requires` → `[deps].build` del corpus.
138  "curl", "openssl", "zlib", "libglvnd", "mesa", "libdrm", "util-linux",
139  # obs-ffmpeg (el plugin de codificación, sin perilla para apagarlo) pide Libpci para identificar la
140  # GPU por su ID. La pciutils canónica va SHARED=no y sólo trae binarios ⇒ variante -shared.
141  "pciutils-shared",
142  "wayland", "wayland-protocols", "libxkbcommon",
143  "pipewire", "speexdsp", "alsa-lib", "pulseaudio",
144  # `plugins/linux-pipewire` pide Gio REQUIRED: es la captura de pantalla por portal, o sea LA
145  # captura en Wayland. glib arrastra pcre2+libffi por el `Requires` de glib-2.0.pc.
146  "glib", "pcre2", "libffi",
147  # freetype-shared y NO la canónica: `text-freetype2.so` es un MÓDULO, y el `libfreetype.a` de la
148  # canónica no es PIC ⇒ `relocation R_X86_64_32 cannot be used against symbol tt_driver_class`.
149  # Es el mismo cuadro de gdk-pixbuf. Lo mismo con fontconfig (IA__FcConfigCreate). Las dos
150  # variantes shared YA existían en el corpus: no hubo que escribirlas, sí que buscarlas.
151  "freetype-shared", "fontconfig-shared", "libpng",
152  # find_package(X11/XCB/X11_XCB) es incondicional en libobs-opengl (ver arriba).
153  "libX11", "libxcb", "libXau", "libXdmcp", "xorgproto",
154  "linux-headers",
155]