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.
60 lines
3.3 KiB
TOML
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)"
|
|
'''
|