rust-bindgen
rust-bindgen copied to clipboard
bindgen fails to generate __bindgen_padding in some situations on AVR
This bug report has an example repo to aid in reproduction of the problem: https://github.com/mutantbob/bindgen-malfunction It does not seem to malfunction when generating in the native environment, but instead malfunctions when cross-compiling for AVR.
headers
base.h:
#ifndef Base_h_
#define Base_h_
class Base
{
private:
int maple;
public:
Base() : maple(7) {}
virtual int f() =0;
};
#endif Base_h_
alpha.h:
#include "base.h"
class Alpha: Base
{
#ifdef MALFUNCTION
int bar;
#else
short bar;
short bacon;
#endif
public:
int f() { return bar; }
};
Bindgen Invocation
use std::env;
use std::path::PathBuf;
use bindgen;
use bindgen::Builder;
pub trait BlocklistFileMulti {
fn blocklist_file_multi<T: AsRef<str>, I: IntoIterator<Item = T>>(self, iter: I) -> Self;
}
impl BlocklistFileMulti for bindgen::Builder {
fn blocklist_file_multi<T: AsRef<str>, I: IntoIterator<Item = T>>(self, iter: I) -> Self {
let mut builder = self;
for file in iter {
println!("# blocking file {}", file.as_ref());
builder = builder.blocklist_file(file)
}
builder
}
}
fn generate_bindings_generic<T: AsRef<str>, I: IntoIterator<Item = T>>(header: &str, out_basename: &str, excludes: I, malfunction:bool) {
println!("cargo:rerun-if-changed={}", header);
let bindings = make_builder_for(header)
.blocklist_file_multi(excludes)
.clang_args(if malfunction {
vec!["-DMALFUNCTION=1"]
} else {
vec![]
})
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let bindings_out_file = out_path.join(out_basename);
bindings
.write_to_file(bindings_out_file)
.expect("Couldn't write bindings!");
}
fn make_builder_for(header: &str) -> Builder {
bindgen::Builder::default()
.header(header)
.clang_args(&[
"-x",
"c++",
])
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.ctypes_prefix("cty")
.rustfmt_bindings(true)
}
fn main()
{
let blank : [&str;0] = [];
generate_bindings_generic("src-cpp/mixed.h", "mixed.rs", &blank, false);
generate_bindings_generic("src-cpp/alpha.h", "alpha.rs", &blank, false);
generate_bindings_generic("src-cpp/alpha.h", "alpha-minus.rs", vec!["src-cpp/base.h"], false);
generate_bindings_generic("src-cpp/alpha.h", "alpha-wrong.rs", vec!["src-cpp/base.h"], true);
}
Actual Results
#[repr(C)]
pub struct Alpha__bindgen_vtable(cty::c_void);
#[repr(C, packed)]
pub struct Alpha {
pub vtable_: *const Alpha__bindgen_vtable,
pub bar: cty::c_int,
}
Expected Results
#[repr(C)]
pub struct Alpha__bindgen_vtable(cty::c_void);
#[repr(C)]
pub struct Alpha {
pub vtable_: *const Alpha__bindgen_vtable,
pub __bindgen_padding_0: u16,
pub bar: cty::c_int,
}