From cddae462057ef5228c5dfd434dfa9902b9e108ab Mon Sep 17 00:00:00 2001 From: Sergio Date: Sun, 6 Sep 2026 01:46:38 +0000 Subject: [PATCH] =?UTF-8?q?wasi-libcxx:=20el=20directorio=20VAC=C3=8DO=20q?= =?UTF-8?q?ue=20hace=20visible=20a=20libc++=20(y=20el=20guardi=C3=A1n=20qu?= =?UTF-8?q?e=20lo=20prueba)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Segunda muerte del firefox con RLBox, otra vez a los 6 segundos y con el mismo mensaje engañoso, ya con wasi-libcxx sellado: checking the wasm C compiler can find wasi headers... yes checking the wasm C++ compiler can find wasi headers... fatal error: 'cstring' file not found El C pasaba todo y sólo fallaba el C++. Y `cstring` ESTABA en el artefacto, en include/wasm32-wasip1/c++/v1/cstring. No era un fichero que faltara: era un fichero que clang no buscaba. CAUSA. El APKBUILD de Alpine hace un `mkdir -p .../include/c++/v1` que parece ruido de empaquetado y yo descarté al transcribir. Es la SONDA por la que el driver de clang decide que el sysroot tiene layout de libc++; sin ese directorio no añade `include//c++/v1` a la lista de búsqueda. MEDIDO, no deducido. Sysroot fusionado (wasi-libc + wasi-libcxx) y la invocación literal del configure de Mozilla, dentro del lab: clang++ -std=gnu++20 --target=wasm32-wasip1 conftest.cpp --sysroot=$S -c sin include/c++/v1 -> fatal error: 'cstring' file not found con include/c++/v1 -> exit 0 Es el reverso exacto de la regla 3 del CLAUDE.md: allá un directorio vacío es un artefacto mentiroso, acá un directorio vacío es una declaración dirigida al compilador. Queda documentado en la receta para que nadie lo borre por limpieza. Y la lección que deja el guardián nuevo: los tests de presencia que tenía la receta habrían dado esto por bueno, porque "existe" no es "se encuentra". Así que ahora la receta corre LA MISMA PRUEBA que el configure de firefox, contra un sysroot fusionado con el de su dep. Si pasa acá no puede fallar allá; y si falla, falla en el segundo 20 de esta receta —imprimiendo la lista de búsqueda de clang— y no en el segundo 6 de un build de cuatro horas que además culpa a otro. Re-hashea: wasi-libcxx b3:1361deae -> b3:838a9557, y con él firefox. --- recipes/wasi-libcxx.toml | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/recipes/wasi-libcxx.toml b/recipes/wasi-libcxx.toml index 6afc0573..d90acf31 100644 --- a/recipes/wasi-libcxx.toml +++ b/recipes/wasi-libcxx.toml @@ -163,6 +163,27 @@ for t in wasm32-unknown-wasip1 wasm32-unknown-wasip1-threads; do done cd /src +# ⚠ UN DIRECTORIO VACÍO QUE SÍ IMPORTA — y por eso está en su propia línea con su propio párrafo. +# +# El APKBUILD de Alpine hace un `mkdir -p .../include/c++/v1` que parece ruido de empaquetado. NO +# lo es: es la SONDA por la que el driver de clang decide que este sysroot tiene layout de libc++. +# Sin ese directorio, clang NO añade `include//c++/v1` a la lista de búsqueda, y los +# headers quedan instalados en el artefacto y a la vez invisibles para el compilador. +# +# MEDIDO, no deducido. Con el sysroot fusionado (wasi-libc + esta receta) y la invocación EXACTA +# que hace el configure de firefox: +# +# clang++ -std=gnu++20 --target=wasm32-wasip1 conftest.cpp --sysroot=$S -c +# +# sin include/c++/v1 -> fatal error: 'cstring' file not found (y `cstring` ESTABA ahí) +# con include/c++/v1 -> exit 0 +# +# Es el reverso exacto de la regla 3 del CLAUDE.md: allá un directorio vacío es un artefacto +# mentiroso; acá un directorio vacío es una declaración dirigida al compilador. Borrarlo por +# "limpieza" reintroduce un fallo que aparece a 6 segundos de un build de 4 horas, culpando a los +# headers de WASI, que están perfectos. +mkdir -p "$S/include/c++/v1" + # GUARDIÁN. Se exige exactamente lo que el configure de firefox no encontró: el header de C++ que # disparó todo esto y la librería que lo respalda, PARA LOS DOS TRIPLES. Un `cmake --install` que no # instala nada sale con 0, y un sysroot con headers y sin `.a` pasa por bueno y revienta dentro del @@ -181,4 +202,30 @@ for t in wasm32-wasip1 wasm32-wasip1-threads; do done echo "guardián: $t ok — libc++.a $(stat -c%s "$A") bytes, libc++abi.a $(stat -c%s "$B") bytes" done + +# ── GUARDIÁN DE VERDAD: CORRER LA MISMA PRUEBA QUE HACE EL CONFIGURE DE FIREFOX ─────────────── +# Los tests de arriba comprueban que los ficheros existen, y "existe" no es "se encuentra": el +# fallo que motivó esta receta era exactamente eso —`cstring` presente en el disco e invisible +# para clang—, así que un guardián de presencia lo habría dado por bueno. +# +# Se reproduce la invocación literal del configure de Mozilla contra un sysroot FUSIONADO (el de +# la dep `wasi-libc` más lo que acaba de instalar esta receta), que es la forma en que se va a usar +# de verdad. Si esto pasa acá, no puede fallar allá; y si falla, falla en el segundo 20 de ESTA +# receta y no en el segundo 6 de un build de cuatro horas que además culpa a otro. +P=/tmp/sysroot-fusionado +mkdir -p "$P" +cp -a /usr/share/wasi-sysroot/. "$P"/ # lo que aporta la dep wasi-libc +cp -a "$S"/. "$P"/ # lo que aporta esta receta +echo '#include ' > /tmp/probe.cpp +for t in wasm32-wasip1 wasm32-wasip1-threads; do + clang++ -std=gnu++20 --target=$t /tmp/probe.cpp --sysroot="$P" -c -o /tmp/probe.o || { + echo "!! libc++ instalada pero INVISIBLE para clang en $t." >&2 + echo " Los headers están en el artefacto y el compilador no los encuentra." >&2 + echo " Sospechá del directorio-sonda include/c++/v1 antes que de la instalación." >&2 + clang++ -std=gnu++20 --target=$t /tmp/probe.cpp --sysroot="$P" -c -o /tmp/probe.o -v 2>&1 \ + | sed -n '/search starts/,/End of search/p' >&2 + exit 1 + } + echo "guardián: clang++ encuentra para $t (la prueba exacta del configure de firefox)" +done '''