use std::fs;
use std::path::PathBuf;
use std::process::Command;
fn main() {
emit_git_build_info();
let base_cuda_path = PathBuf::from("C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA");
if base_cuda_path.exists() {
if let Ok(entries) = fs::read_dir(&base_cuda_path) {
let mut versions: Vec<PathBuf> = entries
.filter_map(|e| e.ok())
.map(|e| e.path())
.filter(|p| {
p.is_dir()
&& p.file_name()
.unwrap_or_default()
.to_string_lossy()
.starts_with("v12.")
})
.collect();
versions.sort();
if let Some(latest) = versions.last() {
let lib_path = latest.join("lib").join("x64");
if lib_path.exists() {
println!("cargo:rustc-link-search=native={}", lib_path.display());
println!("cargo:rustc-link-lib=dylib=cudart");
#[cfg(target_os = "windows")]
println!("cargo:rustc-link-lib=dylib=cublas");
}
}
}
}
#[cfg(target_os = "windows")]
{
let mut res = winres::WindowsResource::new();
res.set_icon("assets/hematite.ico");
if let Err(e) = res.compile() {
eprintln!("winres warning: {e}");
}
}
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=assets/hematite.ico");
}
fn emit_git_build_info() {
let repo_root = std::env::var_os("CARGO_MANIFEST_DIR")
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("."));
let git_dir = resolve_git_dir(&repo_root);
if let Some(git_dir) = git_dir.as_ref() {
println!("cargo:rerun-if-changed={}", git_dir.join("HEAD").display());
println!("cargo:rerun-if-changed={}", git_dir.join("index").display());
if let Ok(head) = fs::read_to_string(git_dir.join("HEAD")) {
if let Some(reference) = head.trim().strip_prefix("ref: ") {
println!(
"cargo:rerun-if-changed={}",
git_dir.join(reference).display()
);
}
}
}
let commit = git_output(&repo_root, &["rev-parse", "--short", "HEAD"]).unwrap_or_default();
let exact_tag =
git_output(&repo_root, &["describe", "--tags", "--exact-match"]).unwrap_or_default();
let dirty = git_output(&repo_root, &["status", "--porcelain"])
.map(|out| (!out.trim().is_empty()).to_string())
.unwrap_or_else(|| "false".to_string());
println!("cargo:rustc-env=HEMATITE_GIT_COMMIT_SHORT={}", commit);
println!("cargo:rustc-env=HEMATITE_GIT_EXACT_TAG={}", exact_tag);
println!("cargo:rustc-env=HEMATITE_GIT_DIRTY={}", dirty);
}
fn resolve_git_dir(repo_root: &PathBuf) -> Option<PathBuf> {
let dot_git = repo_root.join(".git");
if dot_git.is_dir() {
return Some(dot_git);
}
let content = fs::read_to_string(&dot_git).ok()?;
let gitdir = content.trim().strip_prefix("gitdir:")?.trim();
let path = PathBuf::from(gitdir);
if path.is_absolute() {
Some(path)
} else {
Some(repo_root.join(path))
}
}
fn git_output(repo_root: &PathBuf, args: &[&str]) -> Option<String> {
let output = Command::new("git")
.current_dir(repo_root)
.args(args)
.output()
.ok()?;
if !output.status.success() {
return None;
}
let text = String::from_utf8_lossy(&output.stdout).trim().to_string();
Some(text)
}