#![allow(unused_imports)]
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
fn main() {
#[cfg(feature = "rpc")]
{
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let schema_dir = Path::new(&manifest_dir).join("schema");
let schema_path = schema_dir.join("ReadCon.capnp");
if schema_path.exists() {
capnpc::CompilerCommand::new()
.src_prefix(&schema_dir)
.file(&schema_path)
.run()
.expect("Cap'n Proto schema compilation failed");
} else {
panic!(
"Cap'n Proto schema not found at {}. \
The rpc feature requires schema/ReadCon.capnp in the crate root.",
schema_path.display()
);
}
}
#[cfg(feature = "metatensor")]
{
emit_metatensor_sys_metadata();
}
}
#[cfg(feature = "metatensor")]
fn emit_metatensor_sys_metadata() {
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".into());
let target_dir = env::var("CARGO_TARGET_DIR")
.map(PathBuf::from)
.unwrap_or_else(|_| manifest_dir.join("target"));
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let build_root = out_dir
.ancestors()
.find(|p| p.file_name().is_some_and(|n| n == "build"))
.map(|p| p.to_path_buf())
.unwrap_or_else(|| target_dir.join(&profile).join("build"));
let mut include_dir: Option<PathBuf> = None;
let mut lib_dir: Option<PathBuf> = None;
if let Ok(entries) = fs::read_dir(&build_root) {
for ent in entries.flatten() {
let name = ent.file_name();
let name = name.to_string_lossy();
if !name.starts_with("metatensor-sys-") {
continue;
}
let out = ent.path().join("out");
let inc = out.join("include");
if inc.join("metatensor.h").is_file() {
include_dir = Some(inc);
}
let candidates = [
out.join("lib"),
out.join("build")
.join("target")
.join(env::var("TARGET").unwrap_or_default())
.join("release")
.join("deps"),
out.clone(),
];
for c in &candidates {
if dir_has_metatensor_lib(c) {
lib_dir = Some(c.clone());
break;
}
}
if include_dir.is_some() && lib_dir.is_some() {
break;
}
}
}
println!("cargo:rerun-if-env-changed=OUT_DIR");
println!("cargo:rerun-if-changed=build.rs");
if let Some(ref inc) = include_dir {
println!("cargo:rustc-env=READCON_METATENSOR_INCLUDE={}", inc.display());
println!("cargo:INCLUDE={}", inc.display());
println!("cargo:root={}", manifest_dir.display());
}
if let Some(ref lib) = lib_dir {
println!("cargo:rustc-link-search=native={}", lib.display());
println!("cargo:rustc-link-lib=dylib=metatensor");
println!("cargo:rustc-env=READCON_METATENSOR_LIB_DIR={}", lib.display());
println!("cargo:LIB={}", lib.display());
if env::var("CARGO_CFG_TARGET_FAMILY").as_deref() == Ok("unix") {
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", lib.display());
}
}
let env_path = target_dir.join(&profile).join("readcon-metatensor.env");
if let (Some(inc), Some(lib)) = (&include_dir, &lib_dir) {
let body = format!(
"READCON_METATENSOR_INCLUDE={}\nREADCON_METATENSOR_LIB_DIR={}\n",
inc.display(),
lib.display()
);
let _ = fs::create_dir_all(env_path.parent().unwrap());
let _ = fs::write(&env_path, body);
println!("cargo:rustc-env=READCON_METATENSOR_ENV_FILE={}", env_path.display());
}
}
#[cfg(feature = "metatensor")]
fn dir_has_metatensor_lib(dir: &Path) -> bool {
if !dir.is_dir() {
return false;
}
for name in [
"libmetatensor.so",
"libmetatensor.dylib",
"metatensor.dll",
"libmetatensor.a",
"metatensor.lib",
] {
if dir.join(name).is_file() {
return true;
}
}
if let Ok(entries) = fs::read_dir(dir) {
for ent in entries.flatten() {
let n = ent.file_name();
let s = n.to_string_lossy();
if s.starts_with("libmetatensor.") || s == "metatensor.dll" {
return true;
}
}
}
false
}