use std::path::{Path, PathBuf};
const LIB: &str = "libArrowMetalC.dylib";
fn repo_root() -> PathBuf {
let here = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
here.parent()
.and_then(Path::parent)
.map(Path::to_path_buf)
.unwrap_or(here)
}
fn candidates() -> Vec<PathBuf> {
let mut out = Vec::new();
if let Ok(lib) = std::env::var("ARROWMETAL_LIB") {
if let Some(parent) = Path::new(&lib).parent() {
out.push(parent.to_path_buf());
}
}
if let Ok(dir) = std::env::var("ARROWMETAL_LIB_DIR") {
out.push(PathBuf::from(dir));
}
let root = repo_root();
out.push(root.join(".build/release"));
out.push(root.join(".build/debug"));
out.push(PathBuf::from("/usr/local/lib"));
out.push(PathBuf::from("/opt/homebrew/lib"));
out
}
fn main() {
println!("cargo:rerun-if-env-changed=ARROWMETAL_LIB");
println!("cargo:rerun-if-env-changed=ARROWMETAL_LIB_DIR");
if std::env::var_os("DOCS_RS").is_some() {
return;
}
if std::env::var("CARGO_CFG_TARGET_OS").as_deref() != Ok("macos") {
panic!(
"arrowmetal-sys only builds on macOS: ArrowMetal is a Metal library and \
{LIB} exists for Apple silicon only."
);
}
let searched: Vec<String> = candidates().iter().map(|d| d.display().to_string()).collect();
let dir = match candidates().into_iter().find(|d| d.join(LIB).exists()) {
Some(d) => d,
None => panic!(
"{LIB} not found.\n\
Searched, in order:\n {}\n\n\
Either point ARROWMETAL_LIB at the dylib:\n \
export ARROWMETAL_LIB=/path/to/libArrowMetalC.dylib\n\
or build it from the repository root:\n \
DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer \
swift build -c release --product ArrowMetalC",
searched.join("\n ")
),
};
let dir = dir.canonicalize().unwrap_or(dir);
println!("cargo:rerun-if-changed={}", dir.join(LIB).display());
let dir = dir.display();
println!("cargo:rustc-link-search=native={dir}");
println!("cargo:rustc-link-lib=dylib=ArrowMetalC");
println!("cargo:rustc-link-arg=-Wl,-rpath,{dir}");
println!("cargo:lib_dir={dir}");
println!("cargo:rustc-env=ARROWMETAL_SYS_LIB_DIR={dir}");
}