fn main() {
#[cfg(feature = "lapack")]
build_fortran();
}
#[cfg(feature = "lapack")]
fn build_fortran() {
use std::process::Command;
let saved = save_and_clear_c_flags();
cc::Build::new()
.compiler("gfortran")
.file("native/prism.f90")
.file("native/spectral.f90")
.flag("-fPIC")
.flag("-O2")
.compile("fortran_ops");
restore_c_flags(saved);
let lib_name = if cfg!(target_os = "macos") {
"libgfortran.dylib"
} else {
"libgfortran.so"
};
let output = Command::new("gfortran")
.args([format!("-print-file-name={}", lib_name)])
.output()
.expect("gfortran must be in PATH");
let lib_path = String::from_utf8(output.stdout).unwrap();
let lib_path = lib_path.trim();
if let Some(dir) = std::path::Path::new(lib_path).parent() {
let d = dir.display().to_string();
if !d.is_empty() {
println!("cargo:rustc-link-search=native={}", d);
}
}
println!("cargo:rustc-link-lib=gfortran");
if cfg!(target_os = "macos") {
println!("cargo:rustc-link-lib=framework=Accelerate");
} else {
println!("cargo:rustc-link-lib=lapack");
println!("cargo:rustc-link-lib=blas");
}
}
#[cfg(feature = "lapack")]
const C_FLAG_VARS: &[&str] = &["CFLAGS", "CXXFLAGS", "NIX_CFLAGS_COMPILE"];
#[cfg(feature = "lapack")]
fn save_and_clear_c_flags() -> Vec<(&'static str, Option<String>)> {
C_FLAG_VARS
.iter()
.map(|&var| {
let val = std::env::var(var).ok();
unsafe { std::env::remove_var(var) };
(var, val)
})
.collect()
}
#[cfg(feature = "lapack")]
fn restore_c_flags(saved: Vec<(&'static str, Option<String>)>) {
for (var, val) in saved {
match val {
Some(v) => unsafe { std::env::set_var(var, v) },
None => unsafe { std::env::remove_var(var) },
}
}
}