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>
39 lines
1.3 KiB
Rust
39 lines
1.3 KiB
Rust
use std::path::PathBuf;
|
|
|
|
fn main() {
|
|
// Capture the absolute C compiler path at build time so the binary is self-contained.
|
|
// This is critical for Nix builds where cc/gcc live in /nix/store paths.
|
|
let cc_path = std::env::var("CC").ok()
|
|
.filter(|s| !s.is_empty())
|
|
.and_then(|s| resolve_absolute(&s))
|
|
.or_else(|| find_in_path("cc"))
|
|
.or_else(|| find_in_path("gcc"))
|
|
.or_else(|| find_in_path("clang"))
|
|
.unwrap_or_default();
|
|
|
|
println!("cargo:rustc-env=LUX_CC_PATH={}", cc_path);
|
|
println!("cargo:rerun-if-env-changed=CC");
|
|
println!("cargo:rerun-if-env-changed=PATH");
|
|
}
|
|
|
|
/// Resolve a command name to its absolute path by searching PATH.
|
|
fn find_in_path(cmd: &str) -> Option<String> {
|
|
let path_var = std::env::var("PATH").ok()?;
|
|
for dir in path_var.split(':') {
|
|
let candidate = PathBuf::from(dir).join(cmd);
|
|
if candidate.is_file() {
|
|
return Some(candidate.to_string_lossy().into_owned());
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
/// If the path is already absolute and exists, return it. Otherwise search PATH.
|
|
fn resolve_absolute(cmd: &str) -> Option<String> {
|
|
let p = PathBuf::from(cmd);
|
|
if p.is_absolute() && p.is_file() {
|
|
return Some(cmd.to_string());
|
|
}
|
|
find_in_path(cmd)
|
|
}
|