use std::env;
use std::fs;
use std::path::{PathBuf};
use fs_extra::file as fs_file;
fn find_onnx_runtime_lib_dir() -> Option<PathBuf> {
let home_dir = dirs::home_dir()?;
let cache_base = home_dir.join(".cache/ort.pyke.io/dfbin");
let target_triple = env::var("TARGET").ok()?;
let target_cache_dir = cache_base.join(&target_triple);
if !target_cache_dir.is_dir() {
println!("cargo:warning=build.rs: ONNX Runtime cache directory not found for target {} at {}", target_triple, target_cache_dir.display());
return None;
}
for entry in fs::read_dir(&target_cache_dir).ok()?.filter_map(Result::ok) {
let path = entry.path();
if path.is_dir() {
let lib_dir = path.join("onnxruntime/lib");
if lib_dir.is_dir() {
let has_libs = fs::read_dir(&lib_dir).ok()?.any(|f| {
f.map_or(false, |e| {
let p = e.path();
p.is_file() && (p.extension().map_or(false, |ext| ext == "so" || ext == "dylib"))
})
});
if has_libs {
println!("cargo:warning=build.rs: Found potential ONNX Runtime library directory: {}", lib_dir.display());
return Some(lib_dir);
}
}
}
}
println!("cargo:warning=build.rs: Could not find a subdirectory containing ONNX Runtime libraries within {}", target_cache_dir.display());
None
}
fn main() {
println!("cargo:rerun-if-changed=build.rs");
if cfg!(target_os = "linux") || cfg!(target_os = "macos") {
if let Some(source_lib_dir) = find_onnx_runtime_lib_dir() {
let out_dir = env::var("OUT_DIR").expect("OUT_DIR not set");
let out_dir_path = PathBuf::from(&out_dir);
let target_profile_dir = out_dir_path
.parent().expect("OUT_DIR has no parent?") .parent().expect("OUT_DIR has no parent parent?") .parent().expect("OUT_DIR has no parent parent parent?");
let target_lib_dir = target_profile_dir.join("lib");
if let Err(e) = fs::create_dir_all(&target_lib_dir) {
println!("cargo:warning=build.rs: Failed to create target library directory {}: {}. Skipping copy.", target_lib_dir.display(), e);
return;
}
let copy_options = fs_file::CopyOptions::new().overwrite(true);
let mut files_copied = 0;
let mut copy_errors = 0;
println!(
"cargo:warning=build.rs: Attempting to copy library files from {} to {}",
source_lib_dir.display(),
target_lib_dir.display()
);
match fs::read_dir(&source_lib_dir) {
Ok(entries) => {
for entry_result in entries {
if let Ok(entry) = entry_result {
let source_path = entry.path();
if source_path.is_file() {
let extension = source_path.extension().and_then(|s| s.to_str());
if extension == Some("so") || extension == Some("dylib") {
let target_path = target_lib_dir.join(entry.file_name());
if let Err(e) = fs_file::copy(&source_path, &target_path, ©_options) {
println!(
"cargo:warning=build.rs: Failed to copy {} to {}: {}",
source_path.display(),
target_path.display(),
e
);
copy_errors += 1;
} else {
files_copied += 1;
}
}
}
}
}
if copy_errors > 0 {
println!(
"cargo:warning=build.rs: Finished copying with {} errors. {} files copied successfully.",
copy_errors,
files_copied
);
} else if files_copied > 0 {
println!(
"cargo:warning=build.rs: Successfully copied {} library files to {}",
files_copied,
target_lib_dir.display()
);
} else {
println!("cargo:warning=build.rs: No library files found to copy in {}.", source_lib_dir.display());
}
},
Err(e) => {
println!(
"cargo:warning=build.rs: Failed to read source library directory {}: {}. Skipping copy.",
source_lib_dir.display(),
e
);
return; }
}
if files_copied > 0 && copy_errors == 0 {
let rpath_value = if cfg!(target_os = "macos") {
"@executable_path/lib"
} else {
"$ORIGIN/lib"
};
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", rpath_value);
println!("cargo:warning=build.rs: Setting RPATH to: {}", rpath_value);
} else {
println!("cargo:warning=build.rs: Skipping RPATH setup due to copy errors or no files copied.");
}
} else {
println!("cargo:warning=build.rs: ONNX Runtime library directory not found in cache. Skipping library copy and RPATH setup.");
}
}
}