Files
takana/recipes/wasi-libc-headers.toml
Sergio 85a393aff4 cadena wasm completa: wasi-libc y wasi-sdk sellan (SDD 26, unidad 3.b)
Los cuatro eslabones que enciende RLBox en firefox, sellados de punta a punta:

  wasi-libc-headers  b3:54c6e96d  (andamio, rompe el ciclo del bootstrap)
  wasi-compiler-rt   b3:a3fe63d1  (libclang_rt.builtins-wasm32.a)
  wasi-libc          b3:8e50b145  (libc.a 970.734 bytes, 32 archivos .a)
  wasi-sdk           b3:c8a587fa  (el .cfg que hace el sysroot invisible)

Los dos primeros ya estaban construidos; los dos últimos costaron dos fallos, y
ninguno de los dos era de la receta:

1. `check-symbols` moría por SESGO DE CLANG, no por un artefacto malo. El lab
   trae clang 22.1.8 y este commit de wasi-libc (2025-06-26) congeló su snapshot
   de macros predefinidos contra un clang anterior, así que el diff completo era
   UNA línea: `+#define __wasip1__ 1`. La mitad que importa —los símbolos
   definidos e indefinidos de la libc recién construida— coincidía byte a byte.
   Por eso se RECONCILIA `expected/*/predefined-macros.txt` en vez de saltar el
   chequeo con `make no-check-symbols`, que era la salida fácil: ese target
   existe y se lleva por delante también la comparación de símbolos, que es la
   que vale. Así cualquier OTRA deriva sigue matando el build.

2. `make TARGET_TRIPLE=NOBUILD ... install` NO es un no-op. La regla `install`
   depende de `finish`, que depende de `libc`, así que make no lee el triple
   inexistente como «no construyas» sino como «construí para el triple NOBUILD»
   y muere en `build/NOBUILD/.../crt1-command.o` con `invalid thread model
   'single'` — un error que nombra un fichero que nadie pidió. Se copia
   `sysroot/{lib,share,include}` a mano, que es literalmente lo que hace la
   regla de upstream (`SYSROOT ?= $(CURDIR)/sysroot`).

Cada receta lleva su guardián de contenido, porque acá el modo de fallo caro no
es el ausente sino el vacío: un sysroot con headers y sin libc.a pasa por bueno
y revienta dentro del build de firefox, horas después y sin nombrar a nadie de
esta cadena. Verificado en verde: los builtins son objetos wasm de verdad
(magic 0061736d, no x86_64 nativos) y el .cfg de wasi-sdk apunta a un sysroot
que existe.

El segundo fallo lo diagnosticamos entre dos sesiones: hammer-f8 aportó el
`invalid thread model 'single'` que explicaba la línea que yo veía.

Queda para la próxima unidad el flip de recipes/firefox.toml:
--without-wasm-sandboxed-libraries -> --with-wasi-sysroot, que es un rebuild
largo y su propia unidad de trabajo.
2026-09-06 01:29:41 +00:00

60 lines
3.3 KiB
TOML

# wasi-libc-headers — SÓLO los headers de wasi-libc, para ROMPER el ciclo del bootstrap wasm.
#
# EL CICLO: `wasi-libc` necesita `libclang_rt.builtins-wasm32.a` para enlazar, y
# `wasi-compiler-rt` necesita los headers de wasi-libc para compilar. Ninguno de los dos puede ir
# primero. Se rompe por acá: los headers NO necesitan compilar nada —el target
# `copy-include-headers.stamp` sólo copia ficheros— así que esta receta sale sin builtins y le da a
# `wasi-compiler-rt` el `CMAKE_SYSROOT` que le falta.
#
# ⚠ POR QUÉ ESTE COMMIT Y NO EL DE `wasi-libc`: acá se pinea `ac020b86` (viejo) y en `wasi-libc`
# `3f7eb4c7` (nuevo), igual que Alpine. NO es un descuido. El árbol instala los headers en
# `sysroot/include/$(TARGET_TRIPLE)`, y el TRIPLE POR DEFECTO cambió entre los dos commits:
# `wasm32-wasi` en el viejo, `wasm32-wasip1` en el nuevo. El toolchain file de wasi-sdk que usa
# `wasi-compiler-rt` fija `wasm32-wasi`, así que con el árbol nuevo clang buscaría
# `include/wasm32-wasi` y encontraría `include/wasm32-wasip1` — sysroot vacío y build muerto.
# El artefacto FINAL que consume firefox es el de `wasi-libc` (wasip1, el triple que clang 22.1
# usa de verdad); éste es andamio de bootstrap y muere acá.
#
# Verificado: el sha512 de este tarball coincide byte a byte con el que publica Alpine en su
# APKBUILD de `wasi-compiler-rt` — o sea que la descarga está contrastada contra una fuente
# independiente, no sólo consigo misma.
name = "wasi-libc-headers"
version = "0.20250521"
license = "Apache-2.0 WITH LLVM-exception AND MIT AND CC0-1.0 AND BSD-2-Clause"
[source]
# Tarball `/archive/<commit>` de GitHub: se genera al vuelo, pero va pineado por COMMIT (no por tag
# móvil) y su sha256 está fijado acá, así que un cambio de bytes falla ruidosamente en el fetch.
# El repo trae un `.gitmodules` con `tools/wasi-headers/WASI`, que en el tarball llega VACÍO: es el
# generador de headers desde la espec WASI, y su salida ya está commiteada en el árbol. El Makefile
# no lo toca. No hace falta modo git.
tarball = "https://github.com/WebAssembly/wasi-libc/archive/ac020b86fd44bafe60aa4fa12f407d16e3731329.tar.gz"
sha256 = "d44bd7fa456aa42c1494767e5ffa00cdbab182d8497a577592a6562629f6f49e"
[build]
compiler = "clang"
[deps]
build = ["make"]
[build.phases]
configure = "true"
# `install-include-headers.sh` necesita un shell POSIX y `find`; los dos están en el lab.
compile = 'make build/wasm32-wasi/copy-include-headers.stamp'
install = '''
set -e
mkdir -p /out/usr/share/wasi-sysroot-bootstrap
cp -a sysroot/. /out/usr/share/wasi-sysroot-bootstrap/
# GUARDIÁN. El target de la stamp es un `touch`: si el script de copia fallara sin salir con
# error, la stamp existiría igual y esta receta sellaría un sysroot VACÍO — que es un cache-hit
# envenenado, no un fallo (regla 3 del CLAUDE.md). Se exige un header concreto, no el directorio.
test -f /out/usr/share/wasi-sysroot-bootstrap/include/wasm32-wasi/stdlib.h || {
echo "!! el sysroot de bootstrap no tiene include/wasm32-wasi/stdlib.h" >&2
echo " (¿cambió TARGET_TRIPLE por defecto en este commit de wasi-libc?)" >&2
ls -R /out/usr/share/wasi-sysroot-bootstrap 2>/dev/null | head -30 >&2
exit 1
}
echo "guardián: headers wasm32-wasi presentes ($(find /out/usr/share/wasi-sysroot-bootstrap -name '*.h' | wc -l) .h)"
'''