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 1574Shell 204Rust 111Markdown 993763 Definiciones

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.

d47be16a8be807843ef2642e3f48e2adc4dfdc3b · por sergio · (hace 3 meses) · padre 4bb5e67e8 · ver el árbol en este commit

Delta semántico · 3

crates/hammer-build/src/lib.rs

crates/hammer-core/src/recipe.rs

  • cambió de firma struct Build pub

6 archivos · +79 −44

diff --git a/crates/hammer-build/src/lib.rs b/crates/hammer-build/src/lib.rs
index f7ea30c7..2b3524fb 100644
--- a/crates/hammer-build/src/lib.rs
+++ b/crates/hammer-build/src/lib.rs
@@ -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
diff --git a/crates/hammer-core/src/recipe.rs b/crates/hammer-core/src/recipe.rs
index 0a9fe00a..9c54c18a 100644
--- a/crates/hammer-core/src/recipe.rs
+++ b/crates/hammer-core/src/recipe.rs
@@ -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)]
diff --git a/tandas/staged-fallidos/sq.toml b/recipes/sq.toml
similarity index 78%
rename from tandas/staged-fallidos/sq.toml
rename to recipes/sq.toml
index 1fc3527b..5bce2a95 100644
--- a/tandas/staged-fallidos/sq.toml
+++ b/recipes/sq.toml
@@ -1,4 +1,3 @@
-# DIFERIDA (finde): driver sqlite3 necesita CGO (undefined driveri/DBTypeForKind con CGO off), como usql.
 # 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.
@@ -15,7 +14,8 @@ compiler = "zig-cc"
 target   = "x86_64-linux-musl"
 link     = "static"
 flags    = []
+cgo      = true   # driver sqlite3 con C bundled — necesita cgo
 
-# buildInputs de nix (no usados con CGO off): go
+# buildInputs de nix: go
 [deps]
 build = ["go"]
diff --git a/tandas/staged-fallidos/usql.toml b/recipes/usql.toml
similarity index 73%
rename from tandas/staged-fallidos/usql.toml
rename to recipes/usql.toml
index d7e7ce00..a871b9ce 100644
--- a/tandas/staged-fallidos/usql.toml
+++ b/recipes/usql.toml
@@ -1,4 +1,3 @@
-# DIFERIDA (go-13): driver SQLite necesita CGO (cgo-sqlite); con CGO_ENABLED=0 → 'undefined: sqlite'. Necesita build CGO + libs de DB.
 # 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.
@@ -15,7 +14,9 @@ compiler = "zig-cc"
 target   = "x86_64-linux-musl"
 link     = "static"
 flags    = []
+cgo      = true   # driver sqlite3 (mattn) con C bundled — necesita cgo
 
-# buildInputs de nix (no usados con CGO off): go, unixodbc, icu4c
+# buildInputs de nix: go, unixodbc, icu4c
 [deps]
 build = ["go"]
+