Files
hammer/recipes/incoming-gnome/pipewire.toml
T
sergioandClaude Opus 5 346cd59706 licencias: campo license en la receta — de 0 a 228 de 1141, sin re-hashear nada
La deuda legal bloqueante del SDD 19 §2.1. Medido hoy: **0 de 1141 recetas** declaraban
licencia, no «5 de 771» como decía el informe anterior. Los dos números estaban mal: los
«5» eran falsos positivos de `grep license` (el paquete `addlicense`, el paquete
`cargo-bundle-licenses`, una línea `install .../share/licenses/` y un comentario), y las
recetas son 1141. Contar con `grep -l <palabra>` sobre TOML cuenta comentarios y nombres,
no campos; `scripts/licencias.sh` cuenta el campo de verdad (clave en la raíz, antes del
primer `[table]`).

LO QUE HACE LA DEUDA PAGABLE: `Recipe::hash_inputs` es una LISTA BLANCA — sólo entran
source, compiler, target, link, patches, flags, phases y deps. `license` no entra, igual
que `evidence` y `slots`. Por eso se puede poblar en las recetas YA SELLADAS sin mover un
solo ArtifactHash. Verificado, no supuesto: en 40 recetas modificadas se comparó el hash
con y sin la línea — 40 idénticos, 0 cambiados. Si el campo entrara al hash, declarar la
licencia costaría reconstruir el corpus entero y no se haría nunca. Clavado con el test
`licencia_round_trip_y_no_afecta_el_hash`.

TRAMPA DE TOML: una clave suelta después de un `[table]` pertenece a esa tabla. Puesta al
final del fichero, `license` acaba dentro de `[deps]` y se pierde EN SILENCIO, porque serde
ignora los campos que no conoce — no hay error, simplemente no está. Va arriba, junto a
`name` y `version`; el sembrador la inserta tras `version`.

NO SE ADIVINA. Declarar mal una licencia es peor que dejarla vacía: convierte un hueco
visible en una afirmación falsa. Sólo se puebla desde una tabla curada entrada por entrada
(`docs/licencias-conocidas.tsv`); lo que no tiene evidencia queda vacío y se CUENTA.
Concretamente se descartó el atajo «k* = KDE ⇒ LGPL»: en este catálogo `kail`, `kind`,
`ko`, `kopia`, `krew`, `kustomize`, `kyverno`, `katana`, `kibi`, `kmon` y toda la familia
`kube*` son herramientas Go sin relación con KDE. El nombre no es evidencia.

Quedan 913, casi todas CLIs Go/Rust importados en masa — y ésas sí son automatizables con
evidencia real: Cargo.toml trae el campo `license` y los módulos Go traen su LICENSE en el
árbol. El cierre estructural es capturarlo en la fase de fetch, que ya descarga y extrae
cada tarball, y inyectar el texto en `hammer pack` (aguas abajo del ArtifactHash) en vez de
en la fase install (que sí re-hashearía).

De paso, respaldo-storagebox.sh reordenado por valor irreemplazable y con zstd: medido en
la oficina, el uplink da 8 Mbps iguales por cable y por wifi ⇒ 128 G no caben en una
sentada, así que sube primero el cerebro (estado + repo) y `--partial-dir` hace que cortar
a mitad de un artefacto no tire lo ya subido.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 10:24:11 -04:00

96 lines
6.3 KiB
TOML

# 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"
license = "MIT"
[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"]