libclang_rt.profile.a, 129.178 bytes — la que implementa los __llvm_profile_* y
escribe los .profraw. Hermana nativa de wasi-compiler-rt: mismo tarball de LLVM
22.1.8, mismo patrón, mismo sitio de aterrizaje; cambia el target (x86_64 en vez
de wasm32) y el componente (profile en vez de builtins).
Lo destapó el build del firefox instrumentado, en el minuto 38:56:
ld.lld: error: cannot open
/usr/lib/llvm22/lib/clang/22/lib/x86_64-alpine-linux-musl/libclang_rt.profile.a
El lab trae clang 22.1.8 con su include/ pero el lib/ del resource dir NO EXISTE
— que es exactamente lo que wasi-compiler-rt ya documentaba para el caso wasm.
O sea: el PGO no estaba bloqueado por el display (eso se despejó ayer) sino por
una pieza de toolchain que nunca hizo falta hasta ahora.
Se apaga todo menos profile: compiler-rt trae sanitizers, xray, memprof, orc y
ninguno tiene destinatario acá.
La primera corrida murió en el configure con «CMAKE_C_COMPILER_TARGET must also
be set when COMPILER_RT_DEFAULT_TARGET_ONLY is ON» — un error de cmake que dice
exactamente qué falta, cosa que no se puede dar por supuesta esta noche.
Dos guardianes. El primero exige la RUTA LITERAL del error y no «alguna
libclang_rt»: el layout per-target es una opción de cmake y equivocarla deja la
librería donde clang no mira, que es el mismo fallo que la libstdc++ en
/usr/lib64 de hace unas horas. El segundo es la prueba del consumidor: que
DEFINA __llvm_profile_write_file y compañía, para que un .a vacío no se descubra
al final de una corrida de perfilado.
104 lines
5.2 KiB
TOML
104 lines
5.2 KiB
TOML
# compiler-rt-profile — la runtime de PERFILADO de compiler-rt para el target nativo.
|
|
#
|
|
# QUÉ ES: `libclang_rt.profile.a`, la librería que implementa los `__llvm_profile_*` y que ESCRIBE
|
|
# los ficheros `.profraw`. Sin ella, `-fprofile-generate` compila y no enlaza.
|
|
#
|
|
# ══ POR QUÉ EXISTE: EL LAB NO TRAE NINGUNA RUNTIME DE COMPILER-RT ══════════════════════════════
|
|
# Lo descubrió el build del firefox instrumentado, en el minuto 38:56:
|
|
#
|
|
# ld.lld: error: cannot open
|
|
# /usr/lib/llvm22/lib/clang/22/lib/x86_64-alpine-linux-musl/libclang_rt.profile.a
|
|
#
|
|
# El lab trae clang 22.1.8 con su `include/` pero **el `lib/` del resource dir no existe** — es
|
|
# exactamente lo que ya documentaba `recipes/wasi-compiler-rt.toml` para el caso wasm. Esta receta
|
|
# es su HERMANA NATIVA: mismo tarball, mismo patrón, mismo sitio de aterrizaje; lo que cambia es el
|
|
# target (x86_64 en vez de wasm32) y el componente (profile en vez de builtins).
|
|
#
|
|
# ⚠ LA VERSIÓN SIGUE A LA DEL LAB, igual que su hermana y por lo mismo: la runtime de perfilado es
|
|
# un contrato con el clang que la va a usar (el formato del `.profraw` tiene versión). El tarball es
|
|
# 22.1.8 y el lab trae llvm22 22.1.8-r1. Como `clang`/`llvm` son prefijos de `TOOLCHAIN_PREFIXES`,
|
|
# un bump del lab mueve la huella y re-hashea esto solo: la alineación está vigilada, no confiada.
|
|
#
|
|
# DÓNDE ATERRIZA: `/usr/lib/llvm22/lib/clang/22/lib/<triple>/`, que es donde clang la busca sin que
|
|
# nadie le pase un flag — el layout "per-target runtime dir", que es el que nombra el error. En el
|
|
# lab ese directorio no existe y las deps se apilan como overlay BAJO el rootfs, así que esta receta
|
|
# lo CREA sin pisar nada.
|
|
name = "compiler-rt-profile"
|
|
version = "22.1.8"
|
|
license = "Apache-2.0 WITH LLVM-exception"
|
|
|
|
[source]
|
|
tarball = "https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/llvm-project-22.1.8.src.tar.xz"
|
|
sha256 = "922f1817a0df7b1489272d18134ee0087a8b068828f87ac63b9861b1a9965888"
|
|
|
|
[build]
|
|
compiler = "clang"
|
|
|
|
[deps]
|
|
# `python3` por lo mismo que en la hermana: el CMakeLists de compiler-rt busca Python3 y sin él cae
|
|
# a un `find_package(Python2 ... REQUIRED)` que muere diciendo «Could NOT find Python2» — el mensaje
|
|
# nombra el fallback, no la causa.
|
|
build = ["cmake", "samurai", "python3"]
|
|
|
|
[build.phases]
|
|
configure = '''
|
|
set -e
|
|
# Se apaga TODO menos profile. compiler-rt trae sanitizers, xray, memprof, orc… y ninguno hace falta
|
|
# acá; construirlos multiplicaría el tiempo y ampliaría la superficie de fallo sin destinatario.
|
|
unset CFLAGS CXXFLAGS LDFLAGS
|
|
cmake -B build -G Ninja -S compiler-rt -Wno-dev \
|
|
-DCMAKE_BUILD_TYPE=MinSizeRel \
|
|
-DCMAKE_C_COMPILER=clang \
|
|
-DCMAKE_CXX_COMPILER=clang++ \
|
|
-DCMAKE_AR=/usr/bin/llvm-ar \
|
|
-DCMAKE_RANLIB=/usr/bin/llvm-ranlib \
|
|
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \
|
|
-DCMAKE_C_COMPILER_TARGET=x86_64-alpine-linux-musl \
|
|
-DCMAKE_CXX_COMPILER_TARGET=x86_64-alpine-linux-musl \
|
|
-DCMAKE_ASM_COMPILER_TARGET=x86_64-alpine-linux-musl \
|
|
-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \
|
|
-DCOMPILER_RT_BUILD_PROFILE=ON \
|
|
-DCOMPILER_RT_BUILD_BUILTINS=OFF \
|
|
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
|
|
-DCOMPILER_RT_BUILD_XRAY=OFF \
|
|
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF \
|
|
-DCOMPILER_RT_BUILD_MEMPROF=OFF \
|
|
-DCOMPILER_RT_BUILD_ORC=OFF \
|
|
-DCOMPILER_RT_BUILD_CTX_PROFILE=OFF \
|
|
-DCOMPILER_RT_INCLUDE_TESTS=OFF \
|
|
-DCMAKE_INSTALL_PREFIX=/usr/lib/llvm22/lib/clang/22/
|
|
'''
|
|
compile = 'cmake --build build'
|
|
install = '''
|
|
set -e
|
|
DESTDIR=/out cmake --install build
|
|
|
|
RES=/out/usr/lib/llvm22/lib/clang/22
|
|
# El `include/` del resource dir es del LAB (los headers de clang). Instalarlo desde acá lo taparía
|
|
# con una copia del tarball — la misma trampa que su hermana wasm documenta y evita.
|
|
rm -rf "$RES/include"
|
|
|
|
# ── GUARDIÁN 1: el fichero EXACTO que el enlazador pidió ─────────────────────────────────────
|
|
# No «alguna libclang_rt»: la ruta literal del error, porque el layout per-target es una opción de
|
|
# cmake y equivocarla deja la librería instalada donde clang no mira. Es el mismo fallo que la
|
|
# libstdc++ en /usr/lib64 de esta misma noche, un directorio más allá.
|
|
A="$RES/lib/x86_64-alpine-linux-musl/libclang_rt.profile.a"
|
|
test -s "$A" || {
|
|
echo "!! no está $A — ¿cambió el layout del resource dir?" >&2
|
|
find /out -name 'libclang_rt*' >&2
|
|
exit 1
|
|
}
|
|
echo "guardián: $A ($(stat -c%s "$A") bytes)"
|
|
|
|
# ── GUARDIÁN 2: LA PRUEBA DEL CONSUMIDOR ─────────────────────────────────────────────────────
|
|
# «Existe» no es «sirve». Se exige que DEFINA lo que un binario instrumentado va a buscar: la
|
|
# función que vuelca el `.profraw` y el contador de versión del formato. Si el `.a` sale vacío o
|
|
# con otro componente dentro, esto lo caza acá y no al final de una corrida de perfilado.
|
|
falta=""
|
|
for s in __llvm_profile_write_file __llvm_profile_get_version __llvm_profile_initialize_file; do
|
|
llvm-nm --defined-only "$A" 2>/dev/null | grep -qE " $s(@|$)" || falta="$falta $s"
|
|
done
|
|
test -z "$falta" || { echo "!! el .a no define:$falta" >&2; exit 1; }
|
|
echo "guardián: define los símbolos que emite -fprofile-generate"
|
|
'''
|