use bindgen::EnumVariation;
use std::{env, path::PathBuf, sync::OnceLock};
fn main() {
let library = find_starpu();
let bindings = generate_bindings(&library);
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
fn find_starpu() -> pkg_config::Library {
let lib = pkg_config::Config::new()
.probe("libstarpu")
.expect("Could not find a suitable version of StarPU");
if target_family().split(',').any(|family| family == "unix") {
for link_path in &lib.link_paths {
println!(
"cargo:rustc-link-arg=-Wl,-rpath,{}",
link_path
.to_str()
.expect("Link path is not an UTF-8 string")
);
}
}
lib
}
fn generate_bindings(library: &pkg_config::Library) -> bindgen::Bindings {
bindgen::Builder::default()
.allowlist_file(".*/starpu/.*")
.allowlist_recursively(false)
.allowlist_type(".*va_list.*|drand48_data")
.array_pointers_in_arguments(true)
.blocklist_var("STARPU_TASK_INIT")
.clang_args(
library
.include_paths
.iter()
.flat_map(|include_path| {
["-isystem".to_string(), include_path.display().to_string()]
})
.chain(std::iter::once(
"-fretain-comments-from-system-headers".to_string(),
))
.collect::<Vec<_>>(),
)
.default_enum_style(EnumVariation::Consts)
.derive_copy(true)
.derive_debug(true)
.derive_default(true)
.generate_cstr(true)
.header("wrapper.h")
.impl_debug(true)
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.prepend_enum_name(false)
.generate()
.expect("Unable to generate StarPU bindings")
}
fn target_family() -> &'static str {
static TARGET_FAMILY: OnceLock<Box<str>> = OnceLock::new();
TARGET_FAMILY
.get_or_init(|| {
std::env::var("CARGO_CFG_TARGET_FAMILY")
.expect("Cargo should tell us what the target family is")
.into_boxed_str()
})
.as_ref()
}