tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1569Shell 203Rust 109Markdown 993728 Definiciones

Etapa G: gueto gcc para build-scripts de crates Rust con dep-C (frente sistematico)

La granja revelo una clase entera de fallos Rust: crates con dep-C cuyo build-script
(cc-rs) compila C con zig-cc, que lo RECHAZA/miscompila (delta=libgit2-sys,
gitui=openssl-sys, jless=libc-stdhandle). Mismo frente que file/jq en C puro -> misma
solucion: el GUETO gcc.

FIX (hammer-build/lib.rs, camino Cargo nativo): cuando la receta declara compiler="gcc",
cc-rs usa CC=gcc (el Alpine musl gcc del sandbox, probado en C) para compilar el C de
las deps; el LINKER sigue siendo el wrapper zig-cc. Los .o/.a de gcc-musl y el Rust
zig-musl son ABI-compatibles (ambos musl, mismo ELF x86-64). ADITIVO: una receta Rust
sin compiler= queda en ZigCc -> baseline (ripgrep/fd/...) intacto. 2 tests nuevos.

PROBADO END-TO-END: delta 0.19.2 construye+corre ELF estatico (libgit2-sys vendorea y
compila libgit2 desde decenas de .c con gcc; + dep zlib para -lz que libgit2/libz-sys
enlazan). Publicado al repo firmado (83 paquetes). Corpus 82->83.

LEVERAGE: libgit2-sys/openssl-sys/onig_sys/libc-stdhandle aparecen en CIENTOS de crates
-> el gueto gcc (+ resolver libs externas via deps.build) destraba esa clase entera, no
solo delta. jless queda staged (su feature de clipboard pide libxcb/X11, fuera de
alcance, NO toolchain). gitui (openssl-src vendoreado) deberia construir con el mismo
patron (compiler=gcc), pendiente de correr.

7c1a2ac8d547f3a87763c4669915f2a95535fba6 · por sergio · (hace 4 meses) · padre 70be258cc · ver el árbol en este commit

Delta semántico · 3

4 archivos · +76 −3

diff --git a/crates/hammer-build/src/lib.rs b/crates/hammer-build/src/lib.rs
index 4a39d7b8..e003d27f 100644
--- a/crates/hammer-build/src/lib.rs
+++ b/crates/hammer-build/src/lib.rs
@@ -539,6 +539,19 @@ fn resolve_phases(recipe: &Recipe, src: &Path) -> hammer_core::Result<Phases> {
                     // (i.e. un rust vanilla como el hammer-rust del frente self-host); para Alpine,
                     // omitirlo. RUSTFLAGS alcanza a todas las unidades; los `bin_flags` (cargo rustc
                     // --) sólo a la top.
+                    // CC para los build-scripts (cc-rs compila el C de deps como libgit2-sys,
+                    // openssl-sys, libc-stdhandle). Por defecto = el wrapper zig-cc. PERO zig-cc
+                    // MISCOMPILA/RECHAZA muchos de esos C (mismo frente que file/jq en C puro: la
+                    // granja lo reveló — delta/gitui/jless mueren ahí). Con `compiler="gcc"` la receta
+                    // declara el GUETO: cc-rs usa gcc (el Alpine musl gcc del sandbox, probado en C),
+                    // y el linker sigue siendo zig-cc — los .o/.a de gcc-musl y el Rust zig-musl son
+                    // ABI-compatibles (ambos musl, mismo ELF x86-64). Aditivo: una receta Rust sin
+                    // `compiler=` queda en ZigCc ⇒ baseline (ripgrep/fd/…) intacto.
+                    let cc_for_scripts = match recipe.build.compiler {
+                        Compiler::Gcc => "gcc",
+                        Compiler::Clang => "clang",
+                        Compiler::ZigCc => "$PWD/.hammer-zig-cc",
+                    };
                     Some(format!(
                         "printf '%s\\n' '#!/bin/sh' 'for a do' \
                          'case \"$a\" in --target=*) a=--target=x86_64-linux-musl ;; esac' \
@@ -546,7 +559,7 @@ fn resolve_phases(recipe: &Recipe, src: &Path) -> hammer_core::Result<Phases> {
                          > \"$PWD/.hammer-zig-cc\" && chmod +x \"$PWD/.hammer-zig-cc\" && \
                          RF=\"-C linker=$PWD/.hammer-zig-cc\"; \
                          rustc -vV | grep -q 'host: .*-alpine-' || RF=\"$RF -C link-self-contained=no\"; \
-                         CC=\"$PWD/.hammer-zig-cc\" RUSTFLAGS=\"$RF\" \
+                         CC=\"{cc_for_scripts}\" RUSTFLAGS=\"$RF\" \
                          cargo rustc --release --locked --offline{flags_suffix} -- {bin_flags}"
                     ))
                 } else {
@@ -728,6 +741,32 @@ commit = "deadbeef"
         assert!(i.contains("find target/release"), "nativo instala de target/release ({i})");
     }
 
