cbindgen
cbindgen copied to clipboard
Binding generation fails when generic struct is aliased
It looks like this happens when there is a generic struct in one module and a non-generic struct in another module, and you want to generate bindings for that non-generic struct. I have an example project here with these contents:
───────┬───────────────────────────────────────────────────────────────────
│ File: src/ffi.rs
───────┼───────────────────────────────────────────────────────────────────
1 │ type SomeType = super::MyStruct<u32>;
2 │
3 │ #[repr(C)]
4 │ pub struct MyStruct;
5 │
6 │ #[no_mangle]
7 │ pub extern "C" fn use_mystruct(my_struct: *mut MyStruct) {
8 │ }
───────┴───────────────────────────────────────────────────────────────────
───────┬───────────────────────────────────────────────────────────────────
│ File: src/lib.rs
───────┼───────────────────────────────────────────────────────────────────
1 │ pub mod ffi;
2 │
3 │ pub struct MyStruct<T> {
4 │ t: T,
5 │ }
───────┴───────────────────────────────────────────────────────────────────
───────┬───────────────────────────────────────────────────────────────────
│ File: build.rs
───────┼───────────────────────────────────────────────────────────────────
1 │ extern crate cbindgen;
2 │
3 │ use std::env;
4 │ use cbindgen::Language;
5 │
6 │ fn main() {
7 │ let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
8 │
9 │ cbindgen::Builder::new()
10 │ .with_crate(crate_dir)
11 │ .with_language(Language::C)
12 │ .generate()
13 │ .expect("Unable to generate bindings")
14 │ .write_to_file("bindings.h");
15 │ }
───────┴───────────────────────────────────────────────────────────────────
And I get this error:
allen@allen-XPS-13-9370 ~/s/cbindgen_bug> env RUST_BACKTRACE=1 cargo build
Compiling cbindgen_bug v0.1.0 (/home/allen/scratch/cbindgen_bug)
error: failed to run custom build command for `cbindgen_bug v0.1.0 (/home/allen/scratch/cbindgen_bug)`
process didn't exit successfully: `/home/allen/scratch/cbindgen_bug/target/debug/build/cbindgen_bug-34f7bb810f197ece/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'MyStruct is not generic', /home/allen/.cargo/registry/src/github.com-1ecc6299db9ec823/cbindgen-0.7.1/src/bindgen/ir/structure.rs:290:9
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at src/libstd/sys_common/backtrace.rs:59
at src/libstd/panicking.rs:211
3: std::panicking::default_hook
at src/libstd/panicking.rs:227
4: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:491
5: std::panicking::continue_panic_fmt
at src/libstd/panicking.rs:398
6: std::panicking::begin_panic_fmt
at src/libstd/panicking.rs:353
7: <cbindgen::bindgen::ir::structure::Struct as cbindgen::bindgen::ir::item::Item>::instantiate_monomorph
at /home/allen/.cargo/registry/src/github.com-1ecc6299db9ec823/cbindgen-0.7.1/src/bindgen/ir/structure.rs:290
8: cbindgen::bindgen::ir::ty::Type::add_monomorphs
at /home/allen/.cargo/registry/src/github.com-1ecc6299db9ec823/cbindgen-0.7.1/src/bindgen/ir/ty.rs:535
9: cbindgen::bindgen::ir::typedef::Typedef::add_monomorphs
at /home/allen/.cargo/registry/src/github.com-1ecc6299db9ec823/cbindgen-0.7.1/src/bindgen/ir/typedef.rs:108
10: cbindgen::bindgen::library::Library::instantiate_monomorphs::{{closure}}
at /home/allen/.cargo/registry/src/github.com-1ecc6299db9ec823/cbindgen-0.7.1/src/bindgen/library.rs:363
11: <cbindgen::bindgen::ir::item::ItemMap<T>>::for_all_items
at /home/allen/.cargo/registry/src/github.com-1ecc6299db9ec823/cbindgen-0.7.1/src/bindgen/ir/item.rs:188
12: cbindgen::bindgen::library::Library::instantiate_monomorphs
at /home/allen/.cargo/registry/src/github.com-1ecc6299db9ec823/cbindgen-0.7.1/src/bindgen/library.rs:362
13: cbindgen::bindgen::library::Library::generate
at /home/allen/.cargo/registry/src/github.com-1ecc6299db9ec823/cbindgen-0.7.1/src/bindgen/library.rs:63
14: cbindgen::bindgen::builder::Builder::generate
at /home/allen/.cargo/registry/src/github.com-1ecc6299db9ec823/cbindgen-0.7.1/src/bindgen/builder.rs:345
15: build_script_build::main
at ./build.rs:9
16: std::rt::lang_start::{{closure}}
at /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b/src/libstd/rt.rs:74
17: std::panicking::try::do_call
at src/libstd/rt.rs:59
at src/libstd/panicking.rs:310
18: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:102
19: std::rt::lang_start_internal
at src/libstd/panicking.rs:289
at src/libstd/panic.rs:398
at src/libstd/rt.rs:58
20: std::rt::lang_start
at /rustc/9fda7c2237db910e41d6a712e9a2139b352e558b/src/libstd/rt.rs:74
21: main
22: __libc_start_main
23: _start
It's interesting that if I comment out line 1 of src/ffi.rs
, then the bug doesn't occur and binding generation happens as I'd expect.
So this is because cbindgen isn't able to follow paths, so it gets confused, and your MyStruct in ffi.rs is indeed not generic...
I think you can hack around this, fwiw, with something like:
// ffi.rs
pub use super::MyStruct as MyGenericStruct;
type SomeType = MyGenericStruct<i32>;
Yes, that seems to work. That'll be a good workaround for now. Thanks!
Underlying issue: #7