protobuf/abseil vuelven a zig: la causa raíz quita el escape a gcc — y lo valida en un segundo proyecto
Ayer estas dos huyeron a `compiler = "gcc"` para esquivar un crash del linker en los tres
`protoc-gen-upb*`. **Esquivé el fallo sin conocer su causa, y salió caro:** al mover sólo protobuf, el
link murió con `undefined reference to std::__1::basic_string<…>` —el `__1` de libc++— porque abseil
seguía en zig, así que hubo que arrastrar las dos fuera del toolchain por defecto.
La causa apareció al día siguiente en `dwarves`, bisecando la línea de enlace real:
tal cual → exit 139 (SIGSEGV)
quitando `-static` → exit 139 ⇒ no es el enlace estático
quitando `--dependency-file` → **exit 0** ⇒ ES ESO
El `lld` de zig 0.16.0 segfaultea con el `--dependency-file` que CMake ≥3.27 mete en la línea de
enlace. Con `-DCMAKE_LINK_DEPENDS_USE_LINKER=OFF` **los cuatro binarios de protobuf enlazan con zig**,
incluidos los tres plugins que se caían.
Esto es, además, la validación de la causa raíz en un proyecto INDEPENDIENTE de dwarves: dos
proyectos sin relación, mismo síntoma, misma perilla, los dos arreglados.
Con el escape se va también el `-static-libstdc++`, que sólo hacía falta porque g++ enlaza contra la
libstdc++ de GNU. Comprobado sobre el artefacto: el único NEEDED de `protoc` es `libc.so`, que provee
`musl-shared`.
Verificado de punta a punta, no por el código de salida: `protoc --version` → `libprotoc 36.1`, y un
`.proto` compila a `m.pb.h`/`m.pb.cc` **y** a `p/m.pb.go` pasando por `protoc-gen-go` — o sea que la
cadena plugin↔driver que abrí anteayer sigue entera. Las dos REPRODUCEN bit a bit.
Se deja escrito el camino completo en las recetas, diagnóstico corto incluido, porque la lección no
es la perilla: es que **un escape que funciona sin explicar el fallo se paga después**, y acá se pagó
con dos recetas fuera del toolchain por defecto y un choque de runtimes de C++ que sólo apareció
porque el escape era parcial.
This commit is contained in:
@@ -86,3 +86,5 @@ dwarves c77953627a7f2913ce6b617cb1baebd45f701c6130a440f525e94c5e453f3b0f 2026-09
|
||||
ia-modelo-embeddings 2c0c425833464e166b5bcb623d809018d68d14fab28320a303e2fb55e2b44714 2026-09-12 reproduce
|
||||
ia-modelo-chat 09cea3f0fce85afa1c26d4d7591058f5b019c34a8c961531218d76bad0ff19a3 2026-09-12 reproduce
|
||||
firefox-pgo-profile 3647c6be5f37b641620c93840eb86f4c8b7d655d2c1f5c67a97901337607c720 2026-09-12 reproduce
|
||||
abseil-cpp 8faf0d793ce7db5c36da139ce36564cb62b4e1e9dd033febdbe7e1f2810d3c89 2026-09-12 reproduce
|
||||
protobuf 3de99c8fa1387023468a4164ea936948e5d8ade94ce6bd98ad215efd66080519 2026-09-12 reproduce
|
||||
|
||||
|
+13
-6
@@ -22,9 +22,8 @@
|
||||
# targets de CMake, y protobuf puede compilarse con otro ⇒ dos mitades del mismo binario con
|
||||
# `std::string_view` distinto. Es la familia de las dos glib estáticas en un proceso, en C++.
|
||||
#
|
||||
# ⚠ **`compiler = "gcc"` NO ES UNA PREFERENCIA: ES EL CONTRATO CON PROTOBUF, Y SE DESCUBRIÓ
|
||||
# ROMPIÉNDOLO.** Con `zig-cc` esta receta sella perfecto —669 ficheros, 88 `.a`— y después protobuf
|
||||
# muere al enlazar con:
|
||||
# ⚠ **EL `compiler` DE ESTA RECETA Y EL DE PROTOBUF TIENEN QUE SER EL MISMO, Y SE DESCUBRIÓ
|
||||
# ROMPIÉNDOLO.** Con esta en `zig-cc` y protobuf en `gcc`, protobuf muere al enlazar con:
|
||||
#
|
||||
# undefined reference to `std::__1::basic_string<…>::assign(char const*, unsigned long)'
|
||||
#
|
||||
@@ -37,7 +36,15 @@
|
||||
# `-DABSL_PROPAGATE_CXX_STD=ON` cubre el OTRO eje del mismo problema —que el *estándar* (C++17) viaje
|
||||
# a los consumidores por los targets de CMake— pero no cubre éste: la *librería* no la propaga CMake,
|
||||
# la elige el compilador. Por eso la decisión vive en el campo `compiler` de las dos recetas, y
|
||||
# cambiar una sin la otra vuelve a romper.
|
||||
# **cambiar una sin la otra vuelve a romper**.
|
||||
#
|
||||
# **Las dos volvieron a `zig-cc` el 2026-09-12.** La huida a `gcc` fue para esquivar un crash del
|
||||
# linker de zig en los plugins `protoc-gen-upb*` de protobuf, esquivado SIN conocer la causa. La
|
||||
# causa apareció al día siguiente en `dwarves` y es otra: el `lld` de zig 0.16.0 **segfaultea con el
|
||||
# `--dependency-file` que CMake ≥3.27 mete en la línea de enlace**, y se apaga con
|
||||
# `-DCMAKE_LINK_DEPENDS_USE_LINKER=OFF`. Con la causa arreglada el escape sobra — y vale más quitarlo
|
||||
# que dejarlo: el toolchain por defecto del proyecto es zig, y cada `compiler = "gcc"` es una
|
||||
# excepción que alguien tiene que entender después.
|
||||
#
|
||||
# `CMAKE_INSTALL_LIBDIR=lib`: el lab usa `/usr/lib`, no `/usr/lib64`, o los `.cmake` y `.pc` quedan
|
||||
# donde nadie los busca.
|
||||
@@ -50,13 +57,13 @@ tarball = "https://github.com/abseil/abseil-cpp/archive/refs/tags/20250512.1.tar
|
||||
sha256 = "9b7a064305e9fd94d124ffa6cc358592eb42b5da588fb4e07d09254aa40086db"
|
||||
|
||||
[build]
|
||||
compiler = "gcc"
|
||||
compiler = "zig-cc"
|
||||
target = "x86_64-linux-musl"
|
||||
link = "static"
|
||||
flags = []
|
||||
|
||||
[build.phases]
|
||||
configure = "cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_CXX_STANDARD=17 -DABSL_PROPAGATE_CXX_STD=ON -DABSL_BUILD_TESTING=OFF"
|
||||
configure = "cmake -S . -B build -DCMAKE_LINK_DEPENDS_USE_LINKER=OFF -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_CXX_STANDARD=17 -DABSL_PROPAGATE_CXX_STD=ON -DABSL_BUILD_TESTING=OFF"
|
||||
compile = 'cmake --build build -j"$(nproc)"'
|
||||
install = "DESTDIR=/out cmake --install build"
|
||||
|
||||
|
||||
+28
-7
@@ -17,7 +17,7 @@
|
||||
# `-Dprotobuf_BUILD_TESTS=OFF`: la suite arrastra googletest, que es otra dep que no hace falta para
|
||||
# producir un `protoc`. `-Dprotobuf_BUILD_SHARED_LIBS=OFF` deja `protoc` monolítico salvo por la libc.
|
||||
#
|
||||
# ⚠ **`compiler = "gcc"` Y `-static-libstdc++`: DOS MUROS, Y EL SEGUNDO ESCONDÍA AL PRIMERO.**
|
||||
# ⚠ **`compiler = "zig-cc"` Y `-static-libstdc++`: DOS MUROS, Y EL SEGUNDO ESCONDÍA AL PRIMERO.**
|
||||
#
|
||||
# 1. **`zig c++` SE CAE AL ENLAZAR los tres plugins `protoc-gen-upb*`** — `Error running link
|
||||
# command: Segmentation fault`, no un error de símbolos. Se aisló FUERA de takana y fuera del
|
||||
@@ -35,10 +35,31 @@
|
||||
# Por eso `recipes/abseil-cpp.toml` también lleva `compiler = "gcc"`, y **cambiar una sin la otra
|
||||
# vuelve a romper**.
|
||||
#
|
||||
# `-static-libstdc++ -static-libgcc` en `CMAKE_EXE_LINKER_FLAGS` para que `protoc` no salga pidiendo
|
||||
# `libstdc++.so.6`, que es una soname que sólo vive en el LAB y que el corpus no publica — la familia
|
||||
# de [[needed-colgante-libstdcxx]]. Comprobado sobre el artefacto: el único NEEDED es `libc.so`, que
|
||||
# provee `musl-shared`.
|
||||
# ⚠⚠ **ACTUALIZACIÓN 2026-09-12: LA CAUSA ERA OTRA, Y LA RECETA VOLVIÓ A `zig-cc`.** Lo de arriba
|
||||
# describe lo que se midió el día 11 y sigue siendo cierto como SÍNTOMA, pero el diagnóstico se
|
||||
# quedó corto: el crash no es «zig no puede con estos plugins». Apareció otra vez en `dwarves` y ahí
|
||||
# se bisecó la línea de enlace real (`build/CMakeFiles/<target>.dir/link.txt`, rehecha a mano fuera
|
||||
# del sandbox):
|
||||
#
|
||||
# tal cual → exit 139 (SIGSEGV)
|
||||
# quitando `-static` → exit 139 ⇒ no es el enlace estático
|
||||
# quitando `--dependency-file` → **exit 0** ⇒ ES ESO
|
||||
#
|
||||
# `-Xlinker --dependency-file=…` lo emite CMake ≥3.27 y el `lld` de zig 0.16.0 segfaultea
|
||||
# procesándolo. Con `-DCMAKE_LINK_DEPENDS_USE_LINKER=OFF` los cuatro binarios enlazan con zig, así
|
||||
# que **el escape a gcc sobra** — y con él se va también el `-static-libstdc++`, que sólo hacía falta
|
||||
# porque g++ enlaza contra la libstdc++ de GNU. abseil vuelve a `zig-cc` en el mismo movimiento: el
|
||||
# runtime de C++ de las dos tiene que coincidir, y eso no cambió.
|
||||
#
|
||||
# Se deja escrito el camino entero, con el diagnóstico corto incluido, porque la lección no es la
|
||||
# perilla: es que **esquivar un fallo sin conocer su causa funciona y cuesta caro después** — dos
|
||||
# recetas fuera del toolchain por defecto y un choque de runtimes de C++ que apareció sólo porque el
|
||||
# escape era parcial.
|
||||
#
|
||||
# **Ya NO hace falta `-static-libstdc++`**: lo llevaba mientras la receta iba con `g++`, que enlaza
|
||||
# contra la libstdc++ de GNU y habría dejado a `protoc` pidiendo `libstdc++.so.6`, una soname que
|
||||
# sólo vive en el LAB ([[needed-colgante-libstdcxx]]). Con `zig-cc` la libc++ va estática de fábrica.
|
||||
# Comprobado sobre el artefacto: el único NEEDED de `protoc` es `libc.so`, que provee `musl-shared`.
|
||||
#
|
||||
# Lo que sale, verificado corriéndolo y no por el código de salida: `protoc` (13,3 M) más los tres
|
||||
# plugins de upb, y un `.proto` de prueba se compila a `.pb.h`/`.pb.cc` de verdad.
|
||||
@@ -58,13 +79,13 @@ tarball = "https://github.com/protocolbuffers/protobuf/releases/download/v36.1/p
|
||||
sha256 = "dc74fa582f559cbd31614ddfefb4868f43c919d7184bde514bb47f90c6025eb8"
|
||||
|
||||
[build]
|
||||
compiler = "gcc"
|
||||
compiler = "zig-cc"
|
||||
target = "x86_64-linux-musl"
|
||||
link = "dynamic"
|
||||
flags = []
|
||||
|
||||
[build.phases]
|
||||
configure = "cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17 -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_LOCAL_DEPENDENCIES_ONLY=ON -Dprotobuf_ABSL_PROVIDER=package -DCMAKE_EXE_LINKER_FLAGS='-static-libstdc++ -static-libgcc'"
|
||||
configure = "cmake -S . -B build -DCMAKE_LINK_DEPENDS_USE_LINKER=OFF -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17 -DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_SHARED_LIBS=OFF -Dprotobuf_LOCAL_DEPENDENCIES_ONLY=ON -Dprotobuf_ABSL_PROVIDER=package"
|
||||
compile = 'cmake --build build -j"$(nproc)"'
|
||||
install = "DESTDIR=/out cmake --install build"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user