libslirp: la red de usuario que qemu dejó de traer incluida
Dep de qemu, que entra para cerrar «virtualización» — el censo lo marcaba 3 de 3
ausente con el argumento entero en su comentario: «ni invitado ni anfitrión: no
se puede probar la propia ISO sin salir». Este proyecto genera imágenes y las
prueba en QEMU DESDE FUERA; la distro dependía de un anfitrión ajeno para
verificarse a sí misma.
⚠ Y no es un detalle opcional: desde qemu 7.2 la pila slirp dejó de venir
incluida. Sin esta biblioteca `-netdev user` no existe y la única red posible es
tap, que pide root y configurar un puente — o sea que probar una ISO con red se
volvería una operación privilegiada.
Cuesta una receta: medido sobre su meson.build, sus deps son glib-2.0 (está) e
iconv, que musl trae en libc.
⚠ El `.pc` se llama `slirp`, NO `libslirp` — lo fija su
pkg.generate(filebase: 'slirp'), y es el nombre exacto con el que qemu la busca
(dependency('slirp'), meson.build:1281). Un .pc con otro nombre se instalaría
igual y qemu diría «slirp not found» sin mencionar que la biblioteca está, así
que el guardián comprueba el NOMBRE y no sólo la existencia. Y exige slirp_init
DEFINIDO (sección != UND): un símbolo presente no es un símbolo resuelto.
⚠ `-Ddefault_library=static` EXPLÍCITO, y la primera pasada lo aprendió por las
malas: la receta declara link = "static" y aun así salió libslirp.so.0.4.0. En
un proyecto meson el `link` de la receta NO decide lo que se produce —controla
cómo enlaza el lab— y la forma de la biblioteca la decide `default_library`,
cuyo default en meson es `shared`. El idioma del repo es pasarlo explícito, como
hacen cairo.toml y glib.toml. Estática además evita un nodo de runtime: qemu la
embute en vez de arrastrar un NEEDED que habría que declarar en la clausura de
toda imagen con qemu.
Verificado: libslirp.a + include/slirp/libslirp.h + slirp.pc 4.9.5.
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
1 qillqakuna · +79 −0
- recipes/libslirp.toml +79 −0
diff --git a/recipes/libslirp.toml b/recipes/libslirp.toml
new file mode 100644
index 00000000..4f0f3183
--- /dev/null
+++ b/recipes/libslirp.toml
@@ -0,0 +1,79 @@
+# libslirp 4.9.5 — la pila de red en espacio de usuario. Dep de `qemu` para que una máquina virtual
+# tenga red SIN privilegios.
+#
+# ══ POR QUÉ ENTRA ══════════════════════════════════════════════════════════════════════════════
+# `censo-distro.py` marca «virtualización» **3 de 3 ausente**, con el comentario que da el argumento
+# entero: «ni invitado ni anfitrión: **no se puede probar la propia ISO sin salir**». Una distro que
+# genera imágenes y no puede arrancarlas depende de otra máquina para verificarse — y este proyecto
+# ya tiene memorias de probar sus escritorios en QEMU **desde fuera**.
+#
+# ⚠ **Y libslirp no es un detalle opcional de qemu: desde qemu 7.2 la pila slirp DEJÓ DE VENIR
+# incluida.** Sin esta biblioteca, `-netdev user` no existe, y la única red posible es `tap`, que
+# necesita root y configurar un puente. O sea: sin libslirp, probar una ISO con red se convierte en
+# una operación privilegiada. Con ella, es `qemu -netdev user`.
+#
+# ══ CUESTA UNA RECETA: CERO DEPS NUEVAS ════════════════════════════════════════════════════════
+# Medido sobre su `meson.build`: `glib-2.0` (está) e `iconv`, que **musl trae en libc**. Nada más.
+#
+# ⚠ El `.pc` se llama **`slirp`**, no `libslirp` — su `pkg.generate(filebase: 'slirp')` lo fija, y es
+# el nombre exacto con el que qemu la busca (`dependency('slirp')`, `meson.build:1281`). Un `.pc`
+# con otro nombre se instalaría igual y qemu diría «slirp not found» sin mencionar que la
+# biblioteca está. Por eso el guardián comprueba el NOMBRE y no sólo la existencia.
+name = "libslirp"
+version = "4.9.5"
+license = "BSD-3-Clause"
+
+[source]
+tarball = "https://gitlab.freedesktop.org/slirp/libslirp/-/archive/v4.9.5/libslirp-v4.9.5.tar.gz"
+sha256 = "f43e68b60b580647574ec4a0e2b6c600a56281e6c39f79426510832dc810f483"
+
+[build]
+# `glib` del corpus es estática, así que no hay dep shared-only que fuerce dinámico (la regla está
+# en `recipes/gdb.toml`: `link` tiene que coincidir con lo que publican las deps de ESTA receta).
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "static"
+flags = []
+
+[build.phases]
+# `--prefer-static` para que pkg-config entregue los `Requires.private` del corpus estático-primero.
+# ⚠ **`-Ddefault_library=static` EXPLÍCITO, y la primera pasada lo aprendió por las malas:** la
+# receta declara `link = "static"` y aun así salió `libslirp.so.0.4.0`. En un proyecto meson el
+# `link` de la receta **no decide lo que se PRODUCE** —controla cómo enlaza el lab— y lo que decide
+# la forma de la biblioteca es `default_library`, cuyo default de meson es `shared`. El idioma del
+# repo es pasarlo explícito: `cairo.toml` y `glib.toml` lo hacen.
+#
+# Estática además evita un nodo de runtime: qemu la embute en vez de arrastrar un `NEEDED
+# libslirp.so.0` que habría que declarar en la clausura de toda imagen con qemu.
+configure = 'PKG_CONFIG_PATH=/usr/lib/pkgconfig meson setup output --prefix=/usr --buildtype=release --prefer-static -Ddefault_library=static'
+compile = 'meson compile -C output'
+install = '''
+set -e
+DESTDIR=/out meson install -C output
+lib=$(find /out/usr/lib -name 'libslirp.*' 2>/dev/null | head -1)
+[ -n "$lib" ] || { echo "libslirp: no quedó ninguna libslirp.* — NO sello" >&2; ls -R /out/usr 2>/dev/null | head -20 >&2; exit 1; }
+# La ruta de la cabecera importa: qemu incluye <slirp/libslirp.h>, así que tiene que estar en ese
+# subdirectorio y no suelta en /usr/include.
+[ -f /out/usr/include/slirp/libslirp.h ] || { echo "libslirp: falta include/slirp/libslirp.h — es la ruta que qemu incluye" >&2; find /out -name 'libslirp.h' >&2; exit 1; }
+# ⚠ El nombre del `.pc` es el contrato con qemu: `slirp.pc`, no `libslirp.pc`.
+pc=/out/usr/lib/pkgconfig/slirp.pc
+[ -f "$pc" ] || { echo "libslirp: no quedó slirp.pc — qemu la busca como dependency('slirp') y diría «not found» sin mencionar que la biblioteca está" >&2; ls /out/usr/lib/pkgconfig 2>/dev/null >&2; exit 1; }
+# CHEQUEO FUERTE: con PKG_CONFIG_LIBDIR puesto —para no leer el anfitrión— y pidiendo cflags+libs
+# de verdad, que es lo único que valida las transitivas (`Requires: glib-2.0`). `--exists` no valida
+# nada: en este repo dio verde en falso dos veces.
+PKG_CONFIG_LIBDIR=/out/usr/lib/pkgconfig:/usr/lib/pkgconfig pkgconf --cflags --libs slirp >/dev/null 2>&1 || {
+ echo "libslirp: pkgconf no resuelve 'slirp' con sus transitivas — el dependency() de qemu fallaría" >&2
+ PKG_CONFIG_LIBDIR=/out/usr/lib/pkgconfig:/usr/lib/pkgconfig pkgconf --cflags --libs slirp >&2
+ exit 1
+}
+# Y que exporte la API de verdad: una biblioteca presente sin `slirp_init` es un fichero, no una
+# pila de red. Se exige DEFINIDO, no sólo presente — un símbolo UND casa con un grep y no sirve.
+readelf -sW "$lib" 2>/dev/null | awk '$8=="slirp_init" && $7!="UND"{f=1} END{exit !f}' || {
+ echo "libslirp: slirp_init no está DEFINIDO en $(basename "$lib") — qemu enlazaría y no tendría red de usuario" >&2
+ exit 1
+}
+echo "libslirp: $(basename "$lib") + include/slirp/libslirp.h + slirp.pc $(PKG_CONFIG_LIBDIR=/out/usr/lib/pkgconfig:/usr/lib/pkgconfig pkgconf --modversion slirp)"
+'''
+
+[deps]
+build = ["meson", "samurai", "pkgconf", "python3", "glib", "libffi", "pcre2", "zlib", "binutils"]