fix: embed C compiler path at build time for self-contained binary

build.rs captures the absolute path to cc/gcc/clang during compilation
and bakes it into the binary. On Nix systems this embeds the full
/nix/store path so `lux compile` works without cc on PATH.

Lookup order: $CC env var > embedded build-time path > PATH search.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-18 08:12:18 -05:00
parent dbdd3cca57
commit 8e788c8a9f
2 changed files with 70 additions and 2 deletions

View File

@@ -726,6 +726,36 @@ fn collect_lux_files_nonrecursive(dir: &str, pattern: Option<&str>, files: &mut
}
}
/// Find a C compiler. Priority: $CC env var, build-time embedded path, PATH search.
fn find_c_compiler() -> String {
// 1. Explicit env var
if let Ok(cc) = std::env::var("CC") {
if !cc.is_empty() {
return cc;
}
}
// 2. Path captured at build time (e.g. absolute nix store path)
let built_in = env!("LUX_CC_PATH");
if !built_in.is_empty() && std::path::Path::new(built_in).exists() {
return built_in.to_string();
}
// 3. Search PATH
for name in &["cc", "gcc", "clang"] {
if let Ok(output) = std::process::Command::new("which").arg(name).output() {
if output.status.success() {
if let Ok(p) = String::from_utf8(output.stdout) {
let p = p.trim();
if !p.is_empty() {
return p.to_string();
}
}
}
}
}
// 4. Last resort
"cc".to_string()
}
fn compile_to_c(path: &str, output_path: Option<&str>, run_after: bool, emit_c: bool) {
use codegen::c_backend::CBackend;
use modules::ModuleLoader;
@@ -817,8 +847,8 @@ fn compile_to_c(path: &str, output_path: Option<&str>, run_after: bool, emit_c:
std::process::exit(1);
}
// Find C compiler
let cc = std::env::var("CC").unwrap_or_else(|_| "cc".to_string());
// Find C compiler: $CC env var > embedded build-time path > PATH search
let cc = find_c_compiler();
let compile_result = Command::new(&cc)
.args(["-O2", "-o"])