`recipes/protoc-gen-go.toml` estaba SELLADO y era INERTE: un plugin de protoc no hace nada sin `protoc`, y `protoc` no estaba en el catálogo. Cualquier servicio gRPC lo necesita en tiempo de build — empezando por `qdrant`, que el censo del servidor de origen encontró corriendo como binario suelto, de los que se pierden al apagar la máquina vieja. Entran dos recetas: `abseil-cpp` (que protobuf exige) y `protobuf`. Verificado corriéndolo, no por el código de salida: `protoc --version` contesta `libprotoc 36.1`, y un `.proto` de prueba se compila a `.pb.h`/`.pb.cc` reales. Único NEEDED `libc.so`, que provee `musl-shared`. Las dos REPRODUCEN bit a bit. **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` — un crash del linker, no un error de símbolos. Se aisló FUERA de takana y fuera del sandbox, rehaciendo el link a mano sobre los mismos `.o` y las mismas `.a`: `zig c++` vuelve a segfaultear. No es presión de memoria (corrió solo) y no es el `-Wl,-rpath,::::::::::::::` que CMake emite — se probó sin él y cae igual. `protobuf_BUILD_LIBUPB=OFF` tampoco es escapatoria: queda `OFF` en el `CMakeCache` y los plugins se construyen igual. Con `g++` y el `ld` de GNU los cuatro binarios enlazan. 2. Al pasar **sólo** protobuf a `gcc`, con abseil todavía construida por `zig-cc`, el link murió con `undefined reference to std::__1::basic_string<…>::assign(char const*, unsigned long)`. **El `__1` es el namespace inline de libc++** —la libstdc++ que trae zig— y g++ usa la de GNU, con otro mangling para los mismos tipos. O sea: **abseil y protobuf tienen que compartir runtime de C++ o no enlazan**, y el error habla de `std::string` sin nombrar a abseil ni una vez. Es la familia de las dos glib estáticas en un proceso, pero en C++ y en tiempo de link. ⇒ Las dos recetas llevan `compiler = "gcc"` y está escrito en ambas que cambiar una sin la otra vuelve a romper. `-static-libstdc++ -static-libgcc` para que `protoc` no salga pidiendo una soname que sólo vive en el lab. Y una decisión que NO es «la última versión»: abseil va pineada a `20250512.1` porque es exactamente la que protobuf 36.1 declara en `cmake/dependencies.cmake`. Abseil no promete ABI estable entre releases; el disparador para subirla es que protobuf suba la suya, no que abseil publique.
73 lines
4.7 KiB
TOML
73 lines
4.7 KiB
TOML
# protobuf 36.1 — **`protoc`**, el compilador de `.proto`. Es el hueco que se ve solo al mirar el
|
|
# catálogo: `recipes/protoc-gen-go.toml` está SELLADO y es **inerte**, porque un plugin de protoc no
|
|
# hace nada sin protoc; y cualquier servicio gRPC necesita `protoc` en tiempo de build — empezando
|
|
# por `qdrant`, que el censo del servidor de origen encontró corriendo como binario suelto (de los
|
|
# que se pierden al apagar la máquina vieja) y cuyo `build.rs` lo invoca vía prost/tonic.
|
|
#
|
|
# **La dep de abseil no se vendoriza ni se descarga: se declara.** El tarball de release de protobuf
|
|
# NO trae abseil adentro (comprobado: cero entradas bajo `third_party/abseil-cpp/`), y su
|
|
# `cmake/abseil-cpp.cmake` tiene un fallback que hace `FetchContent` desde GitHub. Ese fallback en
|
|
# este lab es una trampa doble: el sandbox está OFFLINE, así que fallaría igual — pero fallaría
|
|
# hablando de red y no de dependencias — y si algún día no estuviera offline, metería una fuente sin
|
|
# pinear en un build que se supone reproducible. `protobuf_LOCAL_DEPENDENCIES_ONLY=ON` apaga el
|
|
# fallback ⇒ si abseil no está, el error dice *«Cannot find abseil-cpp dependency»*, que es lo que
|
|
# uno necesita leer. `recipes/abseil-cpp.toml` está pineada a la versión exacta que este protobuf
|
|
# declara.
|
|
#
|
|
# `-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.**
|
|
#
|
|
# 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
|
|
# sandbox: rehaciendo a mano el link de `protoc-gen-upb` con el `zig` del lab, sobre los mismos
|
|
# `.o` y las mismas `.a`, `zig c++` vuelve a segfaultear. No es presión de memoria (corrió solo) y
|
|
# no es el `-Wl,-rpath,::::::::::::::` que CMake emite —se probó sin él y cae igual—. Con `g++` y
|
|
# el `ld` de GNU los cuatro binarios enlazan. `protobuf_BUILD_LIBUPB=OFF` **no** es escapatoria:
|
|
# se probó, queda `OFF` en el `CMakeCache` y los plugins se construyen igual.
|
|
#
|
|
# 2. **abseil y protobuf TIENEN QUE COMPARTIR RUNTIME DE C++.** Al pasar sólo protobuf a `gcc`, con
|
|
# abseil todavía construida por `zig-cc`, el link murió con
|
|
# `undefined reference to std::__1::basic_string<…>::assign(char const*, unsigned long)`. El `__1`
|
|
# es el namespace inline de **libc++** (la que trae zig); g++ usa **libstdc++ de GNU**, con otro
|
|
# mangling para los mismos tipos. El error habla de `std::string` y no nombra a abseil ni una vez.
|
|
# 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`.
|
|
#
|
|
# 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.
|
|
#
|
|
# `CMAKE_INSTALL_LIBDIR=lib` por lo de siempre: el lab usa `/usr/lib`, no `/usr/lib64`, o los `.pc` y
|
|
# los `.cmake` quedan donde ningún consumidor los busca.
|
|
#
|
|
# ⚠ **La versión de protobuf ES contrato de generación, no sólo de API.** `protoc` decide qué código
|
|
# emite, y el `.pb.cc`/`.pb.go` generado tiene que casar con la librería runtime que el consumidor
|
|
# enlace. Subirla no es actualizar una herramienta: es mover el formato de lo que sale.
|
|
name = "protobuf"
|
|
version = "36.1"
|
|
license = "BSD-3-Clause"
|
|
|
|
[source]
|
|
tarball = "https://github.com/protocolbuffers/protobuf/releases/download/v36.1/protobuf-36.1.tar.gz"
|
|
sha256 = "dc74fa582f559cbd31614ddfefb4868f43c919d7184bde514bb47f90c6025eb8"
|
|
|
|
[build]
|
|
compiler = "gcc"
|
|
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'"
|
|
compile = 'cmake --build build -j"$(nproc)"'
|
|
install = "DESTDIR=/out cmake --install build"
|
|
|
|
[deps]
|
|
build = ["binutils", "busybox", "make", "cmake", "abseil-cpp", "zlib"]
|