Skip to content

Commit

Permalink
Configure callbacks for bindgen
Browse files Browse the repository at this point in the history
The bindgen 0.63.0 version needs callbacks configured as the
generated bindings has wrong types.

Signed-off-by: Gowtham Suresh Kumar <[email protected]>
  • Loading branch information
gowthamsk-arm committed Mar 13, 2023
1 parent f995ce8 commit adc05a9
Showing 1 changed file with 76 additions and 27 deletions.
103 changes: 76 additions & 27 deletions cryptoki-sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Copyright 2021 Contributors to the Parsec project.
// Copyright 2021,2023 Contributors to the Parsec project.
// SPDX-License-Identifier: Apache-2.0
fn main() {
#[cfg(feature = "generate-bindings")]
{
generate_bindings();
generate::generate_bindings();
}

#[cfg(not(feature = "generate-bindings"))]
Expand Down Expand Up @@ -33,30 +33,79 @@ fn main() {

// Only on a specific feature
#[cfg(feature = "generate-bindings")]
fn generate_bindings() {
let bindings = bindgen::Builder::default()
.header("pkcs11.h")
.dynamic_library_name("Pkcs11")
// The PKCS11 library works in a slightly different way to most shared libraries. We have
// to call `C_GetFunctionList`, which returns a list of pointers to the _actual_ library
// functions. This is the only function we need to create a binding for.
.allowlist_function("C_GetFunctionList")
// This is needed because no types will be generated if `allowlist_function` is used.
// Unsure if this is a bug.
.allowlist_type("*")
// See this issue: https://github.com/parallaxsecond/rust-cryptoki/issues/12
.blocklist_type("max_align_t")
// Derive the `Debug` trait for the generated structs where possible.
.derive_debug(true)
// Derive the `Default` trait for the generated structs where possible.
.derive_default(true)
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.expect("Unable to generate bindings");
mod generate {
use bindgen::callbacks;
#[derive(Debug)]
pub struct CargoCallbacks;

// Write the bindings to the $OUT_DIR/pkcs11_bindings.rs file.
let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("pkcs11_bindings.rs"))
.expect("Couldn't write bindings!");
impl callbacks::ParseCallbacks for CargoCallbacks {
fn int_macro(&self, name: &str, _: i64) -> Option<callbacks::IntKind> {
let prefixes = [
("CK_", "CK_ULONG"),
("CKA_", "CK_ATTRIBUTE_TYPE"),
("CKC_", "CK_CERTIFICATE_TYPE"),
("CKD_", "CK_EC_KDF_TYPE"),
("CKF_", "CK_FLAGS"),
("CKG_MGF1_", "CK_RSA_PKCS_MGF_TYPE"),
("CKH_", "CK_HW_FEATURE_TYPE"),
("CKK_", "CK_KEY_TYPE"),
("CKM_", "CK_MECHANISM_TYPE"),
("CKN_", "CK_NOTIFICATION"),
("CKO_", "CK_OBJECT_CLASS"),
("CKP_", "CK_PROFILE_ID"),
("CKR_", "CK_RV"),
("CKS_", "CK_STATE"),
("CKU_", "CK_USER_TYPE"),
("CKZ_", "CK_RSA_PKCS_OAEP_SOURCE_TYPE"),
("CRYPTOKI_VERSION_", "CK_BYTE"),
];

if ["CK_TRUE", "CK_FALSE"].contains(&name) {
Some(callbacks::IntKind::Custom {
name: "CK_BBOOL",
is_signed: false,
})
} else {
let mut result = None;
for (prefix, variable) in &prefixes {
if name.starts_with(prefix) {
result = Some(callbacks::IntKind::Custom {
name: variable,
is_signed: false,
})
}
}
result
}
}
}

pub fn generate_bindings() {
let bindings = bindgen::Builder::default()
.header("pkcs11.h")
.dynamic_library_name("Pkcs11")
// The PKCS11 library works in a slightly different way to most shared libraries. We have
// to call `C_GetFunctionList`, which returns a list of pointers to the _actual_ library
// functions. This is the only function we need to create a binding for.
.allowlist_function("C_GetFunctionList")
// This is needed because no types will be generated if `allowlist_function` is used.
// Unsure if this is a bug.
.allowlist_type("*")
.allowlist_file("pkcs11.h")
// See this issue: https://github.com/parallaxsecond/rust-cryptoki/issues/12
.blocklist_type("max_align_t")
// Derive the `Debug` trait for the generated structs where possible.
.derive_debug(true)
// Derive the `Default` trait for the generated structs where possible.
.derive_default(true)
.parse_callbacks(Box::new(CargoCallbacks))
.generate()
.expect("Unable to generate bindings");

// Write the bindings to the $OUT_DIR/pkcs11_bindings.rs file.
let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("pkcs11_bindings.rs"))
.expect("Couldn't write bindings!");
}
}

0 comments on commit adc05a9

Please sign in to comment.