+    #[test]
+    fn cargo_gcc_ghetto_uses_gcc_for_build_scripts() {
+        // Receta Rust con `compiler="gcc"`: el GUETO para crates con dep-C (libgit2-sys/openssl-sys/
+        // libc-stdhandle) que zig-cc rechaza. cc-rs debe usar gcc (CC=gcc), pero el LINKER sigue
+        // siendo el wrapper zig-cc (objetos gcc-musl + Rust zig-musl son ABI-compatibles).
+        let d = tempfile::tempdir().unwrap();
+        touch(d.path(), "Cargo.toml");
+        let mut r = recipe(&[]);
+        r.build.compiler = Compiler::Gcc;
+        let c = resolve_phases(&r, d.path()).unwrap().compile.unwrap();
+        assert!(c.contains("CC=\"gcc\""), "cc-rs usa gcc en el gueto ({c})");
+        assert!(!c.contains("CC=\"$PWD/.hammer-zig-cc\""), "CC ya no es el wrapper ({c})");
+        // El linker NO cambia: sigue el wrapper zig-cc.
+        assert!(c.contains("RF=\"-C linker=$PWD/.hammer-zig-cc"), "linker sigue zig-cc ({c})");
+        assert!(c.contains("cargo rustc --release"), "sigue el camino cargo nativo ({c})");
+    }
+
+    #[test]
+    fn cargo_default_compiler_keeps_zig_cc_for_build_scripts() {
+        // Sin `compiler=` (default ZigCc): CC sigue siendo el wrapper — baseline ripgrep/fd intacto.
+        let d = tempfile::tempdir().unwrap();
+        touch(d.path(), "Cargo.toml");
+        let c = resolve_phases(&recipe(&[]), d.path()).unwrap().compile.unwrap();
+        assert!(c.contains("CC=\"$PWD/.hammer-zig-cc\""), "default: cc-rs usa el wrapper zig ({c})");
+    }
+
     #[test]
     fn cargo_cross_target_keeps_triple() {
         // Un target NO nativo (cross real) sí pasa --target + el linker per-triple.
diff --git a/recipes/delta.toml b/recipes/delta.toml
new file mode 100644
index 00000000..09a9469f
--- /dev/null
+++ b/recipes/delta.toml
@@ -0,0 +1,29 @@
+# Importada de nixpkgs por `hammer import-nix` (Etapa G). PUNTO DE PARTIDA, no final:
+# - el build usa el lab de hammer (zig-cc / musl estático), NO el stdenv de nix ⇒ revisá
+#   compiler/link/phases y adaptá hasta que compile.
+# - las deps van con su nombre NIX; remapealas a las recetas del corpus si difieren.
+name    = "delta"
+version = "0.19.2"
+
+[source]
+repo   = "https://github.com/dandavison/delta"
+commit = "1502986e81c8e3fa27bfb5b84bac6b281a6b1edd"
+
+# GUETO gcc para los build-scripts: delta trae `libgit2-sys`, que vendorea y COMPILA libgit2 desde
+# C (decenas de .c). zig-cc los rechaza (la granja lo reveló: ToolExecError en apply.c/attr_file.c/…).
+# `compiler="gcc"` ⇒ cc-rs compila ese C con el Alpine musl gcc (probado en C); el linker sigue zig-cc.
+[build]
+compiler = "gcc"
+target   = "x86_64-linux-musl"
+link     = "static"
+flags    = ["--bin", "delta"]
+
+[build.phases]
+install = "mkdir -p /out/usr/bin && cp target/release/delta /out/usr/bin/delta"
+
+# libgit2-sys y libz-sys enlazan `-lz`; el lab materializa zlib (libz.a en /usr/lib) como capa overlay.
+[deps]
+build = ["zlib"]
+
+# buildInputs de nix (NO deps de hammer — cargo vendorea; backend Rust por
+# defecto). Si algún sys-crate C falla, adaptá per-paquete (patch/feature): git, oniguruma
diff --git a/recipes/incoming/gitui.toml b/recipes/incoming/gitui.toml
index 8a50563a..4d8ebe0a 100644
--- a/recipes/incoming/gitui.toml
+++ b/recipes/incoming/gitui.toml
@@ -9,8 +9,10 @@ version = "0.28.1"
 repo   = "https://github.com/gitui-org/gitui"
 commit = "e24fb45df1584ee8d8ebdc4258531b4a91ca975d"
 
+# GUETO gcc para build-scripts: gitui trae openssl-src (vendorea+compila openssl 3.4 desde C) +
+# libgit2-sys; zig-cc los rechaza. compiler="gcc" -> cc-rs usa el Alpine musl gcc; linker zig-cc.
 [build]
-compiler = "zig-cc"
+compiler = "gcc"
 target   = "x86_64-linux-musl"
 link     = "static"
 flags    = ["--bin", "gitui"]
diff --git a/recipes/incoming/jless.toml b/recipes/incoming/jless.toml
index 728e33d5..d79198a7 100644
--- a/recipes/incoming/jless.toml
+++ b/recipes/incoming/jless.toml
@@ -9,8 +9,11 @@ version = "0.9.0"
 repo   = "https://github.com/PaulJuliusMartinez/jless"
 commit = "21dd6100edb47145bb9570931bec29697bcd0d9b"
 
+# GUETO gcc para los build-scripts: jless trae `libc-stdhandle` (un sys-crate con un imp.c que
+# cc-rs compila); zig-cc lo rechaza (mismo frente que file/jq en C puro). `compiler="gcc"` ⇒ cc-rs
+# usa el Alpine musl gcc para ese C; el linker sigue zig-cc (ABI musl compatible).
 [build]
-compiler = "zig-cc"
+compiler = "gcc"
 target   = "x86_64-linux-musl"
 link     = "static"
 flags    = ["--bin", "jless"]