tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

⎇ main recipes/wasi-libc.toml TOML · 118 lines · 6.3 KB History raw

cadena wasm completa: wasi-libc y wasi-sdk sellan (SDD 26, unidad 3.b) 85a393aff · Sergio ·

1# wasi-libc — la libc de WebAssembly. Es el sysroot que firefox usa para compilar sus librerías
2# enjauladas en wasm (RLBox): los parsers de fuentes y medios —graphite, ogg, expat, woff2—, o sea
3# el código que come entrada no confiable de la red.
4#
5# ES EL ESLABÓN FINAL de la cadena wasm, y el que firefox consume de verdad:
6#   wasi-libc-headers (andamio, triple viejo) → wasi-compiler-rt (los builtins) → ESTE
7#
8# ⚠ COMMIT DISTINTO AL DE `wasi-libc-headers`, a propósito. Acá va el NUEVO (`3f7eb4c7`), cuyo
9# triple por defecto es `wasm32-wasip1`. Ése es el que importa: en LLVM 22.1 el target `wasm32-wasi`
10# se renombró a `wasm32-wasip1` y el propio `toolchain.configure` de Mozilla lo contempla
11# explícitamente, así que el clang 22.1 del lab va a pedir el sysroot con ESE nombre. El commit
12# viejo existe sólo para romper el ciclo de bootstrap; ver `wasi-libc-headers.toml`.
13#
14# Verificado: el sha512 de este tarball coincide byte a byte con el del APKBUILD de Alpine.
15name    = "wasi-libc"
16version = "27.20250626"
17license = "Apache-2.0 WITH LLVM-exception AND Apache-2.0 AND MIT AND CC0-1.0 AND BSD-2-Clause"
18
19[source]
20tarball = "https://github.com/WebAssembly/wasi-libc/archive/3f7eb4c7d6ede4dde3c4bffa6ed14e8d656fe93f.tar.gz"
21sha256  = "6bb86e09dc5ed43260e81176537d702568689cf4203b8beb1f505609c4139ca5"
22
23[build]
24compiler = "clang"
25
26[deps]
27build = ["make", "wasi-compiler-rt"]
28
29[build.phases]
30configure = "true"
31compile = '''
32set -e
33
34# ⚠ `BUILTINS_LIB` NO ES OPCIONAL ACÁ, y no por gusto: si no se define, el Makefile se BAJA una
35# copia conocida desde la CI de wasi-sdk con `curl` (línea ~610 del Makefile upstream). Dentro del
36# sandbox hermético eso no tiene red, así que el build moriría; y si la tuviera sería peor, porque
37# estaríamos sellando un binario ajeno sin hash. Se le pasa el que construyó `wasi-compiler-rt`.
38#
39# Ruta ABSOLUTA, no la relativa que usa el APKBUILD de Alpine: el Makefile la consume como
40# prerequisito de una regla (`$(BUILTINS_LIB_PATH): $(BUILTINS_LIB)`) y la resuelve contra su propio
41# CURDIR, que acá es `/src` y no `/`.
42BUILTINS=/usr/lib/llvm22/lib/clang/22/lib/wasi/libclang_rt.builtins-wasm32.a
43test -f "$BUILTINS" || { echo "!! falta $BUILTINS (¿no llegó la dep wasi-compiler-rt?)" >&2; exit 1; }
44
45unset CFLAGS CXXFLAGS LDFLAGS
46
47# ⚠ `check-symbols` CONTRA UN CLANG MÁS NUEVO QUE EL SNAPSHOT DEL ÁRBOL.
48#
49# El target `check-symbols` del Makefile hace DOS cosas: compara los símbolos definidos/indefinidos
50# de la libc recién construida contra `expected/`, y compara la lista de macros predefinidos del
51# clang que la compiló contra otro snapshot del mismo directorio. Lo primero es una comprobación
52# real del artefacto; lo segundo es un detector de deriva de toolchain.
53#
54# El lab trae clang 22.1.8 y este commit de wasi-libc (2025-06-26) fue congelado contra un clang
55# anterior, así que el build muere con UNA sola línea de diferencia:
56#
57#     +#define __wasip1__ 1
58#
59# La mitad que importa PASÓ: `defined-symbols.txt` y `undefined-symbols.txt` coinciden byte a byte;
60# el diff completo son esas 3.196 líneas iguales y ese macro de más. O sea: la libc construida es la
61# esperada y lo que cambió es que el compilador define un macro nuevo.
62#
63# Por eso se RECONCILIA el snapshot en vez de saltar el chequeo con `make no-check-symbols`, que era
64# la salida fácil: ese target existe y se lleva por delante también la comparación de símbolos, que
65# es justamente la que vale. Así el chequeo sigue vivo y CUALQUIER OTRA deriva —un símbolo que
66# desaparece, otro macro nuevo— sigue matando el build.
67#
68# Se exige que la inserción ocurra: si upstream renombra el ancla, este bloque no puede quedarse
69# callado dejando el mismo fallo para más adelante.
70for T in wasm32-wasip1 wasm32-wasip1-threads; do
71  F="expected/$T/predefined-macros.txt"
72  grep -q '^#define __wasip1__ 1$' "$F" && continue
73  sed -i 's/^#define __wasm 1$/#define __wasip1__ 1\n#define __wasm 1/' "$F"
74  grep -q '^#define __wasip1__ 1$' "$F" || {
75    echo "!! no se pudo reconciliar $F: no apareció el ancla '#define __wasm 1'" >&2
76    exit 1
77  }
78done
79
80# Los dos triples que firefox puede pedir. NO se construye `wasm32-wasip2`: el APKBUILD de Alpine lo
81# hace para rust, que acá no lo consume, y cada triple de más es tiempo de build sin destinatario.
82make CC=clang TARGET_TRIPLE=wasm32-wasip1 BUILTINS_LIB="$BUILTINS"
83make CC=clang TARGET_TRIPLE=wasm32-wasip1-threads THREAD_MODEL=posix BUILTINS_LIB="$BUILTINS"
84
85# `make install` copia `sysroot/{lib,share,include}` en bloque y falla si `share/` no existe.
86mkdir -p sysroot/share
87'''
88install = '''
89set -e
90mkdir -p /out/usr/share/wasi-sysroot
91
92# SE COPIA A MANO EN VEZ DE `make install`, y no es atajo — `make install` NO SIRVE ACÁ.
93#
94# La regla de upstream son dos líneas: `mkdir -p $(INSTALL_DIR)` y
95# `cp -p -r $(SYSROOT)/{lib,share,include} $(INSTALL_DIR)`, con `SYSROOT ?= $(CURDIR)/sysroot`.
96# O sea que copia el sysroot ENTERO, sin mirar el triple. Pero la regla declara `install: finish`
97# y `finish` depende de `libc`, así que invocarla vuelve a entrar al grafo de compilación.
98#
99# El truco de pasarle un triple inexistente (`TARGET_TRIPLE=NOBUILD`, que es lo que hacía la
100# primera versión de esta receta) NO lo evita: make no lo lee como «no construyas», lo lee como
101# «construí para el triple NOBUILD» y muere compilando `build/NOBUILD/.../crt1-command.o` — con
102# un error que habla de un fichero que nadie pidió. Las dos vueltas de arriba ya dejaron el
103# sysroot completo; lo único que falta es moverlo.
104cp -p -r sysroot/lib sysroot/share sysroot/include /out/usr/share/wasi-sysroot/
105
106# GUARDIÁN. Un sysroot con headers pero SIN `libc.a` es exactamente la clase de artefacto que pasa
107# por bueno y revienta 50 minutos después, dentro del build de firefox, con un error que no nombra
108# a wasi-libc. Se exige la libc del triple que firefox va a pedir.
109LIBC=/out/usr/share/wasi-sysroot/lib/wasm32-wasip1/libc.a
110test -s "$LIBC" || {
111  echo "!! el sysroot no trae $LIBC" >&2
112  find /out/usr/share/wasi-sysroot -name '*.a' 2>/dev/null | head -20 >&2
113  exit 1
114}
115test -f /out/usr/share/wasi-sysroot/include/wasm32-wasip1/stdlib.h || {
116  echo "!! el sysroot no trae los headers de wasm32-wasip1" >&2; exit 1; }
117echo "guardián: sysroot wasm32-wasip1 completo (libc.a $(stat -c%s "$LIBC") bytes, $(find /out/usr/share/wasi-sysroot -name '*.a' | wc -l) archivos .a)"
118'''