# man-pages 6.20 — la documentación del sistema. Sin esto, `man open` no contesta nada. # # ══ EL HUECO, MEDIDO — Y EL CENSO LO DESCRIBÍA MAL ═════════════════════════════════════════════ # La fila «páginas de manual» decía *«`mandoc` LEE man; falta el CONTENIDO»*, que se lee como «no # hay ninguna página». **Falso, y por eso valía medirlo antes de construir:** el store tiene 4.710 # páginas de sección 3 y 1.074 de la 1 — cada paquete trae las suyas, y `man pass` o `man curl` # funcionan desde siempre. # # Lo que falta es exacto y es otra cosa: # # find /store/*/usr/share/man/man2 -type f | wc -l ⇒ 0 # man open.2 · read.2 · fork.2 · mmap.2 · signal.7 · socket.7 · printf.3 · malloc.3 ⇒ AUSENTES # # **Cero páginas de sección 2 en todo el corpus**: ni una sola llamada al sistema documentada, ni # las funciones de libc, ni las páginas de concepto de la 7. Eso es justo lo que publica el proyecto # Linux man-pages y nadie más — las de sección 3 que ya había son APIs de bibliotecas (libxcb # aporta 2.311 y libX11 807; o sea que **3.118 de las 4.710 documentan X11, que esta distro # descartó**). # # Para una distro que se compila a sí misma desde fuente, no poder hacer `man mmap` es un hueco con # nombre. Y cuesta 1,9 MB de tarball. # # ══ ⚠ LAS SECCIONES NO ESTÁNDAR, QUE SON LA TRAMPA DE ESTE PAQUETE ════════════════════════════ # man-pages moderno no instala sólo `man1..man9`: trae **`man2const`, `man2type`, `man3attr`, # `man3const`, `man3head`, `man3type`**. Son páginas reales y útiles (`man 3type size_t`, # `man 2const AT_FDCWD`), pero `man` **no las encuentra** si no se las nombra: el buscador recorre # los directorios `man` que conoce. # # ⇒ Acá se instalan igual —tirarlas sería perder contenido— y el guardián comprueba que estén, para # que el día que alguien configure `MANSECT`/`manpath` ya tenga qué encontrar. **No se intenta # arreglar la búsqueda desde esta receta**: eso es configuración de `mandoc`/`man.conf` y le toca al # perfil, no al paquete de datos. Dejarlo dicho vale más que resolverlo a medias y en el sitio # equivocado. # # ══ NO HAY COMPILACIÓN, Y AUN ASÍ EL GUARDIÁN TIENE QUE SER FUNCIONAL ══════════════════════════ # Son ficheros de texto con macros `man(7)`. «Existe el fichero» es trivialmente cierto y no prueba # que sirva: una página puede estar ahí y **no renderizar** si usa macros que el formateador de esta # distro no implementa. Esta distro no trae `groff` — lee con `mandoc`, que es otro programa. # # ⇒ El guardián RENDERIZA con mandoc y busca texto esperado en la salida. Es la diferencia entre # «el paquete está» y «la documentación se puede leer». name = "man-pages" version = "6.20" license = "GPL-2.0-or-later AND LGPL-2.0-or-later AND BSD-3-Clause AND MIT" [source] tarball = "https://mirrors.edge.kernel.org/pub/linux/docs/man-pages/man-pages-6.20.tar.xz" sha256 = "180f0d16a2142dd9671760ac0afeadcc25e861f695eb420293e1206a87ca083f" [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "dynamic" flags = [] [build.phases] # `make install prefix=… DESTDIR=…` es lo que documenta su propio INSTALL. No hay configure. # # ⚠ **DOS EXIGENCIAS DEL `GNUmakefile` QUE NO ESTÁN EN EL `INSTALL`**, y las dos se ven en sus # primeras veinte líneas: # # SHELL ::= bash ← no `sh`: pide bash explícitamente # .SHELLFLAGS ::= -Eeuo pipefail -c # ifneq (4.4.999, …$(MAKE_VERSION)) # ifneq (R,$(findstring R, $(firstword -$(MAKEFLAGS)))) # $(error Please run make(1) with the '-R' option) # # 1. **`-R`** (= `--no-builtin-variables`) es OBLIGATORIO con el make de este lab, y su ausencia # mata el build en la línea 11 con un mensaje que al menos dice qué quiere: # GNUmakefile:11: *** Please run make(1) with the '-R' option. Stop. # La guarda sólo salta por debajo de make 4.4.999 ⇒ el día que el lab suba de make, el `-R` # pasa a ser inofensivo pero sigue siendo correcto. No se quita. # 2. **`bash` es dep de BUILD**, no sólo de lectura: el Makefile corre sus recetas con bash y # `pipefail`. Sin él el fallo llega más tarde y más confuso que el de arriba. configure = "true" compile = "true" install = ''' set -e # ⚠ **`install-man`, NO `install`** — y la diferencia son 12 ejecutables de más. # `share/mk/install/_.mk:21` dice `install: install-man install-bin`, o sea que el objetivo pelado # instala también el `bin/` del PROYECTO: `diffman-git`, `git-bisect-rebase`, `grepc`, `pdfman`, # `sortman`, `mansectf`… Son herramientas para quien CONTRIBUYE a man-pages, no para quien usa la # distro, y entrarían con dependencias que esta receta no declara (git, perl, un `man -Tpdf`). # Un paquete de DATOS que mete doce scripts ajenos en `/usr/bin` es lastre con promesa rota. # ⇒ `install-man` es el objetivo propio de upstream para «sólo las páginas». make -R install-man prefix=/usr DESTDIR=/out # ── 1. las secciones ESTÁNDAR que eran el hueco ────────────────────────────────────────────── n2=$(find /out/usr/share/man/man2 -type f 2>/dev/null | wc -l) n3=$(find /out/usr/share/man/man3 -type f 2>/dev/null | wc -l) n7=$(find /out/usr/share/man/man7 -type f 2>/dev/null | wc -l) [ "$n2" -gt 400 ] || { echo "man-pages: sólo $n2 páginas de sección 2 — esperaba >400; las llamadas al sistema son el motivo de esta receta" >&2; exit 1; } [ "$n3" -gt 1500 ] || { echo "man-pages: sólo $n3 de sección 3 — esperaba >1500" >&2; exit 1; } [ "$n7" -gt 100 ] || { echo "man-pages: sólo $n7 de sección 7 — esperaba >100" >&2; exit 1; } # ── 2. las páginas CONCRETAS que estaban ausentes y motivaron la receta ────────────────────── # Se nombran una por una a propósito: un recuento alto no prueba que esté LA que falta, y éstas # son las que se comprobaron ausentes antes de construir. for p in man2/open.2 man2/read.2 man2/fork.2 man2/mmap.2 man3/malloc.3 man3/printf.3 man7/signal.7 man7/socket.7; do [ -f "/out/usr/share/man/$p" ] || { echo "man-pages: falta $p — era una de las que el censo midió AUSENTES" >&2; exit 1; } done # ── 3. las secciones NO ESTÁNDAR: que estén, aunque `man` aún no las busque ────────────────── for s in man2const man3type; do c=$(find "/out/usr/share/man/$s" -type f 2>/dev/null | wc -l) [ "$c" -gt 10 ] || { echo "man-pages: $s tiene $c ficheros — se instalan a propósito; ver la nota de la receta" >&2; exit 1; } done # ── 4. ⚠ GUARDIÁN FUNCIONAL: que mandoc la RENDERICE de verdad ─────────────────────────────── # Esta distro no tiene groff: lee con mandoc. Una página puede existir y no renderizar. command -v mandoc >/dev/null || { echo "man-pages: no hay mandoc para comprobar el renderizado — el guardián no puede concluir" >&2; exit 1; } sal=$(mandoc -T ascii /out/usr/share/man/man2/open.2 2>/tmp/mandoc.err | head -60) printf '%s' "$sal" | grep -qi 'OPEN' || { echo "man-pages: mandoc no produjo nada reconocible para open.2" >&2; head -10 /tmp/mandoc.err >&2; exit 1; } printf '%s' "$sal" | grep -qi 'O_CREAT\|open a file\|file descriptor' \ || { echo "man-pages: open.2 renderiza pero sin el contenido esperado — ¿macros no soportadas?" >&2; printf '%s\n' "$sal" | head -20 >&2; exit 1; } # Y una de sección 3, que usa otro juego de macros (.SH/.TP con listas de argumentos): mandoc -T ascii /out/usr/share/man/man3/malloc.3 2>/dev/null | grep -qi 'malloc' \ || { echo "man-pages: malloc.3 no renderiza" >&2; exit 1; } # Los avisos de mandoc no se tratan como error: su -W por defecto se queja de estilo en páginas # perfectamente legibles, y convertir eso en fallo sería un guardián ruidoso que nadie respeta. av=$(wc -l < /tmp/mandoc.err 2>/dev/null || echo 0) # ── 5. que NO se hayan colado ejecutables ──────────────────────────────────────────────────── # Centinela para el futuro: si upstream mueve algo de `install-bin` a `install-man`, o si alguien # cambia el objetivo de vuelta a `install`, esto lo caza en el acto en vez de dejarlo entrar en # silencio. Un paquete de datos no tiene nada que hacer en /usr/bin. if [ -e /out/usr/bin ] || [ -e /out/usr/sbin ]; then echo "man-pages: se instalaron EJECUTABLES, y esto es sólo documentación:" >&2 ls /out/usr/bin /out/usr/sbin 2>/dev/null >&2 echo "⇒ ¿se cambió 'install-man' por 'install'? Ver la nota de la receta." >&2 exit 1 fi tot=$(find /out/usr/share/man -type f 2>/dev/null | wc -l) echo "man-pages: $tot páginas ($n2 en sec.2, $n3 en sec.3, $n7 en sec.7) · open.2 y malloc.3 RENDERIZAN con mandoc · $av aviso(s) de estilo, no bloquean" ''' [deps] # `make` + las herramientas que usa el install (`install`, `ln`, `sed`) + `mandoc` PARA EL # GUARDIÁN: sin él no se puede comprobar que las páginas se lean, y un guardián que no puede # concluir falla ruidosamente en vez de dar un falso verde. build = ["make", "bash", "coreutils", "sed", "mandoc", "findutils"] # Son datos: en runtime no ejecutan nada. Quien las LEE es `mandoc`, que ya viaja en `base` — no se # declara como runtime de este paquete porque la relación es la inversa (el lector usa los datos).