gnome: los 7 typelibs CERRADOS — librsvg y ibus, y dos deudas viejas pagadas de paso
Rsvg-2.0 librsvg b3:351f4658 IBus-1.0 ibus b3:d4d3750a **1. PERILLA NUEVA DEL LAB: `[source] cargo_vendor`.** `detect_build_system` asume UN sistema de build por árbol, y librsvg genuinamente tiene dos: `configure.ac` gana por precedencia pero su Makefile llama a `cargo build`, que dentro del sandbox hermético no tiene red. La perilla fuerza el vendoreo (que ocurre en el fetch, donde sí hay red) sin tocar la detección. **No entra al ArtifactHash** —decide de dónde salen las deps, no cuáles: eso lo fija el Cargo.lock, ya bajo el sha256 de la fuente— así que se puede prender en una receta ya sellada sin re-hashear nada. Con test, y verificado en vivo: libelogind no movió su hash tras el cambio. **2. LA DEUDA DEL UNWINDER, PAGADA.** librsvg moría en `undefined reference: _Unwind_DeleteException`. No es de librsvg: es de la `std` de rustc, que trae landing pads y espera el runtime que en glibc vive en libgcc_s. Es la deuda que el corpus arrastra desde matar-gcc —«las 12 recetas Rust son UN problema, no 12»— y el remedio estaba a mano: **zig empaqueta la libunwind de LLVM** y exporta los `_Unwind_*` (verificado con nm). Alcanza `LIBS=-lunwind`. Va por LIBS y no por LDFLAGS porque autotools pone LIBS al FINAL de la línea de enlace, que es donde tiene que ir una librería que resuelve símbolos indefinidos. librsvg va en 2.58.5 y no 2.59+: en 2.59 cambió a meson + cargo-c, y cargo-cbuild enlaza el crate `cargo` entero (libgit2, libssh2, libcurl, openssl) — una campaña propia por un binario que sólo corre en el constructor. 2.58.5 produce el mismo Rsvg-2.0. Mismo criterio que gnome-desktop 44.5. **3. `x11-compose-data`, y es una tensión que vale la pena tener escrita.** ibus COMPILA la tabla de teclas muertas de X11 dentro de libibus (Makefile.am:310, incondicional, sin `--disable-`). Sin datos no construye. Los datos viven en el tarball de libX11 por historia, no por necesidad técnica: son 5192 líneas de reglas. La receta extrae SÓLO los ficheros de locale reproduciendo la regla de upstream (`cpprules.in`: cpp crudo + CPP_SED_MAGIC literal) y no compila una línea de X11. Un escritorio Wayland-only sigue necesitando la tabla de composición del mundo Unix. Gotchas de ibus, los tres medidos: su ayuda MIENTE (`--enable-gtk4`/`--enable-wayland` sugieren default apagado; el default es `yes`); `--disable-emoji-dict` NO apaga `--disable-unicode-dict`; y con `--disable-wayland` el build muere igual porque `tools/main.c` llama wl_display_* sin `#ifdef` mientras WAYLAND_LIBS sólo se agrega si la opción está prendida — bug de upstream en su propia configuración sin Wayland. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -220,7 +220,13 @@ pub fn build(
|
||||
|
||||
// Recetas Cargo: vendoreamos las deps (red permitida en el fetch) para que el build sea
|
||||
// hermético `--offline` dentro del sandbox. Tras los patches, por si tocaron Cargo.toml/lock.
|
||||
if matches!(detect_build_system(&src_tree), BuildSys::Cargo) {
|
||||
// `cargo_vendor = true` fuerza esta rama en árboles POLÍGLOTAS, donde `detect_build_system`
|
||||
// —que asume un sistema por árbol— eligió el de C. librsvg es el arquetipo: `configure.ac` gana
|
||||
// por precedencia, pero su Makefile llama a `cargo build`, y sin vendoreo ese cargo sale a la
|
||||
// red dentro del sandbox hermético. Ver `Source::cargo_vendor`.
|
||||
if matches!(detect_build_system(&src_tree), BuildSys::Cargo)
|
||||
|| eff_recipe.source.cargo_vendor == Some(true)
|
||||
{
|
||||
// El source se copia DENTRO del repo hammer (que es un workspace Cargo) ⇒ si el Cargo.toml
|
||||
// de la fuente NO declara su propio `[workspace]`, cargo cree que pertenece al workspace de
|
||||
// hammer y `cargo vendor` aborta. Inyectamos un `[workspace]` vacío para aislarla. SÓLO si
|
||||
@@ -229,7 +235,13 @@ pub fn build(
|
||||
// por receta. Ver memoria 'cargo-recipe crate suelto'.
|
||||
ensure_cargo_workspace_isolation(&src_tree)?;
|
||||
// Extractor de workspaces (Etapa G): si el root es virtual, resuelve `-p <pkg>` del bin.
|
||||
inject_cargo_package_selector(&mut eff_recipe, &src_tree);
|
||||
// SÓLO cuando el árbol ES una receta Cargo. En un políglota (`cargo_vendor = true`) el
|
||||
// producto lo arma el sistema de build de C —que llama a cargo con sus propios argumentos—
|
||||
// y meterle un `-p` a los flags de la receta sería inyectar una opción de Cargo en un
|
||||
// `./configure`. Acá el forzado pide vendoreo, nada más.
|
||||
if matches!(detect_build_system(&src_tree), BuildSys::Cargo) {
|
||||
inject_cargo_package_selector(&mut eff_recipe, &src_tree);
|
||||
}
|
||||
tracing::info!("cargo: vendoreando deps para build offline");
|
||||
fetch::vendor_cargo_deps(
|
||||
&src_tree,
|
||||
|
||||
@@ -66,6 +66,19 @@ pub struct Source {
|
||||
/// `.cargo/config.toml` que emite `cargo vendor` ya apunta al dir que se le pasa.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub cargo_vendor_dir: Option<String>,
|
||||
/// Fuerza el vendoreo cargo aunque el árbol NO se detecte como `BuildSys::Cargo`.
|
||||
///
|
||||
/// Existe porque `detect_build_system` asume **un** sistema de build por árbol, y hay proyectos
|
||||
/// que genuinamente tienen dos: C por fuera, Rust por dentro. El arquetipo es librsvg —trae
|
||||
/// `configure.ac` Y `Cargo.toml`, y autotools gana por precedencia—, pero su `Makefile` invoca
|
||||
/// `cargo build`. Sin vendoreo ese cargo intenta salir a la red DENTRO del sandbox hermético y
|
||||
/// el build muere. Es un patrón, no una excepción: cada vez hay más GNOME así.
|
||||
///
|
||||
/// No cambia qué se construye, sólo de dónde salen las deps —el `Cargo.lock` del source es el
|
||||
/// que fija las versiones— así que **no entra al ArtifactHash**, igual que `cargo_vendor_dir`.
|
||||
/// Es lo que permite prenderla en una receta ya sellada sin re-hashearla.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub cargo_vendor: Option<bool>,
|
||||
#[serde(default)]
|
||||
pub patches: Vec<String>,
|
||||
}
|
||||
@@ -732,6 +745,34 @@ expected_output = "b3:deadbeef"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cargo_vendor_roundtripea_y_no_afecta_el_hash() {
|
||||
// `cargo_vendor` decide DE DÓNDE salen las deps de Cargo (registro vs. `vendor/` local), no
|
||||
// CUÁLES: eso lo fija el `Cargo.lock` del source, que ya está bajo el hash de la fuente. Por
|
||||
// eso no entra a `hash_inputs`, igual que `cargo_vendor_dir` — y por eso se puede prender en
|
||||
// una receta YA SELLADA para destrabar su build offline sin re-hashear nada aguas abajo.
|
||||
let sin = Recipe::from_toml(SAMPLE).unwrap();
|
||||
let mut con = sin.clone();
|
||||
con.source.cargo_vendor = Some(true);
|
||||
assert_eq!(
|
||||
sin.hash_inputs(&[]).unwrap(),
|
||||
con.hash_inputs(&[]).unwrap(),
|
||||
"cargo_vendor NO debe entrar en hash_inputs"
|
||||
);
|
||||
// Y roundtripea por TOML: si se perdiera al serializar, el forzado se apagaría solo en
|
||||
// cualquier flujo que reescriba la receta.
|
||||
let r = Recipe::from_toml(&con.to_toml().unwrap()).unwrap();
|
||||
assert_eq!(r.source.cargo_vendor, Some(true));
|
||||
// Ausente sigue siendo ausente (no `Some(false)`), que es lo que mantiene el TOML limpio.
|
||||
assert_eq!(
|
||||
Recipe::from_toml(&sin.to_toml().unwrap())
|
||||
.unwrap()
|
||||
.source
|
||||
.cargo_vendor,
|
||||
None
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slots_round_trip_y_no_afectan_el_hash() {
|
||||
// H4b: el bloque `slots` declara TOPOLOGÍA (qué toca / de qué depende), no identidad ⇒
|
||||
|
||||
Reference in New Issue
Block a user