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.
This commit is contained in:
@@ -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,
|
// (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
|
// omitirlo. RUSTFLAGS alcanza a todas las unidades; los `bin_flags` (cargo rustc
|
||||||
// --) sólo a la top.
|
// --) 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!(
|
Some(format!(
|
||||||
"printf '%s\\n' '#!/bin/sh' 'for a do' \
|
"printf '%s\\n' '#!/bin/sh' 'for a do' \
|
||||||
'case \"$a\" in --target=*) a=--target=x86_64-linux-musl ;; esac' \
|
'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\" && \
|
> \"$PWD/.hammer-zig-cc\" && chmod +x \"$PWD/.hammer-zig-cc\" && \
|
||||||
RF=\"-C linker=$PWD/.hammer-zig-cc\"; \
|
RF=\"-C linker=$PWD/.hammer-zig-cc\"; \
|
||||||
rustc -vV | grep -q 'host: .*-alpine-' || RF=\"$RF -C link-self-contained=no\"; \
|
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}"
|
cargo rustc --release --locked --offline{flags_suffix} -- {bin_flags}"
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
@@ -728,6 +741,32 @@ commit = "deadbeef"
|
|||||||
assert!(i.contains("find target/release"), "nativo instala de target/release ({i})");
|
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]
|
#[test]
|
||||||
fn cargo_cross_target_keeps_triple() {
|
fn cargo_cross_target_keeps_triple() {
|
||||||
// Un target NO nativo (cross real) sí pasa --target + el linker per-triple.
|
// Un target NO nativo (cross real) sí pasa --target + el linker per-triple.
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -9,8 +9,10 @@ version = "0.28.1"
|
|||||||
repo = "https://github.com/gitui-org/gitui"
|
repo = "https://github.com/gitui-org/gitui"
|
||||||
commit = "e24fb45df1584ee8d8ebdc4258531b4a91ca975d"
|
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]
|
[build]
|
||||||
compiler = "zig-cc"
|
compiler = "gcc"
|
||||||
target = "x86_64-linux-musl"
|
target = "x86_64-linux-musl"
|
||||||
link = "static"
|
link = "static"
|
||||||
flags = ["--bin", "gitui"]
|
flags = ["--bin", "gitui"]
|
||||||
|
|||||||
@@ -9,8 +9,11 @@ version = "0.9.0"
|
|||||||
repo = "https://github.com/PaulJuliusMartinez/jless"
|
repo = "https://github.com/PaulJuliusMartinez/jless"
|
||||||
commit = "21dd6100edb47145bb9570931bec29697bcd0d9b"
|
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]
|
[build]
|
||||||
compiler = "zig-cc"
|
compiler = "gcc"
|
||||||
target = "x86_64-linux-musl"
|
target = "x86_64-linux-musl"
|
||||||
link = "static"
|
link = "static"
|
||||||
flags = ["--bin", "jless"]
|
flags = ["--bin", "jless"]
|
||||||
|
|||||||
Reference in New Issue
Block a user