use std::env;
use std::io::BufRead;
use std::path::PathBuf;
fn main() {
let cuvs_build = cmake::Config::new(".")
.build();
println!(
"cargo:rustc-link-search=native={}/lib",
cuvs_build.display()
);
println!("cargo:rustc-link-lib=dylib=cuvs_c");
println!("cargo:rustc-link-lib=dylib=cudart");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let cmake_cache: Vec<String> = std::io::BufReader::new(
std::fs::File::open(format!("{}/build/CMakeCache.txt", out_path.display()))
.expect("Failed to open cuvs CMakeCache.txt"),
)
.lines()
.map(|x| x.expect("Couldn't parse line from CMakeCache.txt"))
.collect();
let cmake_cxx_flags = cmake_cache
.iter()
.find(|x| x.starts_with("CMAKE_CXX_FLAGS:STRING="))
.expect("failed to find CMAKE_CXX_FLAGS in CMakeCache.txt")
.strip_prefix("CMAKE_CXX_FLAGS:STRING=")
.unwrap();
let cmake_linker_flags = cmake_cache
.iter()
.find(|x| x.starts_with("CMAKE_EXE_LINKER_FLAGS:STRING="))
.expect("failed to find CMAKE_EXE_LINKER_FLAGS in CMakeCache.txt")
.strip_prefix("CMAKE_EXE_LINKER_FLAGS:STRING=")
.unwrap();
println!("cargo:cmake_linker_flags={}", cmake_linker_flags);
for flag in cmake_linker_flags.split(' ') {
if flag.starts_with("-Wl,-rpath-link") {
println!("cargo:rustc-link-arg={}", flag);
}
}
bindgen::Builder::default()
.header("cuvs_c_wrapper.h")
.clang_arg("-I../../cpp/include")
.clang_args(cmake_cxx_flags.split(' '))
.clang_arg(format!(
"-I{}/build/_deps/dlpack-src/include/",
out_path.display()
))
.must_use_type("cuvsError_t")
.allowlist_type("(cuvs|bruteForce|cagra|DL).*")
.allowlist_function("(cuvs|bruteForce|cagra).*")
.rustified_enum("(cuvs|cagra|DL|DistanceType|codebook_gen|cudaDataType_t).*")
.allowlist_function("(cudaMemcpyAsync|cudaMemcpy)")
.rustified_enum("cudaError")
.generate()
.expect("Unable to generate cagra_c bindings")
.write_to_file(out_path.join("cuvs_bindings.rs"))
.expect("Failed to write generated rust bindings");
}