use std::env;
use std::path::{Path, PathBuf};
fn main() {
let rustbuilthdr_base;
if std::env::var("DOCS_RS").is_ok() {
rustbuilthdr_base = PathBuf::from("./dummy-platform/");
} else {
rustbuilthdr_base = PathBuf::from(env::var("OUT_DIR").unwrap()).join("rust-built-headers");
run_cbindgen(&rustbuilthdr_base);
};
println!(
"cargo:PLATFORMHEADERS={}",
rustbuilthdr_base
.to_str()
.expect("Please use paths tha are also strings")
);
let liboscore_includes = Path::new("c-src/include/");
assert!(
liboscore_includes.join("oscore/message.h").exists(),
"libOSCORE headers are not avaialble at {}",
liboscore_includes.display()
);
assert!(
rustbuilthdr_base.join("oscore_native/msg_type.h").exists(),
"libOSCORE platform headers are not avaialble at {}",
rustbuilthdr_base.display()
);
run_bindgen(liboscore_includes, &rustbuilthdr_base);
bundle_staticlib(&rustbuilthdr_base)
}
fn run_bindgen(liboscore_include: &Path, platform_include: &Path) {
bindgen::Builder::default()
.clang_arg("-std=c99")
.clang_arg(format!("-I{}", liboscore_include.to_str().unwrap()))
.clang_arg(format!("-I{}", platform_include.to_str().unwrap()))
.clang_arg("-fvisibility=default")
.use_core()
.derive_copy(false)
.derive_debug(false)
.blocklist_type("oscore_msg_native_t")
.blocklist_type("oscore_msgerr_native_t")
.blocklist_type("oscore_crypto_aead_decryptstate_t")
.blocklist_type("oscore_crypto_aead_encryptstate_t")
.allowlist_function("oscore_cryptoerr_is_error") .allowlist_function("oscore_msg_protected_get_code")
.allowlist_function("oscore_msg_protected_map_payload")
.allowlist_function("oscore_msgerr_protected_is_error")
.allowlist_function("oscore_unprotect_request")
.allowlist_function("oscore_oscoreoption_parse")
.allowlist_function("oscore_crypto_aead_from_number")
.allowlist_function("oscore_crypto_hkdf_from_number")
.allowlist_function("oscore_msg_protected_optiter_init")
.allowlist_function("oscore_msg_protected_optiter_next")
.allowlist_function("oscore_msg_protected_optiter_finish")
.allowlist_function("oscore_context_primitive_derive")
.allowlist_function("oscore_crypto_aead_get_ivlength")
.allowlist_function("oscore_prepare_request")
.allowlist_function("oscore_encrypt_message")
.allowlist_function("oscore_msg_protected_trim_payload")
.allowlist_function("oscore_msg_protected_append_option")
.allowlist_function("oscore_msg_protected_set_code")
.allowlist_function("oscore_release_unprotected")
.allowlist_function("oscore_prepare_response")
.allowlist_function("oscore_msgerr_native_is_error")
.allowlist_function("oscore_msg_native_map_payload")
.allowlist_function("oscore_unprotect_response")
.allowlist_type("oscore_msgerr_protected_t")
.allowlist_type("oscore_msg_protected_t")
.allowlist_type("oscore_msg_protected_optiter_t")
.allowlist_type("oscore_unprotect_request_result")
.allowlist_type("oscore_context_primitive")
.allowlist_type("oscore_context_primitive_immutables")
.allowlist_type("oscore_")
.allowlist_var("OSCORE_KEYIDCONTEXT_MAXLEN")
.allowlist_var("IV_KEYID_UNUSABLE")
.allowlist_var("OSCORE_KEYID_MAXLEN")
.allowlist_var("PIV_BYTES")
.allowlist_var("OSCORE_CRYPTO_AEAD_IV_MAXLEN")
.header("oscore_all_headers.h")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("bindgen failed")
.write_to_file(PathBuf::from(env::var("OUT_DIR").unwrap()).join("bindings.rs"))
.expect("writing bindings.rs failed");
}
fn run_cbindgen(rustbuilthdr_base: &Path) {
let rustbuilthdr_dir = rustbuilthdr_base.join("oscore_native");
std::fs::create_dir_all(&rustbuilthdr_dir).unwrap();
let cratedir_cryptobackend;
let cratedir_msgbackend;
let our_dir = std::env::current_dir().unwrap();
let our_dir = our_dir
.file_name()
.unwrap()
.to_str()
.expect("No non-Unicode characters in crate names please");
let our_dir_suffix = our_dir.strip_prefix("liboscore-");
match (our_dir, our_dir_suffix) {
("liboscore", _) => {
cratedir_cryptobackend = "../../rust/liboscore-cryptobackend".to_string();
cratedir_msgbackend = "../../rust/liboscore-msgbackend".to_string();
}
(_, Some(suffix)) => {
cratedir_cryptobackend = format!("../liboscore-cryptobackend-{}", suffix);
cratedir_msgbackend = format!("../liboscore-msgbackend-{}", suffix);
}
(our_dir, _) => panic!(
"Can not find matching backends for own directory {:?}",
our_dir
),
}
cbindgen::Builder::new()
.with_crate(&cratedir_cryptobackend)
.with_config(
cbindgen::Config::from_file(format!("{cratedir_cryptobackend}/cbindgen.toml")).unwrap(),
)
.generate()
.expect("Failure generating cbindgen headers for the cryptobackend")
.write_to_file(rustbuilthdr_dir.join("crypto_type.h"));
cbindgen::Builder::new()
.with_crate(&cratedir_msgbackend)
.with_config(
cbindgen::Config::from_file(format!("{cratedir_msgbackend}/cbindgen.toml")).unwrap(),
)
.with_language(cbindgen::Language::C)
.generate()
.expect("Failure generating cbindgen headers for the msgbackend")
.write_to_file(rustbuilthdr_dir.join("msg_type.h"));
}
fn bundle_staticlib(rustbuilthdr_base: &Path) {
cc::Build::new()
.include("c-src/include/")
.include(".")
.include(rustbuilthdr_base.to_str().unwrap())
.file("c-src/contextpair.c")
.file("c-src/oscore_message.c")
.file("c-src/protection.c")
.file("c-src/context_primitive.c")
.compile("liboscore_static_objects");
}