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…

TOML 604Rust 56Shell 36Markdown 281227 Definiciones

⎇ 2f9253886ff843d9701ac61a9c3ff4f2cd43ef33 recipes/wasi-compiler-rt.toml TOML · 141 líneas · 7.0 KB Historia crudo

takana etapa 5a: los comentarios de las 741 recetas e852f4849 · Sergio ·

1# wasi-compiler-rt — los builtins de compiler-rt compilados a wasm32.
2#
3# QUÉ ES: la runtime del compilador para WebAssembly (`libclang_rt.builtins-wasm32.a`). Sin esto no
4# se puede enlazar NADA a wasm, y por eso es el primer eslabón real del sandbox RLBox de firefox
5# (SDD 26 §3.bis, lectura 1: RLBox apagado es una desventaja de SEGURIDAD — es la jaula wasm
6# alrededor de los parsers de fuentes y medios, o sea justo el código que come entrada no confiable).
7#
8# NO CONSTRUYE LLVM. El lab ya trae LLVM 22.1.8 CON el backend de WebAssembly compilado dentro
9# (comprobado: `wasm32`, `wasm64` y las descripciones "WebAssembly 32-bit/64-bit" están en
10# `libLLVM.so.22.1`). De acá sale sólo la runtime, que son ~100 ficheros C: minutos, no horas.
11#
12# ⚠ LA VERSIÓN TIENE QUE SEGUIR A LA DEL LAB. Los builtins son un contrato con el clang que los va a
13# usar: Alpine lo escribe como `wasi-compiler-rt~$_llvmver` en las makedepends de firefox. Acá el
14# tarball es 22.1.8 y el lab tiene llvm22 22.1.8-r1 — MISMA versión upstream. Si el lab sube de
15# LLVM, esta receta sube con él. Y no queda al aire: `clang` y `llvm` son prefijos de
16# `TOOLCHAIN_PREFIXES` (takana-core/src/lab.rs), así que un bump del lab MUEVE la huella y re-hashea
17# esto solo. La alineación es un invariante vigilado, no una nota al pie.
18#
19# DÓNDE ATERRIZA: `/usr/lib/llvm22/lib/clang/22/lib/wasi/`, que es el resource dir donde clang
20# busca los builtins sin que nadie le pase un flag. En el lab ese `lib/` NO existe (sólo hay
21# `include/`), y las deps se apilan como capas overlay BAJO el rootfs ⇒ esta receta lo CREA sin
22# pisar nada del lab.
23#
24# Verificado: el sha512 del tarball coincide byte a byte con el del APKBUILD de Alpine.
25name    = "wasi-compiler-rt"
26version = "22.1.8"
27license = "Apache-2.0 WITH LLVM-exception"
28
29[source]
30tarball = "https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/llvm-project-22.1.8.src.tar.xz"
31sha256  = "922f1817a0df7b1489272d18134ee0087a8b068828f87ac63b9861b1a9965888"
32
33[build]
34compiler = "clang"
35
36[deps]
37# `python3`: el CMakeLists de compiler-rt busca Python3 y, si no lo encuentra, cae a un
38# `find_package(Python2 ... REQUIRED)` que MUERE. El error dice "Could NOT find Python2" y lo
39# que falta es python3 — el mensaje nombra el fallback, no la causa.
40build = ["cmake", "samurai", "python3", "wasi-libc-headers"]
41
42[build.phases]
43configure = '''
44set -e
45
46# El toolchain file de wasi-sdk, ESCRITO ACÁ EN VEZ DE TRAÍDO. Upstream son 38 líneas repartidas en
47# dos ficheros del tarball de wasi-sdk (`wasi-sdk.cmake` + `cmake/Platform/WASI.cmake`, y el segundo
48# es literalmente `set(WASI 1)`). Traerlos costaría una fuente de red y una receta enteras para 38
49# líneas de declaraciones puras — peor trato. Se transcriben de wasi-sdk-27, que es el que Alpine
50# pinea para esta misma versión de compiler-rt.
51mkdir -p cmake/Platform
52echo 'set(WASI 1)' > cmake/Platform/WASI.cmake
53cat > wasi-sdk.cmake <<'EOF'
54list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
55set(CMAKE_SYSTEM_NAME WASI)
56set(CMAKE_SYSTEM_VERSION 1)
57set(CMAKE_SYSTEM_PROCESSOR wasm32)
58set(triple wasm32-wasi)
59set(CMAKE_C_COMPILER   ${WASI_SDK_PREFIX}/bin/clang)
60set(CMAKE_CXX_COMPILER ${WASI_SDK_PREFIX}/bin/clang++)
61set(CMAKE_ASM_COMPILER ${WASI_SDK_PREFIX}/bin/clang)
62set(CMAKE_AR      ${WASI_SDK_PREFIX}/bin/llvm-ar)
63set(CMAKE_RANLIB  ${WASI_SDK_PREFIX}/bin/llvm-ranlib)
64set(CMAKE_C_COMPILER_TARGET   ${triple})
65set(CMAKE_CXX_COMPILER_TARGET ${triple})
66set(CMAKE_ASM_COMPILER_TARGET ${triple})
67# No buscar EJECUTABLES en el sysroot (los de correr durante el build son del host); el resto,
68# SÓLO en el sysroot, para que no se cuele una lib nativa x86_64 en un enlace a wasm.
69set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
70set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
71set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
72set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
73EOF
74
75# CFLAGS/LDFLAGS del entorno se limpian a propósito: cualquier flag pensado para el x86_64 nativo
76# (un `-static`, un `-march`) es veneno en un enlace a wasm32 y el error que produce no se parece
77# en nada a la causa.
78unset CFLAGS CXXFLAGS LDFLAGS
79
80cmake -B build -G Ninja -S compiler-rt -Wno-dev \
81  -DCMAKE_BUILD_TYPE=MinSizeRel \
82  -DCMAKE_MODULE_PATH=/src/cmake \
83  -DCMAKE_TOOLCHAIN_FILE=/src/wasi-sdk.cmake \
84  -DCMAKE_C_COMPILER_WORKS=ON \
85  -DCMAKE_CXX_COMPILER_WORKS=ON \
86  -DCOMPILER_RT_BAREMETAL_BUILD=ON \
87  -DCOMPILER_RT_INCLUDE_TESTS=OFF \
88  -DCOMPILER_RT_HAS_FPIC_FLAG=OFF \
89  -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
90  -DCOMPILER_RT_OS_DIR=wasi \
91  -DCMAKE_AR=/usr/bin/llvm-ar \
92  -DCMAKE_RANLIB=/usr/bin/llvm-ranlib \
93  -DWASI_SDK_PREFIX=/usr \
94  -DCMAKE_INSTALL_PREFIX=/usr/lib/llvm22/lib/clang/22/ \
95  -DCMAKE_SYSROOT=/usr/share/wasi-sysroot-bootstrap
96'''
97compile = 'cmake --build build'
98install = '''
99set -e
100DESTDIR=/out cmake --install build
101
102RES=/out/usr/lib/llvm22/lib/clang/22
103
104# El `include/` del resource dir pertenece al LAB (son los headers de clang). Instalarlo desde acá
105# lo taparía con una copia del tarball: misma trampa que las deps `clang18`/`llvm18` que había que
106# quitar de firefox. Fuera.
107rm -rf "$RES/include"
108
109# Los alias que espera clang según cómo se nombre el target. `wasm32-wasi` se renombró a
110# `wasm32-wasip1` en LLVM 22.1 (lo dice el propio configure de Mozilla), así que el mismo `.a`
111# tiene que responder a los dos nombres o el enlace falla por un alias que no existe.
112for p in 1 2; do
113  ln -s ./wasi "$RES/lib/wasm32-wasip$p"
114  ln -s ./wasi "$RES/lib/wasm32-unknown-wasip$p"
115done
116ln -s ./libclang_rt.builtins-wasm32.a "$RES/lib/wasi/libclang_rt.builtins.a"
117
118# GUARDIÁN. Un `cmake --install` que no instala nada sale con 0 y deja el árbol vacío — que en el
119# store es un cache-hit envenenado, no un fallo. Se exige el fichero Y que sea un archivo wasm de
120# verdad, no un `.a` vacío ni uno de objetos x86_64.
121A="$RES/lib/wasi/libclang_rt.builtins-wasm32.a"
122test -s "$A" || { echo "!! no se instaló $A" >&2; find /out -name 'libclang_rt*' >&2; exit 1; }
123N=$(llvm-nm --print-file-name "$A" 2>/dev/null | wc -l)
124test "$N" -gt 0 || { echo "!! $A no tiene símbolos: archivo vacío" >&2; exit 1; }
125
126# Que los miembros sean WASM y no x86_64 nativos. Es LA comprobación que importa: si el sysroot o el
127# triple se configuran mal, cmake compila igual pero produce objetos nativos, el `.a` queda lleno y
128# con símbolos, y el fallo recién aparece al enlazar firefox — lejos y sin nombrar a esta receta.
129# Se mira el número mágico del objeto (`\0asm`), no el nombre del fichero: la primera versión de
130# este guardián exigía que el miembro terminara en `.o` y lo rechazó estando BIEN construido,
131# porque compiler-rt los nombra de otro modo. Una convención de nombre no es una propiedad.
132M=$(llvm-ar t "$A" | head -1)
133mkdir -p /tmp/guardian && (cd /tmp/guardian && llvm-ar x "$A" "$M")
134MAGIC=$(od -An -tx1 -N4 "/tmp/guardian/$M" | tr -d ' \n')
135test "$MAGIC" = "0061736d" || {
136  echo "!! los objetos de $A NO son wasm (magic=$MAGIC, esperaba 0061736d)" >&2
137  echo "   primer miembro: $M" >&2
138  exit 1
139}
140echo "guardián: builtins wasm32 instalados ($(llvm-ar t "$A" | wc -l) objetos, magic wasm ok, $(stat -c%s "$A") bytes)"
141'''