OBS Studio 32.2.2 — segunda app gráfica de usuario final, con el renderer portado a EGL
13 plugins sellados, entre ellos los que importan: linux-pipewire (captura de
pantalla en Wayland), obs-ffmpeg, obs-x264, obs-outputs (RTMP RTMP),
linux-pulseaudio/alsa y text-freetype2.
EL PORT. El glad de OBS hacía dlopen("libGL.so.1") + dlsym("glXGetProcAddressARB")
y devolvía 0 si no lo hallaba, o sea que el renderer no arrancaba: OBS estaba
atado a GLX —y por tanto a X11— aun corriendo en Wayland puro. Acá nadie publica
libGL.so.1 y el libglvnd del corpus va sin GLX a propósito. El parche carga por
libEGL.so.1 + eglGetProcAddress, que es lo que OBS ya usa para las extensiones.
Verificado en el artefacto, no en el log: libobs-opengl.so.30 tiene CERO
ocurrencias de glXGetProcAddressARB, sus NEEDED son libEGL.so.1 +
libwayland-egl.so.1, y el binario no filtra a glibc.
DÓNDE VIVE. En incoming-kde y no en el corpus porque su frontend es Qt6 y las 13
recetas Qt viven sólo en esa cola. Se midió antes de descartar el corpus: qtbase
sin X11 cierra en 26 nodos que YA están en el corpus, pero el qtbase de la cola va
xcb=ON, así que un qtbase de corpus tendría otro hash con el MISMO nombre de
artefacto ⇒ dos Qt peleando por /usr/lib/libQt6Core.so. Unificar obligaría a
apagarle xcb a KDE: radio 119.
Los símbolos indefinidos salieron por CAPAS y ninguno nombraba al culpable:
freetype (.a no PIC) → fontconfig (idem) → i2d_SSL_SESSION → inflateInit_. Las dos
primeras se arreglaron usando las variantes -shared que YA existían en el corpus;
las dos últimas con -lssl -lcrypto -lz, porque OBS resuelve curl con el FindCURL
de CMake, que toma libcurl.a por fichero y no lee su Libs.private. Un símbolo
indefinido nombra a la librería que lo USA, no a la que falta.
Huecos escritos en la receta para que no se descubran en la mano del usuario:
sin webcam (ENABLE_V4L2=OFF, libv4l2 no está en ninguna cola), sin salida MPEG-TS
(SRT/RIST ausentes) y sin scripting (falta swig). Grabar, capturar pantalla y
publicar por RTMP no pasan por ninguno de los tres.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
Cargar los punteros de GL por EGL en vez de por GLX.
|
||||
|
||||
El `glad` que OBS trae hace, en Linux, `dlopen("libGL.so.1")` y busca dentro
|
||||
`glXGetProcAddressARB`; si no lo encuentra, `open_gl()` devuelve 0, `gladLoadGL()`
|
||||
falla y el renderer de OpenGL no arranca. Eso ata a OBS a GLX —y por lo tanto a
|
||||
X11— incluso corriendo en una sesión Wayland pura, que es la única que esta
|
||||
distro tiene: acá nadie publica `libGL.so.1` (mesa va `glx=disabled`) y el
|
||||
libglvnd del corpus se construye SIN GLX a propósito, para no arrastrar
|
||||
libX11/libxcb al catálogo compartido.
|
||||
|
||||
EGL 1.5 resuelve funciones de GL de escritorio por `eglGetProcAddress`, que es lo
|
||||
que OBS ya usa en `gl-egl-common.c` para las extensiones. El parche cambia la
|
||||
librería y el símbolo; la firma es la misma (`void *(*)(const char *)`), así que
|
||||
el resto de glad queda intacto.
|
||||
|
||||
--- a/deps/glad/src/glad.c
|
||||
+++ b/deps/glad/src/glad.c
|
||||
@@ -48,7 +48,7 @@
|
||||
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"
|
||||
};
|
||||
#else
|
||||
- static const char *NAMES[] = {"libGL.so.1", "libGL.so"};
|
||||
+ static const char *NAMES[] = {"libEGL.so.1", "libEGL.so"};
|
||||
#endif
|
||||
|
||||
unsigned int index = 0;
|
||||
@@ -60,7 +60,7 @@
|
||||
return 1;
|
||||
#else
|
||||
gladGetProcAddressPtr = (PFNGLXGETPROCADDRESSPROC_PRIVATE)dlsym(libGL,
|
||||
- "glXGetProcAddressARB");
|
||||
+ "eglGetProcAddress");
|
||||
return gladGetProcAddressPtr != NULL;
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
# OBS Studio 32.2.2 — captura y streaming. Segunda app gráfica de usuario final del catálogo,
|
||||
# después de mpv (montón A del ADR 0015: sin muro estructural, falta escribirla).
|
||||
#
|
||||
# ══ POR QUÉ VIVE EN `incoming-kde` Y NO EN EL CORPUS ═══════════════════════════════════════════
|
||||
# mpv fue al corpus porque un reproductor lo quieren las cuatro imágenes. OBS no puede: su frontend
|
||||
# es **Qt6**, y las 13 recetas Qt viven sólo en `incoming-kde`. Una receta resuelve sibling-first y
|
||||
# después el catálogo PADRE, nunca una cola hermana ⇒ desde el corpus no se alcanza Qt.
|
||||
#
|
||||
# Subir Qt al corpus se MIDIÓ antes de descartarlo, no se supuso:
|
||||
# · `qtbase` sin la cadena X11 cierra en 26 nodos y los 26 YA están en el corpus (cero recetas
|
||||
# nuevas). Tentador.
|
||||
# · Pero el `qtbase` de la cola va `-DQT_FEATURE_xcb=ON`. Un `qtbase` de corpus con xcb OFF tendría
|
||||
# OTRO hash y el MISMO nombre de artefacto (`qt6-qtbase`) ⇒ **dos Qt peleando por
|
||||
# `/usr/lib/libQt6Core.so`** en cualquier imagen que tenga a la vez una app KDE y OBS. Es el
|
||||
# cuadro de las dos glib, y es la trampa que este repo ya pagó dos veces.
|
||||
# · Unificar en un solo Qt Wayland-only obligaría a apagarle xcb a KDE: `yupana radio qtbase` = 119
|
||||
# recetas. Eso es una campaña propia, no un paso de esta receta.
|
||||
# Acá, además, la cadena X11 que OBS exige (abajo) ya está, porque la trajo el propio qtbase.
|
||||
#
|
||||
# ══ MURO 1: EL RENDERER PEDÍA GLX EN RUNTIME ═══════════════════════════════════════════════════
|
||||
# `deps/glad/src/glad.c` hacía `dlopen("libGL.so.1")` y buscaba `glXGetProcAddressARB`; si no está,
|
||||
# `open_gl()` devuelve 0 y el renderer no arranca. En esta distro NADIE publica `libGL.so.1` (mesa va
|
||||
# `glx=disabled`) y el `libglvnd` del corpus se construye sin GLX a propósito, para no meter
|
||||
# libX11/libxcb en el catálogo compartido. `obs-glad-egl-loader.patch` cambia la carga a
|
||||
# `libEGL.so.1` + `eglGetProcAddress`, que es lo que OBS ya usa para las extensiones en
|
||||
# `gl-egl-common.c`. La firma del puntero es la misma, así que el resto de glad no se toca.
|
||||
#
|
||||
# El muro de LINK es otro y se resuelve aparte: `deps/glad/CMakeLists.txt` linkea `OpenGL::GL`, que
|
||||
# en CMake ES `libGL.so`. Se apunta `-DOPENGL_gl_LIBRARY` al `libOpenGL.so.0` de libglvnd — GL de
|
||||
# escritorio pelado, sin GLX ni X11.
|
||||
#
|
||||
# ══ MURO 2: X11/XCB SON INCONDICIONALES ════════════════════════════════════════════════════════
|
||||
# `libobs-opengl/CMakeLists.txt` pone `find_package(X11 REQUIRED)`, `XCB` y `X11_XCB` **fuera** del
|
||||
# `if(ENABLE_WAYLAND)`: OBS 32 exige la cadena X11 para CONFIGURAR aunque sólo se compile Wayland.
|
||||
# No se parchea: en esta cola las libs están (las trajo qtbase) y arrancar una pelea con el CMake de
|
||||
# upstream por un `find_package` que se satisface es peor negocio que declarar tres deps.
|
||||
#
|
||||
# ══ `-lssl -lcrypto` A MANO: EL `.pc` LO DICE Y CMake NO LO LEE ════════════════════════════════
|
||||
# El link final moría con `undefined symbol: i2d_SSL_SESSION`, `SSL_CTX_set_cert_store`… referidos
|
||||
# desde `libcurl.a(libcurl_la-openssl.o)`. **No falta openssl** —está declarada en `[deps]`— y su
|
||||
# `libcurl.pc` incluso trae `Libs.private: -lssl -lcrypto`. Lo que pasa es que OBS resuelve curl con
|
||||
# el `FindCURL` de CMake, que localiza `libcurl.a` por fichero y NO consulta el `.pc`: un archivo
|
||||
# estático no arrastra sus dependencias, así que nadie pone `-lssl -lcrypto` en la línea.
|
||||
#
|
||||
# Es el mismo cuadro que `-lfts` en dolphin, y la misma familia que el error de `XML_*` «en
|
||||
# libfontconfig.a» que en realidad era expat sin propagar: **el símbolo indefinido nombra a la
|
||||
# librería que lo USA, no a la que falta**.
|
||||
#
|
||||
# `-lz` va por lo mismo, y salió DESPUÉS: al resolver ssl apareció `inflateInit_` — el `.pc` de curl
|
||||
# también declara `-lz` en `Libs.private`. Los símbolos indefinidos se destapan por CAPAS, uno por
|
||||
# librería no propagada, así que conviene leer la lista entera del `.pc` en vez de ir de a uno.
|
||||
#
|
||||
# ══ SUBMÓDULOS AUSENTES: EL `touch` NO ES UN TRUCO ═════════════════════════════════════════════
|
||||
# `[source]` de hammer NO clona submódulos (sólo repo+commit). `obs-browser` y `obs-websocket` son
|
||||
# submódulos ⇒ sus directorios llegan VACÍOS, y `plugins/CMakeLists.txt` los agrega si existe el
|
||||
# `CMakeLists.txt` de adentro. Crear uno vacío los convierte en subdirectorios válidos que no hacen
|
||||
# nada. Es lo mismo que hace el APKBUILD de Alpine, y es honesto: no hay navegador embebido (CEF es
|
||||
# un binario ajeno, y eso es territorio de qorpa) ni websocket.
|
||||
#
|
||||
# ══ LO QUE SE APAGA Y POR QUÉ ══════════════════════════════════════════════════════════════════
|
||||
# ENABLE_BROWSER CEF es un prebuilt glibc ⇒ montón B (qorpa), no se construye desde fuente.
|
||||
# ENABLE_WEBRTC pide libdatachannel, que no está en ninguna cola.
|
||||
# ENABLE_VLC pide vlc, que no está.
|
||||
# ENABLE_LIBFDK pide fdk-aac, que no está; el AAC de ffmpeg alcanza.
|
||||
# ENABLE_JACK el servidor de audio de la distro es PipeWire (decisión firme).
|
||||
# ENABLE_QSV11 pide libvpl (Intel), que no está.
|
||||
# ENABLE_NVENC/ NVIDIA: los headers ffnvcodec no están y la distro no trae driver propietario.
|
||||
# ENABLE_FFMPEG_NVENC
|
||||
# ENABLE_AJA/DECKLINK hardware de captura profesional; sin él no se pierde nada en un escritorio.
|
||||
# ENABLE_VST los plugins VST son binarios ajenos.
|
||||
# ENABLE_SCRIPTING apagado en esta primera vuelta: luajit está en el corpus pero swig no, y
|
||||
# swig es un generador que merece su propia receta y su propio turno.
|
||||
# ENABLE_NEW_MPEGTS_ ⚠ HUECO CONOCIDO: apaga la salida MPEG-TS (SRT/RIST), los transportes de
|
||||
# OUTPUT contribución. `librist` y `libsrt` no están en ninguna cola. Grabar a fichero
|
||||
# y publicar por RTMP —lo que hace el 99% de los usos— NO pasa por acá. El
|
||||
# propio CMake nombra esta perilla en su mensaje de error.
|
||||
# ENABLE_V4L2 ⚠ HUECO CONOCIDO, no un descarte: apaga la captura de WEBCAM. `libv4l2.so`
|
||||
# no lo publica NINGUNA cola y v4l-utils es una receta propia. Lo central de
|
||||
# OBS —capturar la pantalla— NO pasa por acá sino por `linux-pipewire`, que
|
||||
# queda ENCENDIDO. Escrito para que no se descubra en la mano del usuario.
|
||||
#
|
||||
# Fuente por commit (ADR 0006): `32.2.2` es un tag ANOTADO ⇒ esto es el `^{}` pelado.
|
||||
name = "obs-studio"
|
||||
version = "32.2.2"
|
||||
license = "GPL-2.0-or-later"
|
||||
|
||||
[source]
|
||||
repo = "https://github.com/obsproject/obs-studio.git"
|
||||
commit = "ba2f32bdf791005443988a4955e963663e16b1ed"
|
||||
patches = ["obs-glad-egl-loader.patch"]
|
||||
|
||||
[build]
|
||||
compiler = "zig-cc"
|
||||
target = "x86_64-linux-musl"
|
||||
# DINÁMICO y no negociable: OBS es `libobs.so` más una decena de plugins `.so` cargados por dlopen.
|
||||
# Un OBS estático no carga un plugin.
|
||||
link = "dynamic"
|
||||
flags = []
|
||||
|
||||
[build.phases]
|
||||
configure = '''
|
||||
touch plugins/obs-browser/CMakeLists.txt plugins/obs-websocket/CMakeLists.txt
|
||||
cmake -B build -G Ninja -Wno-dev \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib \
|
||||
-DCMAKE_SKIP_INSTALL_RPATH=ON -DOBS_VERSION_OVERRIDE=32.2.2 -DCALM_DEPRECATION=ON \
|
||||
-DCMAKE_COMPILE_WARNING_AS_ERROR=OFF \
|
||||
-DCMAKE_EXE_LINKER_FLAGS="-lssl -lcrypto -lz" -DCMAKE_SHARED_LINKER_FLAGS="-lssl -lcrypto -lz" \
|
||||
-DOpenGL_GL_PREFERENCE=GLVND -DOPENGL_gl_LIBRARY=/usr/lib/libOpenGL.so.0 \
|
||||
-DENABLE_WAYLAND=ON -DENABLE_FRONTEND=ON \
|
||||
-DENABLE_BROWSER=OFF -DENABLE_WEBRTC=OFF -DENABLE_VLC=OFF -DENABLE_LIBFDK=OFF \
|
||||
-DENABLE_JACK=OFF -DENABLE_QSV11=OFF -DENABLE_NVENC=OFF -DENABLE_FFMPEG_NVENC=OFF \
|
||||
-DENABLE_AJA=OFF -DENABLE_DECKLINK=0 -DENABLE_VST=OFF -DENABLE_SCRIPTING=OFF -DENABLE_V4L2=OFF -DENABLE_NEW_MPEGTS_OUTPUT=OFF
|
||||
'''
|
||||
compile = 'cmake --build build'
|
||||
install = 'DESTDIR=/out cmake --install build'
|
||||
|
||||
[deps]
|
||||
build = [
|
||||
"cmake", "samurai", "pkgconf", "python3", "extra-cmake-modules",
|
||||
"qtbase", "qtsvg",
|
||||
"ffmpeg", "x264", "libva",
|
||||
"jansson", "nlohmann-json", "uthash", "simde",
|
||||
# obs-outputs (streaming RTMP) hace find_package(MbedTLS REQUIRED) y NO acepta OpenSSL.
|
||||
"mbedtls",
|
||||
# openssl va porque `libcurl.a` la referencia (Curl_ossl_add_session → i2d_SSL_SESSION y compañía):
|
||||
# el `.a` no arrastra sus deps transitivas, así que el link final las pide sueltas. Patrón
|
||||
# `.pc Requires` → `[deps].build` del corpus.
|
||||
"curl", "openssl", "zlib", "libglvnd", "mesa", "libdrm", "util-linux",
|
||||
# obs-ffmpeg (el plugin de codificación, sin perilla para apagarlo) pide Libpci para identificar la
|
||||
# GPU por su ID. La pciutils canónica va SHARED=no y sólo trae binarios ⇒ variante -shared.
|
||||
"pciutils-shared",
|
||||
"wayland", "wayland-protocols", "libxkbcommon",
|
||||
"pipewire", "speexdsp", "alsa-lib", "pulseaudio",
|
||||
# `plugins/linux-pipewire` pide Gio REQUIRED: es la captura de pantalla por portal, o sea LA
|
||||
# captura en Wayland. glib arrastra pcre2+libffi por el `Requires` de glib-2.0.pc.
|
||||
"glib", "pcre2", "libffi",
|
||||
# freetype-shared y NO la canónica: `text-freetype2.so` es un MÓDULO, y el `libfreetype.a` de la
|
||||
# canónica no es PIC ⇒ `relocation R_X86_64_32 cannot be used against symbol tt_driver_class`.
|
||||
# Es el mismo cuadro de gdk-pixbuf. Lo mismo con fontconfig (IA__FcConfigCreate). Las dos
|
||||
# variantes shared YA existían en el corpus: no hubo que escribirlas, sí que buscarlas.
|
||||
"freetype-shared", "fontconfig-shared", "libpng",
|
||||
# find_package(X11/XCB/X11_XCB) es incondicional en libobs-opengl (ver arriba).
|
||||
"libX11", "libxcb", "libXau", "libXdmcp", "xorgproto",
|
||||
"linux-headers",
|
||||
]
|
||||
Reference in New Issue
Block a user