cosmic: la cadena de pipewire entra a la cola — sale MUCHO más barata de lo estimado

Medido en vez de estimado: copiar pipewire a incoming-cosmic necesita CUATRO
recetas hermanas (alsa-lib, dbus-shared, libsndfile, pulseaudio), no las seis que
había contado a ojo, y de esas **tres dan hash idéntico y ya están selladas**.
Sólo pulseaudio y pipewire hay que construir, porque su glib resuelve al corpus
(b3:93d2cad0) en vez de a la sombra de GNOME (b3:f6ccdf98).

Y eso refina lo que este runbook advertía: el peligro de las dos glib es MEZCLARLAS
EN UNA IMAGEN, y la imagen COSMIC tiene una sola. Acá el costo es de builds, no de
corrección. Lo que sigue vigente es no promover a ciegas entre colas.

Gotcha del copiado: el  se resuelve relativo a la receta, así
que copiar el .toml sin su .patch da 'no pude leer patch' — el hash ni siquiera
se calcula.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-03 12:52:23 -04:00
co-authored by Claude Opus 5
parent 911ac3eeaf
commit d3c0545c4d
6 changed files with 346 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
# alsa-lib 1.2.14 — API de audio del kernel Linux (libasound.so). Campaña KDE (ADR 0011): sustrato de
# PulseAudio → pulseaudio-qt → plasma-pa (el applet de volumen). Primer eslabón de la cadena de AUDIO real
# (hasta ahora el lab sólo tenía libcanberra con backend NULL, sin reproducción).
#
# --disable-python: los bindings pyalsa exigen headers de python + no hacen falta. Sin deps externas.
name = "alsa-lib"
version = "1.2.14"
[source]
tarball = "https://www.alsa-project.org/files/pub/lib/alsa-lib-1.2.14.tar.bz2"
sha256 = "be9c88a0b3604367dd74167a2b754a35e142f670292ae47a2fdef27a2ee97a32"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
flags = []
[build.phases]
configure = './configure --build=$CBUILD --host=$CHOST --prefix=/usr --enable-shared --disable-static --disable-python'
compile = 'make -j"$(nproc)"'
install = "make DESTDIR=/out install && find /out -name '*.la' -delete"
[deps]
build = ["pkgconf"]
+40
View File
@@ -0,0 +1,40 @@
# dbus-shared 1.16.2 — variante DINÁMICA (libdbus-1.so.3) para la isla dinámica de GNOME.
#
# El dbus canónico (recipes/dbus.toml) es `--prefer-static -Ddefault_library=static` y su
# libdbus-1.a no es PIC. gnome-shell la alcanza por transitividad: enlaza atk-bridge-2.0, cuyo .pc
# declara `Requires: atspi-2` y ése `Requires: dbus-1`, así que pkg-config la arrastra al enlace de
# un binario dinámico. Sin la .so el configure ni siquiera llega a compilar — corta con
# `Package 'dbus-1', required by 'atspi-2', not found` cuando el único dbus visible es estático.
#
# Es la cuarta variante -shared de esta cadena (zlib, sqlite, libxml2, libuuid + ésta) y todas por
# la misma raíz: el corpus se construyó para un userland ESTÁTICO y el escritorio es dinámico por
# obligación, no por gusto — la introspección de GObject exige .so reales.
#
# Se mantienen los apagados del canónico (systemd/x11-autolaunch/docs) y su misma versión: un solo
# dbus en la distro, no dos protocolos conviviendo. -Dtools=true igual que el canónico para que el
# artefacto siga trayendo dbus-daemon/dbus-run-session y pueda levantar un bus de verdad.
name = "dbus-shared"
version = "1.16.2"
[source]
tarball = "https://dbus.freedesktop.org/releases/dbus/dbus-1.16.2.tar.xz"
sha256 = "0ba2a1a4b16afe7bceb2c07e9ce99a8c2c3508e5dec290dbb643384bd6beb7e2"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
flags = []
[build.phases]
configure = "PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release -Ddefault_library=shared -Dsystemd=disabled -Dx11_autolaunch=disabled -Ddoxygen_docs=disabled -Dxml_docs=disabled -Dtools=true -Dsystem_pid_file=/run/dbus/dbus.pid"
compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output"
install = '''
set -e
PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install --no-rebuild -C output
# can't install tmpfs
rm -rf /out/run
'''
[deps]
build = ["meson", "samurai", "python3", "pkgconf", "expat"]
+46
View File
@@ -0,0 +1,46 @@
# libsndfile 1.2.2 — lectura/escritura de ficheros de audio (WAV, AIFF, AU…). Entra al frente GNOME
# por debajo de pulseaudio: `sndfile` es dep INCONDICIONAL de su meson.build:615 (top-level, sin
# `required:` que la ablande), así que ni siquiera `-Ddaemon=false` la esquiva. Cadena de la cima:
# gnome-shell → subprojects/gvc → libpulse → libsndfile.
#
# --disable-external-libs es lo que hace que esta receta sea UNA y no CINCO: por defecto libsndfile
# enlaza FLAC, Ogg y Vorbis, ninguna en el corpus. Apagándolos queda una librería C autocontenida
# que no depende de nada fuera de libc. Lo que se pierde es leer .flac/.ogg; lo que consume el
# escritorio de acá son los sonidos de sistema en WAV, que es el formato nativo de libsndfile.
# --disable-mpeg apaga LAME/mpg123 por lo mismo.
#
# --disable-alsa: ALSA sólo la usa el programa de ejemplo sndfile-play, no la librería.
# --disable-sqlite: sólo la usa la utilidad sndfile-regtest.
# --disable-full-suite: no instala los ~10 binarios de utilería (sndfile-info, sndfile-convert…);
# lo que gvc necesita es libsndfile.so y su .pc.
#
# ISLA DINÁMICA: shared, porque libpulse y todo lo que cuelga de gnome-shell son .so.
name = "libsndfile"
version = "1.2.2"
[source]
tarball = "https://github.com/libsndfile/libsndfile/releases/download/1.2.2/libsndfile-1.2.2.tar.xz"
sha256 = "3799ca9924d3125038880367bf1468e53a1b7e3686a934f098b7e1d286cdb80e"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
[build.phases]
configure = '''
./configure \
--build=$CBUILD --host=$CHOST \
--prefix=/usr \
--enable-shared --disable-static \
--disable-external-libs \
--disable-mpeg \
--disable-alsa \
--disable-sqlite \
--disable-full-suite
'''
compile = 'make -j"$(nproc)"'
install = 'make DESTDIR=/out install'
[deps]
build = ["make", "pkgconf"]
@@ -0,0 +1,87 @@
⚠ ESTE PARCHE NO ERA EL BLOQUEO — leer antes de sacar conclusiones.
Se escribió creyendo que `SOUND_INITIALIZED` era lo que impedía enumerar, y **no lo era**: con el
parche aplicado, `wpctl status` seguía dando `Devices:` vacío. La causa real está más abajo en el mismo
fichero y es ESTRUCTURAL, no una propiedad que falte (ver la nota al final).
El parche se conserva porque la incompatibilidad que describe es REAL y volvería a morder en cuanto la
enumeración funcione: sin él, SPA descarta toda tarjeta en un sistema sin udevd. Pero no es la
solución del problema de audio.
pipewire/SPA: no exigir `SOUND_INITIALIZED`, una propiedad que sólo pone udevd con sus reglas.
EL SÍNTOMA, y por qué es caro de leer: con ALSA encendido en el kernel, la tarjeta detectada y
`/dev/snd/controlC0` presente, `wpctl status` seguía dando
Audio
├─ Devices: ← vacío
├─ Sinks: * 33. Dummy Output
o sea el MISMO cuadro que cuando no había kernel con sonido. Tres cosas distintas —no hay ALSA, no hay
tarjeta, hay tarjeta y el stack no la ve— se ven idénticas en esa salida.
LA CAUSA, en la fuente: `spa/plugins/alsa/alsa-udev.c:167`
if (udev_device_get_property_value(udev_device, "SOUND_INITIALIZED") == NULL)
return SPA_ID_INVALID; /* descarta la tarjeta */
`SOUND_INITIALIZED` no es una propiedad del kernel: **la pone udevd al ejecutar sus reglas**
(`78-sound-card.rules` de systemd/eudev marca la tarjeta cuando todos sus devices están listos). Esta
distro usa **libudev-zero**, que lee /sys directo y NO EJECUTA REGLAS por diseño — su
`udev_enumerate_scan_devices` recorre `/sys/dev/block` y `/sys/dev/char`, así que la tarjeta SÍ se
enumera, pero llega sin esa propiedad. Resultado: SPA descarta todas las tarjetas, siempre.
POR QUÉ SE PARCHEA PIPEWIRE Y NO libudev-zero: sintetizar `SOUND_INITIALIZED` en libudev-zero sería
igual de correcto, pero `yupana radio libudev-zero` da **51 artefactos sellados cayendo a deuda** —
está en el cierre de las cinco imágenes. El radio de pipewire son 2. Se paga el barato.
POR QUÉ QUITAR EL GUARDA ES LEGÍTIMO Y NO UN ATAJO: ese `if` existe para no correr una carrera contra
udevd —evitar tomar una tarjeta cuyos devices todavía no aparecieron—. **Con libudev-zero no hay
udevd, así que no hay carrera que perder**: cuando `/sys/dev/char` lista el device, el device existe.
Se elimina una comprobación cuya premisa no se cumple acá, no una que nos moleste.
Lo que NO se toca: los otros tres guardas del mismo bloque (`ACP_IGNORE`, `SOUND_CLASS=modem`,
`DEVPATH`). Los dos primeros son opt-out explícitos del administrador y el tercero es un dato real del
kernel — ésos siguen valiendo.
diff -Naur a/spa/plugins/alsa/alsa-udev.c b/spa/plugins/alsa/alsa-udev.c
--- a/spa/plugins/alsa/alsa-udev.c
+++ b/spa/plugins/alsa/alsa-udev.c
@@ -164,8 +164,13 @@
if ((str = udev_device_get_property_value(udev_device, "SOUND_CLASS")) && spa_streq(str, "modem"))
return SPA_ID_INVALID;
- if (udev_device_get_property_value(udev_device, "SOUND_INITIALIZED") == NULL)
- return SPA_ID_INVALID;
+ /* hammer: NO exigir SOUND_INITIALIZED. Esa propiedad la pone udevd al correr
+ * 78-sound-card.rules, y esta distro usa libudev-zero, que lee /sys directo y no
+ * ejecuta reglas. El guarda existe para no competir con udevd por una tarjeta a
+ * medio inicializar; sin udevd no hay carrera: si /sys/dev/char lista el device,
+ * el device esta. Ver recipes/incoming-gnome/pipewire-sound-initialized.patch.
+ * Los otros guardas de este bloque (ACP_IGNORE, SOUND_CLASS=modem, DEVPATH) se
+ * respetan tal cual: son opt-out del administrador o datos reales del kernel. */
if ((str = udev_device_get_property_value(udev_device, "DEVPATH")) == NULL)
return SPA_ID_INVALID;
══ LO QUE SÍ BLOQUEA, medido después ═════════════════════════════════════════════════════════════
`get_card_nr` sigue con dos comprobaciones más (alsa-udev.c:178-183):
if ((e = strrchr(str, '/')) == NULL) return SPA_ID_INVALID;
if (strlen(e) <= 5 || strncmp(e, "/card", 5) != 0) return SPA_ID_INVALID;
o sea que **sólo acepta el device CARD** (`/sys/.../sound/card0`), no `controlC0` ni `pcmC0D0p`. Y
`card0` es un device de CLASE: no tiene major:minor, no tiene nodo en /dev.
`udev_enumerate_scan_devices` de libudev-zero recorre **exclusivamente** `/sys/dev/block` y
`/sys/dev/char` (udev_enumerate.c:281) — o sea sólo devices CON nodo. El udev real enumera
`/sys/class/*` entero, con nodo o sin él.
⇒ **El device que SPA necesita nunca entra en la enumeración.** No hay guarda que sacar: falta la
mitad del espacio de búsqueda.
**YA RESUELTO (2026-07-30)**, y por el camino (a): `recipes/libudev-zero-scan-class.patch` enseña a
libudev-zero a enumerar devices de CLASE para una lista acotada de subsistemas (hoy `sound`). Se
descartó eudev porque sin udevd es PEOR —rompió el input en otro frente— y correr udevd contradice la
arquitectura. El audio funciona: `48. HDA Intel [alsa]` con sink y source reales. Los detalles, y por
qué la lista es acotada (recorrer `/sys/class` entero rompía el VÍDEO), están en ese parche.
+94
View File
@@ -0,0 +1,94 @@
# pipewire 1.2.7 — EL SERVIDOR DE AUDIO DE LA DISTRO. Decisión tomada por el usuario (2026-07-29):
# **PipeWire, no PulseAudio.** Hasta hoy el corpus tenía sólo el CLIENTE libpulse y el demonio quedaba
# sin decidir; esta receta cierra esa pregunta abierta.
#
# CÓMO CONVIVE CON EL `pulseaudio` DE ESTA MISMA COLA, que es lo que hace que la decisión no rompa
# nada: `pulseaudio` se construyó `-Ddaemon=false` (sólo cliente, para que gvc pueda HABLAR el
# protocolo) y pipewire va con `-Dlibpulse=enabled`, que produce **`pipewire-pulse`**: un servidor que
# habla el protocolo de PulseAudio. O sea que gnome-shell sigue usando libpulse sin saber que del otro
# lado hay PipeWire. Elegir PipeWire NO obligó a tocar una línea del cliente.
#
# ⚠ LLEVA UN PARCHE: `pipewire-sound-initialized.patch`. SPA descartaba TODAS las tarjetas de sonido
# porque exige la propiedad `SOUND_INITIALIZED`, que **no la pone el kernel sino udevd al correr sus
# reglas** — y acá el udev es libudev-zero, que lee /sys directo y no ejecuta reglas por diseño. El
# síntoma era un `wpctl status` con `Devices:` vacío, IDÉNTICO al de no tener ALSA en el kernel. Ver el
# parche: dice por qué se toca pipewire (radio 2) y no libudev-zero (radio 51), y por qué quitar ese
# guarda es legítimo (protege de una carrera contra udevd que sin udevd no existe).
#
# ⚠ GOTCHA DEL LAB, aprendido a la mala el 2026-07-30: **los BYTES del fichero `.patch` entran al
# ArtifactHash** (`Recipe::hash_inputs` lee el patch entero, no sólo su diff), así que **editar la PROSA
# de un parche re-sella el artefacto y todo lo que dependa de él**. Corregir un comentario obsoleto en
# `pipewire-sound-initialized.patch` re-hasheó pipewire y arrastró wireplumber.
# La distinción que conviene tener presente: **comentar una RECETA es gratis** —`hash_inputs` sólo toma
# source/compiler/target/link/flags/fases/deps, no los comentarios del TOML— **y comentar un PARCHE
# cuesta un rebuild**. Si hay que corregir el relato de un parche, hacerlo cuando se pueda pagar.
#
# ⚠ SIN GESTOR DE SESIÓN todavía (`-Dsession-managers=[]`). PipeWire arranca y acepta clientes —lo que
# quita el `Gvc-WARNING: Failed to connect context: Connection refused` del shell— pero sin
# wireplumber no enumera ni enruta dispositivos: no hay política de qué entra y qué sale. Para una VM
# sin tarjeta de sonido alcanza; **para audio de verdad falta autorar `wireplumber`** (Lua + su propio
# cierre). Queda dicho para no confundir «el shell conecta» con «hay sonido».
#
# POR QUÉ UNA COPIA EN ESTA COLA Y NO REUSAR incoming-kde/pipewire.toml: los dos cierres traen glib y
# **NO son la misma glib** — `incoming-kde/glib-shared` y `incoming-gnome/glib` producen
# `libglib-2.0.so.0.8800.1` con bytes DISTINTOS (verificado con `cmp`), y comparten 370 ficheros de
# rutas. Hidratar la receta de KDE en el rootfs de GNOME pondría las dos en la misma ruta, y una
# ganaría por orden de proyección: dos registros de GType en el mismo proceso, que es el cuadro que ya
# costó el episodio de colord. La copia resuelve contra la glib de la isla dinámica.
#
# EL PRECIO DE LA COPIA, medido: cambian `glib-shared`→`glib`, `dbus`→`dbus-shared` y
# `pcre2-shared`→`pcre2`, así que el ArtifactHash NO coincide con el de KDE y se reconstruye. Lo que
# SÍ fue gratis es `alsa-lib`: su única dep es `pkgconf`, que resuelve al catálogo PADRE, ⇒ copiarla
# dio **hash idéntico y cache hit** (b3:93cae411). Es la regla de [[frente-gnome]] sobre duplicar
# recetas entre colas, aplicada con la medición delante.
#
# Fuente del gitlab.freedesktop.org (como networkmanager/modemmanager).
# Recortado al core + SPA: sin bluez5 (cadena de códecs aptx/ldac/aac/opus enorme), sin jack/v4l2/
# libcamera/gstreamer/ffmpeg/vulkan/roc/lv2/avahi/x11/echo-cancel-webrtc/libusb/flatpak/snap.
# systemd/logind/selinux/rtkit off (no hay systemd acá). alsa=enabled + sndfile=enabled + libpulse=enabled
# (el emulador pulse: deja que los clientes libpulse hablen con pipewire) — las 3 ya selladas.
#
# SIN ncurses a propósito: la única consumidora es la tool `pw-top` (monitor de terminal), guardada por
# `if ncurses_dep.found()`. El ncurses del catálogo es static-only y su .pc arrastra `-static` al link ⇒
# "error: using shared libraries requires dynamic linking" al enlazar pw-top contra libpipewire-0.3.so.
# Quitando la dep, meson saltea pw-top y el resto construye.
name = "pipewire"
version = "1.2.7"
[source]
tarball = "https://gitlab.freedesktop.org/pipewire/pipewire/-/archive/1.2.7/pipewire-1.2.7.tar.gz"
sha256 = "e75568ed18bcbe75e9779af57cb9cc256fd7ebfaadc12bb347a0717055d1d3a9"
patches = ["pipewire-sound-initialized.patch"]
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
flags = []
[build.phases]
configure = '''
PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release \
-Ddefault_library=shared \
-Ddocs=disabled -Dman=disabled -Dexamples=disabled -Dtests=disabled \
-Dgstreamer=disabled -Dgstreamer-device-provider=disabled \
-Dsystemd=disabled -Dlogind=disabled -Dsystemd-system-service=disabled \
-Dsystemd-user-service=disabled -Dselinux=disabled -Dlegacy-rtkit=false \
-Dpipewire-jack=disabled -Dpipewire-v4l2=disabled -Djack=disabled -Dv4l2=disabled \
-Dlibcamera=disabled -Dbluez5=disabled -Dffmpeg=disabled -Dvulkan=disabled \
-Droc=disabled -Dlv2=disabled -Davahi=disabled -Dx11=disabled -Dx11-xfixes=disabled \
-Decho-cancel-webrtc=disabled -Dlibusb=disabled -Dflatpak=disabled -Dsnap=disabled \
-Dlibmysofa=disabled -Dsdl2=disabled -Dopus=disabled -Dlibffado=disabled -Dcompress-offload=disabled \
-Dlibcanberra=disabled -Dgsettings=disabled -Dreadline=disabled -Draop=disabled -Davb=disabled \
-Dsession-managers=[] \
-Dalsa=enabled -Dsndfile=enabled -Dlibpulse=enabled -Ddbus=enabled -Dudev=enabled \
-Dpipewire-alsa=disabled \
-Dspa-plugins=enabled -Daudioconvert=enabled -Daudiomixer=enabled -Dcontrol=enabled \
-Dvideoconvert=enabled -Dsupport=enabled
'''
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", "dbus-shared", "expat", "alsa-lib", "libsndfile",
"pulseaudio", "glib", "pcre2", "libffi", "libudev-zero", "zlib-shared", "gettext-tiny"]
+54
View File
@@ -0,0 +1,54 @@
# pulseaudio 17.0 — pero SÓLO las librerías cliente (libpulse, libpulse-simple,
# libpulse-mainloop-glib). No el demonio de sonido.
#
# POR QUÉ ENTRA: gnome-shell incluye el subproyecto `gvc` (el control de volumen del panel) de forma
# INCONDICIONAL — meson.build:256 lo llama sin `if`, y no hay opción para apagarlo — y gvc pide
# `libpulse` y `libpulse-mainloop-glib` duros (subprojects/gvc/meson.build:58). Es la última
# frontera de la cima y llega por el camino más indirecto de toda la campaña:
# gnome-shell → gvc → libpulse → libsndfile.
#
# ── SÓLO CLIENTE, Y POR QUÉ ESO ES LA DECISIÓN CORRECTA ─────────────────────────────────────────
# -Ddaemon=false -Dclient=true. Lo que gvc necesita es hablar el protocolo de PulseAudio, no
# IMPLEMENTARLO: el demonio de sonido de esta distro es una decisión aparte y todavía abierta
# (PulseAudio vs PipeWire), y construir el demonio acá la cerraría de prestado — además de arrastrar
# alsa-lib, orc, speex, soxr y webrtc-audio-processing. Con sólo el cliente, el shell muestra y
# mueve el volumen contra CUALQUIER servidor que hable el protocolo, incluido pipewire-pulse.
#
# -Dglib=enabled NO es opcional: `libpulse-mainloop-glib` es justamente la integración con el bucle
# de eventos de GLib, y es la segunda de las dos .pc que pide gvc.
#
# sndfile sigue haciendo falta pese a -Ddaemon=false: `dependency('sndfile')` está en el top-level
# del meson.build (:615) sin `required:` que la ablande. De ahí la receta libsndfile de esta cola,
# que con --disable-external-libs queda autocontenida (una receta, no cinco).
#
# -Ddatabase=simple: el default es 'tdb' y arrastraría tdb entero. 'simple' es el backend interno.
# Ni siquiera lo usa el cliente, pero el meson lo evalúa igual.
#
# --undefined-version: PulseAudio usa UN SOLO version-script (map-file) con la etiqueta PULSE_0 para
# las tres librerías cliente, así que al enlazar libpulse.so el script nombra símbolos que viven en
# libpulse-simple (pa_simple_new…) y en libpulse-mainloop-glib (pa_glib_mainloop_new…). GNU ld lo
# tolera con un warning; lld lo trata como ERROR. Mismo flag y mismo motivo que en libtiff-shared.
#
# El resto de los `disabled` son backends del demonio y su ecosistema (alsa, bluez5, jack, avahi,
# lirc, x11, orc, soxr, speex, fftw, openssl, systemd, udev, gtk, gsettings, webrtc-aec, tcpwrap,
# asyncns) — cada uno una receta que no hay que autorar. -Delogind=disabled sigue la misma línea que
# el resto de la onda: la C-ABI de logind se esquiva salvo en mutter.
name = "pulseaudio"
version = "17.0"
[source]
tarball = "https://freedesktop.org/software/pulseaudio/releases/pulseaudio-17.0.tar.xz"
sha256 = "053794d6671a3e397d849e478a80b82a63cb9d8ca296bd35b73317bb5ceb87b5"
[build]
compiler = "zig-cc"
target = "x86_64-linux-musl"
link = "dynamic"
[build.phases]
configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload -Ddefault_library=shared -Ddaemon=false -Dclient=true -Dglib=enabled -Ddatabase=simple -Ddoxygen=false -Dman=false -Dtests=false -Dgcov=false -Dalsa=disabled -Dasyncns=disabled -Davahi=disabled -Dbluez5=disabled -Ddbus=disabled -Delogind=disabled -Dfftw=disabled -Dgsettings=disabled -Dgtk=disabled -Djack=disabled -Dlirc=disabled -Dopenssl=disabled -Dorc=disabled -Dsamplerate=disabled -Dsoxr=disabled -Dspeex=disabled -Dsystemd=disabled -Dtcpwrap=disabled -Dudev=disabled -Dwebrtc-aec=disabled -Dx11=disabled -Dc_args=-Wno-error=date-time -Dc_link_args=-Wl,--undefined-version"
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", "gettext-tiny", "glib", "libsndfile", "libffi", "pcre2", "zlib-shared"]