extern crate bindgen;
#[cfg(any(feature = "vendored", feature = "openpmix-src"))]
extern crate openpmix_src;
fn env_inner(name: &str) -> Option<String> {
let var = std::env::var(name);
println!("cargo:rerun-if-env-changed={name}");
match var {
Ok(v) => {
println!("{} = {}", name, v);
Some(v)
}
Err(_) => {
println!("{name} unset");
None
}
}
}
fn find_pmix_normal(out_path: &std::path::PathBuf) -> (std::path::PathBuf, std::path::PathBuf) {
use std::path::PathBuf;
let lib_dir = env_inner("PMIX_LIB_DIR").map(PathBuf::from);
let include_dir = env_inner("PMIX_INCLUDE_DIR").map(PathBuf::from);
if let (Some(lib_dir), Some(include_dir)) = (lib_dir, include_dir) {
match std::os::unix::fs::symlink(&lib_dir, out_path.join("lib")) {
Ok(_) => {}
Err(e) => {
if e.kind() != std::io::ErrorKind::AlreadyExists {
std::fs::remove_file(out_path.join("lib")).unwrap();
std::os::unix::fs::symlink(&lib_dir, out_path.join("lib")).unwrap();
}
}
}
match std::os::unix::fs::symlink(&include_dir, out_path.join("include")) {
Ok(_) => {}
Err(e) => {
if e.kind() != std::io::ErrorKind::AlreadyExists {
std::fs::remove_file(out_path.join("include")).unwrap();
std::os::unix::fs::symlink(&include_dir, out_path.join("include")).unwrap();
}
}
}
println!("cargo:root={}", out_path.display());
return (out_path.join("lib"), out_path.join("include"));
}
else {
panic!("PMIX_LIB_DIR and PMIX_INCLUDE_DIR must be set to use a non-vendored PMI implementation");
}
}
fn find_pmix(out_path: &std::path::PathBuf) -> (std::path::PathBuf, std::path::PathBuf) {
#[cfg(any(feature = "vendored", feature = "openpmix-src"))]
{
if env_inner("PMIX_NO_VENDORED").map_or(true, |v| v == "0") {
let libevent_from_env = env_inner("LIBEVENT_DIR");
let lib_event_dir = libevent_from_env.clone()
.or_else(|| std::env::var("DEP_EVENT_ROOT").ok())
.expect("Couldn't find libevent: set LIBEVENT_DIR to a system libevent install prefix, or enable the vendored-libevent feature");
let hwloc_from_env = env_inner("HWLOC_DIR");
let libhwloc_dir = hwloc_from_env.clone()
.or_else(|| std::env::var("DEP_HWLOC_ROOT").ok())
.expect("Couldn't find libhwloc: set HWLOC_DIR to a system hwloc install prefix, or enable the vendored-hwloc feature");
let artifacts = openpmix_src::Build::new().build();
println!("cargo:rustc-link-search={}/lib", lib_event_dir);
println!("cargo:rustc-link-search={}/lib", libhwloc_dir);
let event_link_kind = if libevent_from_env.is_some() { "dylib" } else { "static" };
let hwloc_link_kind = if hwloc_from_env.is_some() { "dylib" } else { "static" };
println!("cargo:rustc-link-lib={}=event_core", event_link_kind);
println!("cargo:rustc-link-lib={}=event_pthreads", event_link_kind);
println!("cargo:rustc-link-lib={}=hwloc", hwloc_link_kind);
return (
artifacts.lib_dir().to_path_buf(),
artifacts.include_dir().to_path_buf(),
);
}
}
find_pmix_normal(out_path)
}
fn main(){
let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
println!("cargo:rerun-if-changed={}", "build.rs");
let artifacts = find_pmix(&out_path);
let bindings = bindgen::Builder::default()
.header(artifacts.1.join("pmix.h").to_str().unwrap())
.clang_arg(format!("-I{}", artifacts.1.to_str().unwrap()))
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rustc-link-lib=pmix");
println!("cargo:rustc-link-search=native={}", artifacts.0.display());
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", artifacts.0.display());
}