From c484777f3a7dde9e9fe8f47344fd8a6b30840b78 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Tue, 22 Sep 2020 19:09:40 +0200 Subject: Add feature to generate bindings during build This patch adds the bindgen feature to the crate that allows users to re-generate the bindings, including layout tests, during the build instead of using the pre-generated bindings. Per default, this feature is disabled. --- CHANGELOG.md | 2 ++ Cargo.toml | 4 ++++ Makefile | 1 + README.md | 7 +++++++ build.rs | 32 ++++++++++++++++++++++++++++++++ src/lib.rs | 5 +++++ 6 files changed, 51 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8efd48c..5991614 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ - Implement `std::fmt::Display` instead of `std::string::ToString` for the `Version` enum in `build.rs`. - Do not include layout tests in the generated bindings. +- Add `bindgen` feature that re-generates the bindings during the build, + including layout tests. - Update to libnitrokey 3.6, causing all following changes. - New constants: - `NK_device_model_NK_LIBREM` (`NK_device_model` enum) diff --git a/Cargo.toml b/Cargo.toml index 068670b..99b2afd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,4 +13,8 @@ build = "build.rs" readme = "README.md" [build-dependencies] +bindgen = { version = "0.55.1", optional = true } cc = "1.0" + +[features] +default = [] diff --git a/Makefile b/Makefile index b5fec75..b0b5bba 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ LIBNITROKEY ?= $(wildcard libnitrokey-v*) src/ffi.rs: ${LIBNITROKEY}/NK_C_API.h quilt pop -af || true + # always keep options in sync with build.rs ${BINDGEN} \ --whitelist-function "NK_.*" \ --whitelist-var "NK_.*" \ diff --git a/README.md b/README.md index 343b7b5..2646a33 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,13 @@ crate, it links directly against `libnitrokey` instead of building it from source. In this case, `libnitrokey` must be available in the library search path. +Per default, this crate uses bindings that have been generated using Rust’s +`x86_64-unknown-linux-gnu` target. To the best of our knowledge, these +bindings are platform-independent. If you want to generate the bindings, +including layout tests, specifically for your platform during the build, +activate the `bindgen` feature. In this case, you will also need `clang` and +`libclang` in the default search path. + ## Versioning The major and minor version of the `nitrokey-sys` crate map to the major and diff --git a/build.rs b/build.rs index a6ae9fc..d097021 100644 --- a/build.rs +++ b/build.rs @@ -54,6 +54,35 @@ fn prepare_version_source( Ok(out) } +#[cfg(feature = "bindgen")] +fn generate_bindings(library_path: &path::Path, out_path: &path::Path) { + let header_path = library_path.join("NK_C_API.h"); + let header_str = header_path + .to_str() + .expect("Header path contains invalid UTF-8"); + + let include_path = library_path.join("libnitrokey"); + let include_str = include_path + .to_str() + .expect("Include path contains invalid UTF-8"); + + println!("cargo:rerun-if-changed={}", header_str); + + // always keep options in sync with Makefile + let bindings = bindgen::Builder::default() + .header(header_str) + .whitelist_function("NK_.*") + .whitelist_var("NK_.*") + .whitelist_var("MAXIMUM_STR_REPLY_LENGTH") + .derive_default(true) + .clang_arg(&format!("-I{}", include_str)) + .generate() + .expect("Unable to generate bindings"); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Could not write bindings"); +} + fn main() { if env::var("USE_SYSTEM_LIBNITROKEY").is_ok() { println!("cargo:rustc-link-lib=nitrokey"); @@ -78,6 +107,9 @@ fn main() { let version_source = prepare_version_source(LIBNITROKEY_VERSION, &out_path, &library_path) .expect("Could not prepare the version source file"); + #[cfg(feature = "bindgen")] + generate_bindings(library_path, &out_path); + cc::Build::new() .cpp(true) .flag("-std=c++14") diff --git a/src/lib.rs b/src/lib.rs index a179da8..81a98bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,10 +2,15 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] +#[cfg(not(feature = "bindgen"))] mod ffi; +#[cfg(not(feature = "bindgen"))] pub use crate::ffi::*; +#[cfg(feature = "bindgen")] +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + #[cfg(test)] mod tests { use super::*; -- cgit v1.2.1