[PATCH v2 14/18] build-helper: cbindgen, let crates generate a header file
From: Ezekiel Newren <ezekielnewren@gmail.com>
Signed-off-by: Ezekiel Newren <ezekielnewren@gmail.com>
---
rust/build-helper/Cargo.toml | 5 ++++
rust/build-helper/src/lib.rs | 44 +++++++++++++++++++++++++++++++++++-
rust/cbindgen-template.toml | 16 +++++++++++++
3 files changed, 64 insertions(+), 1 deletion(-)
create mode 100644 rust/cbindgen-template.toml
diff --git a/rust/build-helper/Cargo.toml b/rust/build-helper/Cargo.toml
index 8939b4b876..2e42bb5405 100644
--- a/rust/build-helper/Cargo.toml
+++ b/rust/build-helper/Cargo.toml
@@ -4,3 +4,8 @@ version = "0.1.0"
edition = "2021"
[dependencies]
+cbindgen = "0.24.0"
+textwrap = "=0.16.1"
+once_cell = "=1.20.3"
+unicode-width = "=0.1.13"
+
diff --git a/rust/build-helper/src/lib.rs b/rust/build-helper/src/lib.rs
index 70e95d16f5..640bc19734 100644
--- a/rust/build-helper/src/lib.rs
+++ b/rust/build-helper/src/lib.rs
@@ -1,5 +1,7 @@
use std::collections::HashMap;
+use std::io::Write;
use std::path::PathBuf;
+use cbindgen::Config;
fn parse_bool_from_str(value: &str) -> bool {
@@ -23,12 +25,20 @@ fn parse_bool_from_option(value: Option<&String>, default: bool) -> bool {
/// To run tests set GIT_BUILD_DIR and run `USE_LINKING=true cargo test`
pub struct BuildHelper {
crate_env: HashMap<String, String>,
+ generate_header: bool,
+ file_out: PathBuf,
+ config: Config,
}
impl BuildHelper {
pub fn new(crate_env: HashMap<String, String>) -> Self {
- let it = Self {crate_env};
+ let mut it = Self {
+ crate_env,
+ generate_header: false,
+ file_out: PathBuf::default(),
+ config: Config::default(),
+ };
let dir_crate = it.dir_crate();
let dir_workspace = dir_crate.parent().unwrap();
@@ -38,6 +48,12 @@ impl BuildHelper {
std::fs::create_dir(dir_interop.clone()).unwrap();
}
+ let file_cbindgen = dir_workspace.join("cbindgen-template.toml");
+ it.file_out = dir_interop.join(format!("{}.h", it.crate_name()));
+
+ it.config = Config::from_file(file_cbindgen.display().to_string().as_str()).unwrap();
+ it.config.include_guard = Some(format!("{}_H", it.crate_name().to_uppercase()));
+
it
}
@@ -49,6 +65,16 @@ impl BuildHelper {
PathBuf::from(self.crate_env["CARGO_MANIFEST_DIR"].clone())
}
+ pub fn generate_header<F>(mut self, editor: F) -> Self
+ where
+ F: Fn(&mut Config)
+ {
+ self.generate_header = true;
+ editor(&mut self.config);
+
+ self
+ }
+
pub fn build(self) {
let use_linking = parse_bool_from_option(self.crate_env.get("USE_LINKING"), self.crate_env.get("CARGO_TARGET_DIR").is_none());
let dir_crate = self.dir_crate();
@@ -78,6 +104,22 @@ impl BuildHelper {
} else {
println!("cargo:warning={} is not linking against C objects, `USE_LINKING=true cargo test`", self.crate_env["CARGO_PKG_NAME"]);
}
+
+ if self.generate_header {
+ let mut buffer = Vec::<u8>::new();
+ cbindgen::Builder::new()
+ .with_crate(dir_crate.clone())
+ .with_config(self.config)
+ .with_std_types(true)
+ .generate()
+ .expect("Unable to generate bindings")
+ .write(&mut buffer);
+
+ let mut fd = std::fs::File::create(self.file_out).unwrap();
+ fd.write(buffer.as_slice()).unwrap();
+ } else {
+ let _ = std::fs::remove_file(self.file_out);
+ }
}
}
diff --git a/rust/cbindgen-template.toml b/rust/cbindgen-template.toml
new file mode 100644
index 0000000000..cab83218d0
--- /dev/null
+++ b/rust/cbindgen-template.toml
@@ -0,0 +1,16 @@
+## compat/posix.h includes stdbool.h where git-compat-util.h does not
+## this is mandatory for correct bool C <-> Rust interop. Though the
+## 'includes' (and all other variables in this file) can be
+## overridden in build.rs.
+sys_includes = ["compat/posix.h"]
+
+autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
+
+language = "C"
+no_includes = true
+usize_is_size_t = true
+style = "tag"
+tab_width = 4
+
+[parse]
+parse_deps = false
--
gitgitgadget