use std::{env, path::PathBuf, process::Command};
use bindgen::callbacks::ParseCallbacks;
#[derive(Debug)]
struct ProcessComments;
impl ParseCallbacks for ProcessComments {
fn process_comment(&self, comment: &str) -> Option<String> {
match doxygen_bindgen::transform(comment) {
Ok(res) => Some(res),
Err(err) => {
println!(
"cargo:warning=Problem processing doxygen comment: {comment}\n{err}"
);
None
},
}
}
}
fn main() {
println!("cargo:rerun-if-changed=include/wrapper.h");
let nix_libraries = [
"nix-main-c",
"nix-expr-c",
"nix-store-c",
"nix-util-c",
"nix-flake-c",
];
let gcc_include = Command::new("gcc")
.arg("-print-file-name=include")
.output()
.expect("Failed to get gcc include path")
.stdout;
let gcc_include = String::from_utf8_lossy(&gcc_include).trim().to_string();
let mut builder = bindgen::Builder::default()
.header("include/wrapper.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.formatter(bindgen::Formatter::Rustfmt)
.rustfmt_configuration_file(std::fs::canonicalize(".rustfmt.toml").ok())
.parse_callbacks(Box::new(ProcessComments));
for nix_lib in nix_libraries {
let lib = pkg_config::probe_library(nix_lib)
.expect(&format!("Unable to find .pc file for {}", nix_lib));
for include_path in lib.include_paths {
builder = builder.clang_arg(format!("-I{}", include_path.display()));
}
for link_file in lib.link_files {
println!("cargo:rustc-link-lib={}", link_file.display());
}
}
builder = builder.clang_arg(format!("-I{gcc_include}"));
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let bindings = builder.generate().expect("Unable to generate bindings");
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}