New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Private padding and alignment fields + missing Defaut/Clone/Copy implementations #2782
Comments
Could you create a reduced test-case? I suspect something weird is going on, because bindgen padding looks like |
Or like, something that I can run locally at least :) |
Sure, here is an example: # Cargo.toml
[package]
name = "buggy-crate"
version = "0.1.0"
edition = "2021"
[build-dependencies]
bindgen = "0.69.4"
pkg-config = "0.3.30" // build.rs
use std::{env, iter, path::PathBuf};
pub static FUSE_VERSION: u32 = 316;
pub static FUSE_LIBNAME: &str = "fuse3";
fn fuse_binding_filter(builder: bindgen::Builder) -> bindgen::Builder {
let mut builder = builder
// Whitelist "fuse_*" symbols and blocklist everything else
.allowlist_recursively(false)
.allowlist_type("[fF][uU][sS][eE].*")
.allowlist_function("[fF][uU][sS][eE].*")
.allowlist_var("[fF][uU][sS][eE].*")
.blocklist_type("fuse_log_func_t")
.blocklist_function("fuse_set_log_func");
// TODO: properly bind fuse_log_func_t and allowlist fuse_set_log_func again
if cfg!(target_os = "macos") {
// osxfuse needs this type
builder = builder.allowlist_type("setattr_x");
}
builder
}
fn cuse_binding_filter(builder: bindgen::Builder) -> bindgen::Builder {
builder
// Whitelist "cuse_*" symbols and blocklist everything else
.allowlist_recursively(false)
.allowlist_type("[cC][uU][sS][eE].*")
.allowlist_function("[cC][uU][sS][eE].*")
.allowlist_var("[cC][uU][sS][eE].*")
}
fn generate_fuse_bindings(
header: &str,
fuse_lib: &pkg_config::Library,
binding_filter: fn(bindgen::Builder) -> bindgen::Builder,
) {
// Find header file
let mut header_path: Option<PathBuf> = None;
for include_path in fuse_lib.include_paths.iter() {
let test_path = include_path.join(header);
if test_path.exists() {
header_path = Some(test_path);
break;
}
}
let header_path = header_path
.unwrap_or_else(|| panic!("Cannot find {}", header))
.to_str()
.unwrap_or_else(|| panic!("Path to {} contains invalid unicode characters", header))
.to_string();
// Gather fuse defines
let defines = fuse_lib.defines.iter().map(|(key, val)| match val {
Some(val) => format!("-D{}={}", key, val),
None => format!("-D{}", key),
});
// Gather include paths
let includes = fuse_lib
.include_paths
.iter()
.map(|dir| format!("-I{}", dir.display()));
// API version definition
let api_define = iter::once(format!("-DFUSE_USE_VERSION={FUSE_VERSION}"));
// Chain compile flags
let compile_flags = defines.chain(includes).chain(api_define);
// Create bindgen builder
let mut builder = bindgen::builder()
// Add clang flags
.clang_args(compile_flags)
// Derive Debug, Copy and Default
.derive_default(true)
.derive_copy(true)
.derive_debug(true)
// Add CargoCallbacks so build.rs is rerun on header changes
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()));
builder = binding_filter(builder);
// Generate bindings
let bindings = builder
.header(header_path)
.generate()
.unwrap_or_else(|_| panic!("Failed to generate {} bindings", header));
// Write bindings to file
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let bindings_path = out_dir.join(header.replace(".h", ".rs"));
bindings
.write_to_file(&bindings_path)
.unwrap_or_else(|_| panic!("Failed to write {}", bindings_path.display()));
}
fn main() {
let mut pkgcfg = pkg_config::Config::new();
pkgcfg.cargo_metadata(false);
// Find libfuse
let fuse_lib = pkgcfg
.cargo_metadata(true)
.probe(FUSE_LIBNAME)
.unwrap_or_else(|err| panic!("Failed to find pkg-config module {FUSE_LIBNAME} ({err})"));
// Generate highlevel bindings
generate_fuse_bindings("fuse.h", &fuse_lib, fuse_binding_filter);
// Generate lowlevel bindings
generate_fuse_bindings("fuse_lowlevel.h", &fuse_lib, fuse_binding_filter);
// Generate lowlevel cuse bindings
generate_fuse_bindings("cuse_lowlevel.h", &fuse_lib, cuse_binding_filter);
} Note: you need to have both pkg-config and libfuse-dev installed. Run this, and it will generate three bindings files in |
Input C/C++ Header
Bindgen Invocation
Actual Results
Expected Results
__pad0
and__unused
should be marked aspub
Default
,Clone
andCopy
are missingThe same problems occur on many other structs.
The text was updated successfully, but these errors were encountered: