Etapa G Fase 3: flags autotools $CBUILD/$CHOST — el lab provee el triple nativo
El residuo autotools de los imports de Alpine (configure --build=$CBUILD --host=$CHOST del abuild) ya no es trabajo a mano: - El lab exporta CBUILD/CHOST con el triple nativo SANEADO (x86_64-linux-musl, el mismo que el wrapper zig-cc emite) ⇒ las fases traducidas de Alpine que referencian $CBUILD/$CHOST literal resuelven en runtime en vez de quedar vacías (config.guess detectaría x86_64-alpine-linux-musl, vendor que zig rechaza). - La heurística autotools inyecta --build/--host al triple saneado cuando la receta no los puso ya (juicio per-paquete gana). build==host ⇒ NATIVO: autotools sigue corriendo sus AC_RUN tests; sólo normaliza el triple. - Inerte para Cargo/CMake/Meson (no leen esas envs ni el triple). VALIDADO REAL: e2e autotools BUILDEA (configure 'cross compiling... no', sella+corre). 3 tests nuevos de heurística + import comment actualizado. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -217,6 +217,15 @@ pub fn build(
|
||||
env.push(("AR".into(), "llvm-ar".into()));
|
||||
}
|
||||
}
|
||||
// Autotools (Etapa G Fase 3): exporta CBUILD/CHOST con el triple nativo SANEADO del sandbox
|
||||
// (`x86_64-linux-musl`, el mismo que el wrapper zig-cc emite). Las recetas importadas de Alpine
|
||||
// traducen `./configure --build=$CBUILD --host=$CHOST` literal del abuild (`translate_abuild` los
|
||||
// deja intactos a propósito); sin estas envs `$CBUILD/$CHOST` quedan VACÍAS y autotools cae a
|
||||
// `config.guess`, que detecta `x86_64-alpine-linux-musl` — vendor que zig NO conoce
|
||||
// (`UnknownOperatingSystem`). Resuelve el residuo autotools que antes era trabajo a mano. Inerte
|
||||
// para Cargo/CMake/Meson (no leen estas envs).
|
||||
env.push(("CBUILD".into(), SANDBOX_NATIVE_TARGET.to_string()));
|
||||
env.push(("CHOST".into(), SANDBOX_NATIVE_TARGET.to_string()));
|
||||
if let Some(cache) = &cfg.cache_root {
|
||||
std::fs::create_dir_all(cache.join("zig"))?;
|
||||
}
|
||||
@@ -450,12 +459,26 @@ fn resolve_phases(recipe: &Recipe, src: &Path) -> hammer_core::Result<Phases> {
|
||||
let flags = recipe.build.flags.join(" ");
|
||||
let flags_suffix = if flags.is_empty() { String::new() } else { format!(" {flags}") };
|
||||
|
||||
// Autotools (Etapa G Fase 3): fija `--build`/`--host` al triple nativo saneado para que
|
||||
// `config.guess` no detecte el vendor `alpine` que zig rechaza, e iguala lo que el wrapper zig-cc
|
||||
// produce. Sólo si la receta no los puso ya en sus flags (juicio per-paquete gana). build==host
|
||||
// ⇒ NATIVO (no cross): autotools sigue corriendo sus AC_RUN tests; sólo normaliza el triple.
|
||||
let autotools_triple = if recipe.build.flags.iter().any(|f| {
|
||||
f.starts_with("--build=") || f.starts_with("--host=")
|
||||
}) {
|
||||
String::new()
|
||||
} else {
|
||||
format!(" --build={SANDBOX_NATIVE_TARGET} --host={SANDBOX_NATIVE_TARGET}")
|
||||
};
|
||||
|
||||
if out.configure.is_none() {
|
||||
out.configure = match bs {
|
||||
BuildSys::AutoconfRaw => Some(format!(
|
||||
"autoreconf -fi && ./configure --prefix=/usr{flags_suffix}"
|
||||
"autoreconf -fi && ./configure --prefix=/usr{autotools_triple}{flags_suffix}"
|
||||
)),
|
||||
BuildSys::AutoconfReady => Some(format!("./configure --prefix=/usr{flags_suffix}")),
|
||||
BuildSys::AutoconfReady => {
|
||||
Some(format!("./configure --prefix=/usr{autotools_triple}{flags_suffix}"))
|
||||
}
|
||||
BuildSys::CMake => Some(format!(
|
||||
"cmake -S . -B _build -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release{flags_suffix}"
|
||||
)),
|
||||
@@ -623,6 +646,40 @@ commit = "deadbeef"
|
||||
assert!(c.ends_with("--enable-foo"), "{c}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn autotools_injects_native_triple() {
|
||||
// Etapa G Fase 3: configure heurístico fija --build/--host al triple saneado.
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
touch(d.path(), "configure.ac");
|
||||
touch(d.path(), "configure");
|
||||
let c = resolve_phases(&recipe(&[]), d.path()).unwrap().configure.unwrap();
|
||||
assert!(c.contains("--build=x86_64-linux-musl"), "{c}");
|
||||
assert!(c.contains("--host=x86_64-linux-musl"), "{c}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn autotools_triple_yields_to_recipe_flags() {
|
||||
// Si la receta ya fija el triple (juicio per-paquete), no duplicamos.
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
touch(d.path(), "configure.ac");
|
||||
touch(d.path(), "configure");
|
||||
let c = resolve_phases(&recipe(&["--host=aarch64-linux-musl"]), d.path())
|
||||
.unwrap()
|
||||
.configure
|
||||
.unwrap();
|
||||
assert!(c.contains("--host=aarch64-linux-musl"), "{c}");
|
||||
assert!(!c.contains("x86_64-linux-musl"), "no inyecta si la receta ya lo puso ({c})");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cmake_ignores_autotools_triple() {
|
||||
// El triple es exclusivo de autotools; CMake/Meson/Cargo no lo reciben.
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
touch(d.path(), "CMakeLists.txt");
|
||||
let c = resolve_phases(&recipe(&[]), d.path()).unwrap().configure.unwrap();
|
||||
assert!(!c.contains("--host="), "{c}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_cmake() {
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
|
||||
@@ -106,7 +106,7 @@ pub fn recipe_from_apkbuild(text: &str) -> Result<String, String> {
|
||||
let mut s = String::from("\n[build.phases]\n");
|
||||
if let Some(b) = compile {
|
||||
let t = translate_abuild(&b, &pkgname, &version);
|
||||
s.push_str(&format!("# de build() de Alpine (traducido; revisá $CBUILD/$CHOST/--shared para estático):\ncompile = {}\n", toml_multiline(&t)));
|
||||
s.push_str(&format!("# de build() de Alpine (traducido; el lab provee $CBUILD/$CHOST — Etapa G Fase 3; revisá --shared para estático):\ncompile = {}\n", toml_multiline(&t)));
|
||||
}
|
||||
if let Some(p) = install {
|
||||
let t = translate_abuild(&p, &pkgname, &version);
|
||||
@@ -249,8 +249,9 @@ fn func_body(text: &str, name: &str) -> Option<String> {
|
||||
|
||||
/// Traduce las variables de abuild a su equivalente en el lab de hammer. Substituciones SEGURAS
|
||||
/// (inequívocas): `$pkgdir`→`/out` (el DESTDIR del lab), `$pkgname`→nombre, `$pkgver`→versión.
|
||||
/// NO toca `$CBUILD/$CHOST/$srcdir/$builddir` ni `--shared` (juicio por-paquete; quedan para el
|
||||
/// humano, marcados en el comentario de la fase). `make DESTDIR="$pkgdir"` → `make DESTDIR="/out"`.
|
||||
/// NO toca `$CBUILD/$CHOST/$srcdir/$builddir` ni `--shared`. `$CBUILD/$CHOST` los RESUELVE el lab en
|
||||
/// runtime (env con el triple nativo saneado, Etapa G Fase 3 — `hammer-build`); `$srcdir/$builddir` y
|
||||
/// `--shared` quedan para el humano. `make DESTDIR="$pkgdir"` → `make DESTDIR="/out"`.
|
||||
fn translate_abuild(body: &str, name: &str, version: &str) -> String {
|
||||
body.replace("${pkgdir}", "/out")
|
||||
.replace("$pkgdir", "/out")
|
||||
|
||||
Reference in New Issue
Block a user