use cmake::Config;
use std::env;
use std::path::PathBuf;
#[derive(Debug)]
struct ParseSignedConstants;
impl bindgen::callbacks::ParseCallbacks for ParseSignedConstants {
fn int_macro(&self, name: &str, _value: i64) -> Option<bindgen::callbacks::IntKind> {
let prefix: String = name.chars().take_while(|c| *c != '_').collect();
match prefix.as_ref() {
"CV" | "IDA" | "KIN" | "SUN" => Some(bindgen::callbacks::IntKind::Int),
_ => None,
}
}
}
fn main() {
macro_rules! feature {
($s:tt) => {
if cfg!(feature = $s) {
"ON"
} else {
"OFF"
}
};
}
let dst = Config::new("vendor")
.define("CMAKE_INSTALL_LIBDIR", "lib")
.define("BUILD_STATIC_LIBS", "OFF")
.define("BUILD_SHARED_LIBS", "ON")
.define("BUILD_TESTING", "OFF")
.define("EXAMPLES_INSTALL", "OFF")
.define("BUILD_ARKODE", feature!("arkode"))
.define("BUILD_CVODE", feature!("cvode"))
.define("BUILD_CVODES", feature!("cvodes"))
.define("BUILD_IDA", feature!("ida"))
.define("BUILD_IDAS", feature!("idas"))
.define("BUILD_KINSOL", feature!("kinsol"))
.define("OPENMP_ENABLE", feature!("nvecopenmp"))
.define("PTHREAD_ENABLE", feature!("nvecpthreads"))
.build();
println!("cargo:rustc-link-search=native={}/lib", dst.display());
println!("cargo:rustc-link-lib=dylib=sundials_nvecserial");
println!("cargo:rustc-link-lib=dylib=sundials_sunlinsolband");
println!("cargo:rustc-link-lib=dylib=sundials_sunlinsoldense");
println!("cargo:rustc-link-lib=dylib=sundials_sunlinsolpcg");
println!("cargo:rustc-link-lib=dylib=sundials_sunlinsolspbcgs");
println!("cargo:rustc-link-lib=dylib=sundials_sunlinsolspfgmr");
println!("cargo:rustc-link-lib=dylib=sundials_sunlinsolspgmr");
println!("cargo:rustc-link-lib=dylib=sundials_sunlinsolsptfqmr");
println!("cargo:rustc-link-lib=dylib=sundials_sunmatrixband");
println!("cargo:rustc-link-lib=dylib=sundials_sunmatrixdense");
println!("cargo:rustc-link-lib=dylib=sundials_sunmatrixsparse");
println!("cargo:rustc-link-lib=dylib=sundials_sunnonlinsolfixedpoint");
println!("cargo:rustc-link-lib=dylib=sundials_sunnonlinsolnewton");
macro_rules! link {
($($s:tt),*) => {
$(if cfg!(feature = $s) {
println!("cargo:rustc-link-lib=dylib=sundials_{}", $s);
})*
}
}
link! {"arkode", "cvode", "cvodes", "cvodes", "ida", "idas", "kinsol", "nvecopenmp", "nvecpthreads"}
macro_rules! define {
($a:tt, $b:tt) => {
format!(
"-DUSE_{}={}",
stringify!($b),
if cfg!(feature = $a) { 1 } else { 0 }
)
};
}
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindgen::Builder::default()
.header("wrapper.h")
.clang_arg(format!("-I{}/include", dst.display()))
.clang_args(&[
define!("arkode", ARKODE),
define!("cvode", CVODE),
define!("cvodes", CVODES),
define!("ida", IDA),
define!("idas", IDAS),
define!("kinsol", KINSOL),
define!("nvecopenmp", OPENMP),
define!("nvecpthreads", PTHREADS),
])
.parse_callbacks(Box::new(ParseSignedConstants))
.generate()
.expect("Unable to generate bindings")
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}