rust-bindgen
rust-bindgen copied to clipboard
build.rs, Builder and no tests?
Just following the tut and notice no tests at the cargo test
stage? There was when I ran bindgen
by hand like so:
$ bindgen --allowlist-function "sentrypeer_config_new|sentrypeer_config_destroy" \
conf.h -o ../sentrypeer_rust/src/sentrypeer_c/config.rs
$ bindgen sip_message_event.h
-o ../sentrypeer_rust/src/sentrypeer_c/sip_message_event.rs
$ bindgen --allowlist-function "sip_log_event" sip_daemon.h \
-o ../sentrypeer_rust/src/sentrypeer_c/sip_daemon.rs
Here are the ones I generated by hand:
- https://github.com/SentryPeer/SentryPeer/blob/main/sentrypeer_rust/src/sentrypeer_c/config.rs
- https://github.com/SentryPeer/SentryPeer/blob/main/sentrypeer_rust/src/sentrypeer_c/sip_daemon.rs
- https://github.com/SentryPeer/SentryPeer/blob/main/sentrypeer_rust/src/sentrypeer_c/sip_message_event.rs
Input C/C++ Header
wrapper.h
:
#include "../src/conf.h"
#include "../src/sip_message_event.h"
#include "../src/sip_daemon.h"
https://github.com/SentryPeer/SentryPeer/blob/main/src/conf.h https://github.com/SentryPeer/SentryPeer/blob/main/src/sip_message_event.h https://github.com/SentryPeer/SentryPeer/blob/main/src/sip_daemon.h
Bindgen Invocation
use std::env;
use std::path::PathBuf;
fn main() {
// Tell cargo to tell rustc to link the sentrypeer
// shared library and how to find it
println!("cargo:rustc-link-search=../.libs");
println!("cargo:rustc-link-lib=sentrypeer");
// Our other dependencies
println!("cargo:rustc-link-lib=opendht-c");
println!("cargo:rustc-link-lib=jansson");
println!("cargo:rustc-link-lib=uuid");
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
let bindings = bindgen::Builder::default()
// The input header we would like to generate
// bindings for.
.header("wrapper.h")
// Pick the functions we want to generate bindings for
.allowlist_function("sentrypeer_config_new|sentrypeer_config_destroy")
.allowlist_function("sip_message_event_new|sip_message_event_destroy")
.allowlist_function("sip_log_event")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
// Finish the builder and generate the bindings.
.generate()
// Unwrap the Result and panic on failure.
.expect("Unable to generate bindings");
// Write the bindings to the $OUT_DIR/bindings.rs file.
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}
My lib.rs
;
// Use the include! macro to dump our generated bindings right into our crate's main entry point,
// src/lib.rs:
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
My bindings.rs
:
/* automatically generated by rust-bindgen 0.70.1 */
pub type pthread_t = ::std::os::raw::c_ulong;
pub type sa_family_t = ::std::os::raw::c_ushort;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct sockaddr {
pub sa_family: sa_family_t,
pub sa_data: [::std::os::raw::c_char; 14usize],
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of sockaddr"][::std::mem::size_of::<sockaddr>() - 16usize];
["Alignment of sockaddr"][::std::mem::align_of::<sockaddr>() - 2usize];
["Offset of field: sockaddr::sa_family"][::std::mem::offset_of!(sockaddr, sa_family) - 0usize];
["Offset of field: sockaddr::sa_data"][::std::mem::offset_of!(sockaddr, sa_data) - 2usize];
};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct dht_infohash {
pub d: [u8; 20usize],
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of dht_infohash"][::std::mem::size_of::<dht_infohash>() - 20usize];
["Alignment of dht_infohash"][::std::mem::align_of::<dht_infohash>() - 1usize];
["Offset of field: dht_infohash::d"][::std::mem::offset_of!(dht_infohash, d) - 0usize];
};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct dht_op_token {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct dht_runner {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct sentrypeer_config {
pub api_mode: bool,
pub bgp_agent_mode: bool,
pub debug_mode: bool,
pub json_log_mode: bool,
pub p2p_dht_mode: bool,
pub sip_agent_mode: bool,
pub sip_mode: bool,
pub sip_responsive_mode: bool,
pub syslog_mode: bool,
pub verbose_mode: bool,
pub webhook_mode: bool,
pub webhook_url: *mut ::std::os::raw::c_char,
pub oauth2_mode: bool,
pub oauth2_client_id: *mut ::std::os::raw::c_char,
pub oauth2_client_secret: *mut ::std::os::raw::c_char,
pub oauth2_access_token: *mut ::std::os::raw::c_char,
pub db_file: *mut ::std::os::raw::c_char,
pub json_log_file: *mut ::std::os::raw::c_char,
pub node_id: *mut ::std::os::raw::c_char,
pub p2p_bootstrap_node: *mut ::std::os::raw::c_char,
pub sip_daemon_thread: pthread_t,
pub http_daemon: *mut MHD_Daemon,
pub dht_node: *mut dht_runner,
pub dht_info_hash: *mut dht_infohash,
pub dht_op_token: *mut dht_op_token,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of sentrypeer_config"][::std::mem::size_of::<sentrypeer_config>() - 128usize];
["Alignment of sentrypeer_config"][::std::mem::align_of::<sentrypeer_config>() - 8usize];
["Offset of field: sentrypeer_config::api_mode"]
[::std::mem::offset_of!(sentrypeer_config, api_mode) - 0usize];
["Offset of field: sentrypeer_config::bgp_agent_mode"]
[::std::mem::offset_of!(sentrypeer_config, bgp_agent_mode) - 1usize];
["Offset of field: sentrypeer_config::debug_mode"]
[::std::mem::offset_of!(sentrypeer_config, debug_mode) - 2usize];
["Offset of field: sentrypeer_config::json_log_mode"]
[::std::mem::offset_of!(sentrypeer_config, json_log_mode) - 3usize];
["Offset of field: sentrypeer_config::p2p_dht_mode"]
[::std::mem::offset_of!(sentrypeer_config, p2p_dht_mode) - 4usize];
["Offset of field: sentrypeer_config::sip_agent_mode"]
[::std::mem::offset_of!(sentrypeer_config, sip_agent_mode) - 5usize];
["Offset of field: sentrypeer_config::sip_mode"]
[::std::mem::offset_of!(sentrypeer_config, sip_mode) - 6usize];
["Offset of field: sentrypeer_config::sip_responsive_mode"]
[::std::mem::offset_of!(sentrypeer_config, sip_responsive_mode) - 7usize];
["Offset of field: sentrypeer_config::syslog_mode"]
[::std::mem::offset_of!(sentrypeer_config, syslog_mode) - 8usize];
["Offset of field: sentrypeer_config::verbose_mode"]
[::std::mem::offset_of!(sentrypeer_config, verbose_mode) - 9usize];
["Offset of field: sentrypeer_config::webhook_mode"]
[::std::mem::offset_of!(sentrypeer_config, webhook_mode) - 10usize];
["Offset of field: sentrypeer_config::webhook_url"]
[::std::mem::offset_of!(sentrypeer_config, webhook_url) - 16usize];
["Offset of field: sentrypeer_config::oauth2_mode"]
[::std::mem::offset_of!(sentrypeer_config, oauth2_mode) - 24usize];
["Offset of field: sentrypeer_config::oauth2_client_id"]
[::std::mem::offset_of!(sentrypeer_config, oauth2_client_id) - 32usize];
["Offset of field: sentrypeer_config::oauth2_client_secret"]
[::std::mem::offset_of!(sentrypeer_config, oauth2_client_secret) - 40usize];
["Offset of field: sentrypeer_config::oauth2_access_token"]
[::std::mem::offset_of!(sentrypeer_config, oauth2_access_token) - 48usize];
["Offset of field: sentrypeer_config::db_file"]
[::std::mem::offset_of!(sentrypeer_config, db_file) - 56usize];
["Offset of field: sentrypeer_config::json_log_file"]
[::std::mem::offset_of!(sentrypeer_config, json_log_file) - 64usize];
["Offset of field: sentrypeer_config::node_id"]
[::std::mem::offset_of!(sentrypeer_config, node_id) - 72usize];
["Offset of field: sentrypeer_config::p2p_bootstrap_node"]
[::std::mem::offset_of!(sentrypeer_config, p2p_bootstrap_node) - 80usize];
["Offset of field: sentrypeer_config::sip_daemon_thread"]
[::std::mem::offset_of!(sentrypeer_config, sip_daemon_thread) - 88usize];
["Offset of field: sentrypeer_config::http_daemon"]
[::std::mem::offset_of!(sentrypeer_config, http_daemon) - 96usize];
["Offset of field: sentrypeer_config::dht_node"]
[::std::mem::offset_of!(sentrypeer_config, dht_node) - 104usize];
["Offset of field: sentrypeer_config::dht_info_hash"]
[::std::mem::offset_of!(sentrypeer_config, dht_info_hash) - 112usize];
["Offset of field: sentrypeer_config::dht_op_token"]
[::std::mem::offset_of!(sentrypeer_config, dht_op_token) - 120usize];
};
extern "C" {
pub fn sentrypeer_config_new() -> *mut sentrypeer_config;
}
extern "C" {
pub fn sentrypeer_config_destroy(self_ptr: *mut *mut sentrypeer_config);
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct sip_message_event {
pub packet: *mut ::std::os::raw::c_char,
pub packet_len: usize,
pub socket: ::std::os::raw::c_int,
pub transport_type: *mut ::std::os::raw::c_char,
pub client_ip_addr: *mut sockaddr,
pub client_ip_addr_str: *mut ::std::os::raw::c_char,
pub client_addr_len: usize,
pub dest_ip_addr_str: *mut ::std::os::raw::c_char,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
["Size of sip_message_event"][::std::mem::size_of::<sip_message_event>() - 64usize];
["Alignment of sip_message_event"][::std::mem::align_of::<sip_message_event>() - 8usize];
["Offset of field: sip_message_event::packet"]
[::std::mem::offset_of!(sip_message_event, packet) - 0usize];
["Offset of field: sip_message_event::packet_len"]
[::std::mem::offset_of!(sip_message_event, packet_len) - 8usize];
["Offset of field: sip_message_event::socket"]
[::std::mem::offset_of!(sip_message_event, socket) - 16usize];
["Offset of field: sip_message_event::transport_type"]
[::std::mem::offset_of!(sip_message_event, transport_type) - 24usize];
["Offset of field: sip_message_event::client_ip_addr"]
[::std::mem::offset_of!(sip_message_event, client_ip_addr) - 32usize];
["Offset of field: sip_message_event::client_ip_addr_str"]
[::std::mem::offset_of!(sip_message_event, client_ip_addr_str) - 40usize];
["Offset of field: sip_message_event::client_addr_len"]
[::std::mem::offset_of!(sip_message_event, client_addr_len) - 48usize];
["Offset of field: sip_message_event::dest_ip_addr_str"]
[::std::mem::offset_of!(sip_message_event, dest_ip_addr_str) - 56usize];
};
extern "C" {
pub fn sip_message_event_new(
packet: *mut ::std::os::raw::c_char,
packet_len: usize,
socket: ::std::os::raw::c_int,
transport_type: *mut ::std::os::raw::c_char,
client_ip_addr: *mut sockaddr,
client_ip_addr_str: *mut ::std::os::raw::c_char,
client_ip_addr_len: usize,
dest_ip_addr_str: *mut ::std::os::raw::c_char,
) -> *mut sip_message_event;
}
extern "C" {
pub fn sip_message_event_destroy(self_ptr: *mut *mut sip_message_event);
}
extern "C" {
pub fn sip_log_event(
config: *mut sentrypeer_config,
sip_event: *const sip_message_event,
) -> ::std::os::raw::c_int;
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct MHD_Daemon {
pub _address: u8,
}
Expected Results
$ cargo test
to show layout tests like before?
Thanks.