extern crate bindgen;
extern crate pkg_config;
use std::{env, path::PathBuf, process::Command};
use cmake::Config;
use walkdir::WalkDir;
fn build_vendored_compiled_nn(out_path: &PathBuf) -> PathBuf {
let source_path = out_path.join("CompiledNN/");
let status = Command::new("rsync")
.args(["-a", "CompiledNN/", source_path.to_str().unwrap()])
.status()
.expect("Failed to execute rsync process");
if !status.success() {
panic!("rsync process exited with {:?}", status.code());
}
let install_path = Config::new(source_path)
.define("BUILD_SHARED_LIBS", "OFF")
.define("WITH_ONNX", "OFF")
.build();
for entry in WalkDir::new("CompiledNN")
.into_iter()
.filter_map(|entry| entry.ok())
.filter_map(|entry| match entry.metadata().ok() {
Some(metadata) if metadata.is_file() => Some(entry),
_ => None,
})
{
println!("cargo:rerun-if-changed={}", entry.path().display());
}
let library_path = install_path.join("lib/");
let library64_path = install_path.join("lib64/");
let include_path = install_path.join("include/");
println!("cargo:rustc-link-search=native={}", library_path.display());
println!(
"cargo:rustc-link-search=native={}",
library64_path.display()
);
println!("cargo:rustc-link-lib=static=CompiledNN");
let pkg_config = pkg_config::Config::new().probe("hdf5");
match pkg_config {
Ok(config) => {
for library_path in config.link_paths.iter() {
println!("cargo:rustc-link-search=native={}", library_path.display());
}
for library in config.libs.iter() {
println!("cargo:rustc-link-lib=dylib={}", library);
}
}
Err(_) => println!("cargo:rustc-link-lib=dylib=hdf5"),
};
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
"linux" => {
println!("cargo:rustc-link-lib=dylib=stdc++");
}
"macos" => {
println!("cargo:rustc-link-lib=dylib=c++");
}
_ => {
panic!("We don't seem to be compiling on a known OS, aborting...")
}
}
include_path
}
fn pkg_config_config(config: &pkg_config::Library) {
for library_path in config.link_paths.iter() {
println!("cargo:rustc-link-search=native={}", library_path.display());
}
for library in config.libs.iter() {
println!("cargo:rustc-link-lib=dylib={}", library);
}
}
fn generate_bindings(include_path: &[PathBuf], out_path: &PathBuf) {
let clang_args = {
let mut args = vec!["-x", "c++", "-std=c++11"];
for buf in include_path {
if let Some(s) = buf.to_str() {
args.push("-I");
args.push(s);
}
}
args
};
let bindings = bindgen::Builder::default()
.header("wrapper.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.clang_args(clang_args)
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
fn main() {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let pkg_config = pkg_config::Config::new()
.atleast_version("1.0.0")
.probe("compilednn");
if let Ok(config) = pkg_config {
let include_path = config.include_paths.clone();
pkg_config_config(&config);
generate_bindings(include_path.as_slice(), &out_path);
} else {
let include_path = vec![build_vendored_compiled_nn(&out_path)];
generate_bindings(&include_path, &out_path);
}
println!("cargo:rerun-if-changed=wrapper.h");
}