gcc-libs enviaba un ld script que pedía una librería que nadie tenía
`/usr/lib/libgcc_s.so` no es una librería: es un ld script —`GROUP ( libgcc_s.so.1 -lgcc )`— y ese `-lgcc` es libgcc.a, que ninguna receta del corpus proveía. Esta misma la borraba: el `find -name '*.a' -delete` de la poda, y de paso el `rm -rf /usr/lib/gcc` se llevaba el original. Medido en la caja con el rust recién sellado: los binarios estáticos compilan y corren, pero cualquier dylib —y eso incluye TODAS las proc-macros— muere con `unable to find library -lgcc`. O sea `cargo build` con `derive` imposible sobre takana, con el compilador perfecto. Y no alcanza con dar `-L /usr/lib`: con eso se resuelven `-lc` y `-lgcc_s`, y entonces aparece justo este `-lgcc`. Es la misma familia que el hueco que originó esta receta —todo presente, todo reproducible, y el camino que hace falta no existe—, sólo que del lado del ENLACE en vez del arranque. libgcc.a se copia a /usr/lib (donde el -L del enlazador ya mira; el gcc completo no está en esta distro) y se salva de la poda. Y entra un GUARDIÁN 3 que compara lo que el ld script PIDE contra lo que el artefacto TRAE: si vuelve a quedarse sin libgcc.a, corta. Radio medido con yupana antes de tocar: 7 dependientes directos, 9 transitivos, 7 imágenes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
1 qillqakuna · +38 −3
- recipes/gcc-libs.toml +38 −3
diff --git a/recipes/gcc-libs.toml b/recipes/gcc-libs.toml
index 29294c40..30e43e45 100644
--- a/recipes/gcc-libs.toml
+++ b/recipes/gcc-libs.toml
@@ -119,13 +119,37 @@ if [ -d /out/usr/lib64 ]; then
rm -rf /out/usr/lib64
fi
-# Se PODA todo lo que no sea runtime: headers, `.a`, `.la`, libsupc++, los `.py` del pretty-printer.
-# Esta receta existe para que un binario ARRANQUE, no para compilar contra ella; dejar los headers
+# ── libgcc.a SE SALVA DE LA PODA, Y ES UNA CORRECCIÓN (2026-09-17) ───────────────────────────
+# `/usr/lib/libgcc_s.so` que esta receta instala **no es una librería: es un ld script**
+#
+# GROUP ( libgcc_s.so.1 -lgcc )
+#
+# y ese `-lgcc` es `libgcc.a`, que NINGUNA receta del corpus proveía —ésta la borraba con el
+# `find -name '*.a' -delete` de acá abajo, y de paso `rm -rf /usr/lib/gcc` se llevaba el original—.
+# Consecuencia medida en la caja de producción con el `rust` recién sellado: los binarios ESTÁTICOS
+# compilan y corren, pero **cualquier dylib —y eso incluye TODAS las proc-macros— muere**:
+#
+# ld.lld: error: unable to find library -lgcc
+#
+# O sea `cargo build` con `derive` (serde, clap…) imposible sobre takana, con el compilador perfecto.
+# Es la misma familia que el hueco que originó esta receta: todo presente, todo reproducible, y el
+# camino que hace falta no existe. Y no alcanza con dar `-L /usr/lib`: con eso se resuelven `-lc` y
+# `-lgcc_s`, y entonces aparece justo este `-lgcc`.
+#
+# Va a `/usr/lib` —no al directorio privado de gcc— porque es donde el `-L` del enlazador ya mira, y
+# porque el gcc completo no está en esta distro: acá la librería tiene que valerse sola.
+A=$(find /out -name libgcc.a | head -1)
+test -n "$A" || { echo "!! el install no dejó ninguna libgcc.a — sin ella el ld script de libgcc_s miente" >&2; exit 1; }
+cp "$A" /out/usr/lib/libgcc.a
+
+# Se PODA todo lo que no sea runtime: headers, el resto de los `.a`, `.la`, libsupc++, los `.py` del
+# pretty-printer. Esta receta existe para que un binario ARRANQUE —y ahora también para que el
+# `libgcc_s.so` que envía sea ENLAZABLE—, no para compilar C++ contra ella; dejar los headers
# invitaría a que otra receta se enlace contra esto en vez de contra el lab, que es una decisión
# distinta y no la que se está tomando acá.
find /out -name '*.la' -delete
rm -rf /out/usr/include /out/usr/share /out/usr/lib/gcc
-find /out -name '*.a' -delete
+find /out -name '*.a' ! -name 'libgcc.a' -delete
find /out -name '*.py' -delete
L=/out/usr/lib
@@ -166,4 +190,15 @@ test -z "$falta" || {
exit 1
}
echo "guardián: los 6 símbolos que firefox no encontraba están DEFINIDOS"
+
+# ── GUARDIÁN 3: EL LD SCRIPT NO PUEDE MENTIR ─────────────────────────────────────────────────
+# `libgcc_s.so` es un ld script que manda buscar `-lgcc`. Si esa librería no viaja con él, el
+# artefacto sella, reproduce, y la primera dylib que alguien enlace en una caja takana muere. Se
+# comprueba lo que el script PIDE contra lo que el artefacto TRAE, no la intención.
+if grep -q "GROUP" "$L/libgcc_s.so" 2>/dev/null; then
+ grep -q -- "-lgcc" "$L/libgcc_s.so" && test -f "$L/libgcc.a" || {
+ echo "!! $L/libgcc_s.so es un ld script que pide -lgcc y no hay libgcc.a al lado" >&2
+ cat "$L/libgcc_s.so" >&2; exit 1; }
+ echo "guardián: el ld script pide -lgcc y libgcc.a viaja con él ($(stat -Lc%s "$L/libgcc.a") bytes)"
+fi
'''