Etapa G: frontera CGO — knob 'cgo=true' (CC=zig cc + static) destraba sqlite bundled-C
vendor_go_deps/BuildSys::Go por defecto compila CGO_ENABLED=0 (Go puro estático). Nuevo campo [build] cgo=true ⇒ CGO_ENABLED=1 CC="zig cc" (musl nativo del sandbox) + -linkmode=external -extldflags=-static. Validado: usql + sq (driver sqlite3 mattn, bundled-C) → estáticos y CORREN (usql 0.0.0-dev, sq v0.0.0-dev). Tests go_cgo_knob_switches_compile_env. cgo contra libs C EXTERNAS (gpgme/libvirt en werf/minikube/skopeo) aún requiere esas recetas; esto cubre la clase bundled-C.
This commit is contained in:
@@ -757,11 +757,23 @@ fn resolve_phases(recipe: &Recipe, src: &Path) -> hammer_core::Result<Phases> {
|
||||
// disco tenga sitio. /src es el árbol de fuentes bind-montado (en disco) y no se sella
|
||||
// (sólo /out) ⇒ inocuo. GOTMPDIR debe pre-existir. No entra al hash de input (es la
|
||||
// fase generada, no un campo de la receta) ⇒ no re-sella el corpus Go.
|
||||
// CGO opt-in (recipe `cgo = true`): drivers con C bundled (sqlite3 de mattn en
|
||||
// usql/sq/dolt) necesitan cgo. CC="zig cc" (musl nativo del sandbox) + link estático
|
||||
// por el linker externo (`-linkmode=external -extldflags=-static`). Default: CGO off
|
||||
// (Go puro estático). Validado: usql (sqlite, estático y corre).
|
||||
let (cgo_env, ldflags) = if recipe.build.cgo {
|
||||
(
|
||||
"CGO_ENABLED=1 CC=\"zig cc\" CXX=\"zig c++\"",
|
||||
"-ldflags=\"-buildid= -linkmode=external -extldflags=-static\"",
|
||||
)
|
||||
} else {
|
||||
("CGO_ENABLED=0", "-ldflags=-buildid=")
|
||||
};
|
||||
Some(format!(
|
||||
"export GOCACHE=/src/.gocache GOTMPDIR=/src/.gotmp GOPATH=/tmp/gopath \
|
||||
GOTOOLCHAIN=local CGO_ENABLED=0 GOFLAGS=-mod=vendor GOPROXY=off \
|
||||
GOTOOLCHAIN=local {cgo_env} GOFLAGS=-mod=vendor GOPROXY=off \
|
||||
GOBIN=/out/usr/bin; mkdir -p /src/.gotmp; \
|
||||
go install -trimpath -ldflags=-buildid= {pkg}"
|
||||
go install -trimpath {ldflags} {pkg}"
|
||||
))
|
||||
}
|
||||
BuildSys::Unknown => None,
|
||||
@@ -837,6 +849,20 @@ commit = "deadbeef"
|
||||
assert_eq!(p.install.as_deref(), Some("true"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn go_cgo_knob_switches_compile_env() {
|
||||
// cgo=false (default) ⇒ CGO_ENABLED=0, Go puro; cgo=true ⇒ CGO_ENABLED=1 + CC zig + estático.
|
||||
let d = tempfile::tempdir().unwrap();
|
||||
touch(d.path(), "go.mod");
|
||||
std::fs::write(d.path().join("main.go"), b"package main\nfunc main(){}\n").unwrap();
|
||||
let off = resolve_phases(&recipe(&[]), d.path()).unwrap().compile.unwrap();
|
||||
assert!(off.contains("CGO_ENABLED=0"), "{off}");
|
||||
let mut r = recipe(&[]);
|
||||
r.build.cgo = true;
|
||||
let on = resolve_phases(&r, d.path()).unwrap().compile.unwrap();
|
||||
assert!(on.contains("CGO_ENABLED=1") && on.contains("zig cc") && on.contains("-extldflags=-static"), "{on}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_go_when_only_go_work() {
|
||||
// workspace multimódulo sin go.mod en la raíz (sólo go.work) ⇒ sigue siendo Go (antes caía a
|
||||
|
||||
@@ -103,6 +103,14 @@ pub struct Build {
|
||||
/// herramientas, no inputs del of_tree del 4/4). `None` ⇒ el zig por defecto. Ver SDD 11 §7.2b.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub zig_version: Option<String>,
|
||||
/// Habilita CGO en un build Go (`BuildSys::Go`). Por defecto el lab compila con `CGO_ENABLED=0`
|
||||
/// (Go puro, estático, sin C). Algunos proyectos necesitan cgo para drivers con C bundled (p.ej.
|
||||
/// el driver sqlite3 de mattn en usql/sq/dolt): con `cgo = true` el compile usa `CGO_ENABLED=1`
|
||||
/// + `CC="zig cc"` (musl nativo del sandbox) y liga estático (`-linkmode=external -extldflags=
|
||||
/// -static`). Sólo para C bundled; cgo contra libs C EXTERNAS (gpgme/libvirt) requiere además
|
||||
/// esas recetas en el sandbox. No-op fuera de BuildSys::Go.
|
||||
#[serde(default)]
|
||||
pub cgo: bool,
|
||||
/// Overrides explícitos de las fases del build. Lo no especificado se decide por
|
||||
/// heurística en el lab (ver `docs/02-build-lab.md` §4).
|
||||
#[serde(default)]
|
||||
|
||||
Reference in New Issue
Block a user