Bindgen: automatically generate Rust FFI bindings to C and C++ libraries

We'll be using this thread to announce bindgen releases. Feel free to ask questions about the releases and bindgen in general here.


Announcing bindgen v0.29.0

bindgen automatically generates Rust FFI bindings to C and C++ libraries.

Upgrade to this release by updating your Cargo.toml:

bindgen = "0.29.0"

Changelog

Since this is the first post, I'm including some items that aren't strictly new changes in v0.29.0, but are recent changes nonetheless.

Added

  • "Constified enum modules" translating C/C++ enums into constants within a module for namespacing, rather than mangling the name of the generated constants.

    For example, it turns this:

    // bindgen-flags: --constified-enum-module PetKind
    
    enum PetKind {
        Doggo,
        Kitty,
        Hamster
    };
    
    struct Pet {
        PetKind kind;
        char* noise;
    };
    

    Into this:

    /* automatically generated by rust-bindgen */
    
    pub mod PetKind {
        pub type Type = ::std::os::raw::c_uint;
        pub const Doggo: Type = 0;
        pub const Kitty: Type = 1;
        pub const Hamster: Type = 2;
    }
    #[repr(C)]
    #[derive(Debug, Copy)]
    pub struct Pet {
        pub kind: PetKind::Type,
        pub noise: *mut ::std::os::raw::c_char,
    }
    

    The default translation strategy for enums will generate constants with names like PetKind_Hamster instead.

    Use bindgen::Builder::constified_enum_module or --constified-enum-module.

  • You can now mark particular template instantiations as "opaque", so that bindgen emits a blob of bytes with the correct size and alignment rather than creating generic Rust types. This is useful as a workaround for when a template has a specialization for the given type arguments, which bindgen does not yet support. Previously, it was all of a templates' instantiations would be opaque or none of them would be. Use bindgen::Builder::opaque_type("SomeTemplate<Foo, Bar>") or --opaque-type "SomeTemplate<Foo, Bar>".

  • Added the ability to preprocess and dump the input headers given to bindgen to a file. This should make creating reproducible, system independent, standalone test cases much easier! Bring on the new issues! Use bindgen::Builder::dump_preprocessed_input or --dump-preprocessed-input.

  • We now use a fix-point analysis to determine whether any given type can derive Debug, or whether it has an explicit virtual table pointer. Previously we were using an ad-hoc algorithm that had at various times suffered from things like going into infinite loops when coming across cycles. Hopefully those kinds of bugs are a thing of the past! #767 #765

Changed

Fixed

  • No longer generating layout tests for template instantiations using type arguments that we didn't generate bindings for (which then caused compilation errors). #679

  • Fixed function name mangling when cross compiling bindings for iOS. #776

  • Don't include parent inline namespaces' names in types' names. Names of types from some STLs were showing up like std___cxx11_basic_string when they should have been std_basic_string. #789

  • Fixed a bug where we wouldn't generate type definitions for some types referenced by an opaque type's methods, causing compilation errors. #807

  • Fixed function name mangling issues for win32 targets. #819

  • Fixed a bug where bindgen was generating a generic type alias that didn't use its type parameter, which is illegal Rust code and caused compilation errors. #820

  • The generated size, alignment, and field offset unit tests now have stable names rather than sometimes including an internal identifier which is inherently unstable. This was causing unnecessary diffs when folks were checking in new versions of bindings into their VCS. #394

  • Fixed a bug where we would try and derive(Debug, Default) on structs that had padding like [u8; 33], which is larger than the largest array length for which Rust will derive traits. This would cause compilation errors when compiling the emitted bindings. #648

Friends

Thanks to everyone who contributed to these last couple releases!

  • Dylan McKay
  • Emilio Cobos Álvarez
  • Holger Rapp
  • Kevin Lefevre
  • Manish Goregaokar
  • Nick Fitzgerald
  • Omar Akkila
  • Ralph Giles
  • Robin Lambertz
  • Shing Lyu
  • Travis Finkenauer
  • tz70s
  • UK992
  • Xidorn Quan
  • zzhu

Contributing

Want to join us? Check out our CONTRIBUTING.md and take a look at some of these issues:

Want to help improve our documentation? Check out the issues labeled "docs".

Found a bug with bindgen? File an issue here.

18 Likes

Announcing bindgen v0.30.0

bindgen automatically generates Rust FFI bindings to C and C++ libraries.

Upgrade to this release by updating your Cargo.toml:

bindgen = "0.30.0"

Changelog

Added

  • Explicit control over choosing which Rust version (specific stable versions or
    nightly Rust) to target. This defaults to the latest stable Rust version. #832
bindgen::Builder::default()
    .rust_target(bindgen::RustTarget::Stable_1_19)
    // or `.rust_target(bindgen::RustTarget::Nightly)` to use unstable features

or

$ bindgen --rust-target 1.19
# or `--rust-target nightly` to use unstable features
  • Started adding derive(Copy) for large arrays of Copy things, even when the
    array is too large to derive(Clone) because Rust doesn't implement Clone
    for arrays of length greater than 32. #874

  • bindgen can now determine which types are hashable and add derive(Hash) to
    those types that support it. This is disabled by default, but can be enabled
    via bindgen::Builder::derive_hash or --with-derive-hash. #876

  • bindgen can now generate impl Debug for Blah trait implementations for
    types that contain non-Debug types, and therefore cannot
    derive(Debug). This behavior can be enabled with
    bindgen::Builder::impl_debug and --impl-debug. #875

  • bindgen can now invoke rustfmt on the generated bindings. The bindings
    have historically been fairly pretty printed, but sometimes this is not the
    case, especially with the new impl Debug for Blah feature. Have bindgen
    run rustfmt with bindgen::Builder::rustfmt_bindings and
    --rustfmt-bindings, and use non-default rustfmt configuration files with
    bindgen::Builder::rustfmt_configuration_file and
    --rustfmt-configuration-file. #900

  • bindgen can now determine which types can be compared with == and add
    derive(PartialEq) to those types that support it. This is disabled by
    default, but can be enabled via bindgen::Builder::derive_partialeq or
    --with-derive-partialeq. #878

  • Additionally, bindgen can also add derive(Eq) to those types which we
    determined we could derive(PartialEq) and do not transitively contain any
    floats. Enable this behavior with bindgen::Builder::derive_eq or
    --with-derive-eq. #880

Changed

  • Started emitting Rust unions when targeting stable Rust >= 1.19, not just
    unstable nightly Rust. #832

  • Emitted layout #[test]s no longer contain internal IDs for template
    instantiations including pointers and arrays. This should make generated
    bindings more stable across updates to unrelated parts of the input
    headers. #871

  • Determining whether a type can derive Copy or not was ported from an ad-hoc
    algorithm to our fix-point framework. #766

  • Determining whether a type has a destructor or not was also ported from an
    ad-hoc algorithm to our fix-point framework. #927

Deprecated

  • bindgen::Builder::unstable_rust/--unstable-rust is deprecated, in favor of
    targeting explicit Rust versions with
    bindgen::Builder::rust_target/--rust-target instead. #832

Fixed

  • Fixed a regression in the derive(Default) analysis that resulted in some
    opaque types deriving Default when they shouldn't have. #889

  • Fixed a regression where template instantiation layout #[test]s were being
    generated with invalid Rust identifiers. #906

Friends

Thanks to everyone who contributed to this release!

  • Anna Liao
  • Bastian Köcher
  • Benjamin Dahse
  • Emilio Cobos Álvarez
  • Malo Jaffré
  • Nick Fitzgerald
  • Niv
  • Richard Bradfield
  • Travis Finkenauer
  • Wangshan Lu
  • Xidorn Quan
  • Zhiting Zhu

Contributing

Want to join us? Check out our CONTRIBUTING.md and take a look
at some of these issues:

Want to help improve our documentation?
Check out the issues labeled "docs".

Found a bug with bindgen? File an issue here.

4 Likes

bindgen Code Overview

I just wrote this up and figured that

  • some people might find it interesting, and

  • some people could provide feedback: does this give you the information you feel like you'd need to dive head first into bindgen's code base? If not, what's missing or what would you change?

Thanks!

5 Likes

Announcing bindgen 0.31.0

bindgen automatically generates Rust FFI bindings to C and C++ libraries.

Upgrade to this release by updating your Cargo.toml:

bindgen = "0.31.0"

Changelog

Added

  • :tada: A new bindgen reviewer: @pepyakin :tada: You can ask @pepyakin to review all your future pull requests with r? @pepyakin from now on :smile:

  • Timers for seeing which phases bindgen is spending its time in. On the command line, use the --time-phases flag. From a builder, use the bindgen::Builder::time_phases(true) method. #938

  • You can now disable #[derive(Copy)] for all types with --no-derive-copy and bindgen::Builder::derive_copy(false). #948

  • We now have an overview of bindgen's code base and architecture for newcomers in CONTRIBUTING.md. #988

  • Derive PartialOrd with the --with-derive-partialord CLI flag or bindgen::Builder::derive_partialord(true) builder method. #882

  • Derive Ord with the --with-derive-ord CLI flag or bindgen::Builder::derive_ord(true) builder method. #884

  • When PartialEq cannot be derived because of an array larger than Rust's array-derive limit, bindgen can emit an impl PartialEq for ... block. Enable this behavior with the --impl-partialeq CLI flag or the bindgen::Builder::impl_partialeq(true) method. #1012

  • When deriving PartialEq for all types, you can now specify particular types that shouldn't derive(PartialEq) with the --no-partialeq <regex> CLI flag or bindgen::Builder::no_partialeq("<regex>") builder method. #996

  • Specify types that should not derive Copy with the --no-copy <regex> CLI flag or bindgen::Builder::no_copy("<regex>") builder method. This functionality was previously only available via comment annotations in the header sources. #1099

  • When deriving Hash for all types, you can now specify particular types that shouldn't derive(Hash) with the --no-hash <regex> CLI flag or bindgen::Builder::no_hash("<regex>") builder method. #1105

  • The bindgen users guide now has an FAQ section! If you have any FAQ suggestions to put up there, please open a pull request. [#1020]

  • Added csmith fuzzing infrastructure. csmith generates random C and C++ programs, we feed those into bindgen as headers to generate bindings to, then test that the generated bindings compile and that their layout tests pass. This infrastructure landed in many small bits.

    We <3 folks who help us find and fix issues via fuzzing! hint hint

  • Added experimental support for the thiscall ABI when targetting Rust nightly. #1065

Changed

  • If the user does not explicitly pass a --target argument for libclang, bindgen will insert such an argument itself. See #942, #947, and #953 for details.

  • C/C++ enums are now translated into constants by default, rather than Rust enums. The old behavior was a big footgun because rustc assumes that the only values of an enum are its variants, whereas a lot of C/C++ code uses random values as enums. Put these two things and it leads to undefined behavior. Translating C/C++ enums into Rust enums is still available with the --rustified-enum <regex> CLI flag and bindgen::Builder::rustified_enum("<regex>") builder method. #758

  • Generated bindings are now pretty printed with rustfmt by default. Previously, this option existed, but was off by default because syntex did an OK job at pretty printing the bindings. Now that we are using quote! { ... } instead of syntex, we lost that pretty printing, and now rely on rustfmt. You can disable rustfmting with --no-rustfmt-bindings or bindgen::Builder::rustfmt_bindings(false). See #925 and #1022 for details.

Deprecated

  • bindgen::Builder::hide_type is deprecated in favor of bindgen::Builder::blacklist_type. #987

  • bindgen::Builder::whitelisted_type is deprecated in favor of bindgen::Builder::whitelist_type. #987

  • bindgen::Builder::whitelisted_function is deprecated in favor of bindgen::Builder::whitelist_function. #985

  • bindgen::Builder::whitelisted_var is deprecated in favor of bindgen::Builder::whitelist_var. #989

Removed

  • Removed the dependency on (unmaintained) syntex, and build times are cut in half!

    Before:

    $ cargo clean; cargo build
    <snip>
        Finished dev [unoptimized + debuginfo] target(s) in 98.75 secs
    

    After:

    $ cargo clean; cargo build
    <snip>
        Finished dev [unoptimized + debuginfo] target(s) in 46.26 secs
    

    #925

  • The BindgenOptions type is no longer public. It had been deprecated in previous releases. Use bindgen::Builder instead. #1000

Fixed

  • Under certain conditions, a globally scoped enum could end up with bindings in the wrong namespace module. #888

  • Blacklisted types were incorrectly assumed to always be Copyable (and assumed to implement other traits as well). bindgen is now conservatively pessimistic about the traits that blacklisted types implement. #944

  • When bitfields have a ridiculously large number of bits (for example, unsigned : 632;) then bindgen was incorrectly deriving traits that couldn't be derived, resulting in errors when compiling the bindings, and was also generating structs with an incorrect layout. Both issues have been fixed. #982

  • _ is a valid identifier in some C++ contexts, but can't be referenced in Rust, as it is the "throwaway identifier" (a term I just made up, if you use it now, then you owe me money). bindgen will now translate _ into __ so that it can be used on the Rust side. #1008

  • Nested class definitions were sometimes being emitted in the wrong namespace module in the generated bindings. #1048

  • bindgen was mis-handling unions that contained bitfield members. This has been fixed. #744

  • Unsigned constants that were greater than u32::MAX were being mis-translated by bindgen. This is now fixed. #1040

  • When given a directory as an input file, or a file to which we don't have read permissions, then bindgen will print a more useful error message now. #1029

  • bindgen previously attempted to derive Hash for structures with flexibly-sized array members, but knowing how many elements exist in such arrays requires program-specific knowledge that bindgen cannot have. #1094

Friends

Thanks to everyone who contributed to this release!

  • Alexey Zabelin
  • Andrew Gaspar
  • Bastien Orivel
  • Cldfire
  • e
  • Emilio Cobos Álvarez
  • Glyn Normington
  • Harlan Haskins
  • Jackson O'Donnell
  • Jeff Muizelaar
  • KC
  • Liran Ringel
  • Manas Karekar
  • mchlrhw
  • Nick Fitzgerald
  • Oliver Geller
  • seemyvest
  • Sergey Pepyakin
  • Taylor Foxhall
  • Trevor Reiff
  • Zhiting Zhu

Contributing

Join us in our impl period gitter channel: WG-dev-tools-bindgen

Want to join us? Check out our CONTRIBUTING.md and take a look at some of these issues:

Want to help improve our documentation? Check out the issues labeled "docs".

Found a bug with bindgen? File an issue here.

9 Likes

Announcing bindgen 0.32.0

bindgen automatically generates Rust FFI bindings to C and C++ libraries.

Upgrade to this release by updating your Cargo.toml:

bindgen = "0.32.0"

Changelog

Added

  • Added support for bit-field allocation units that are larger than 64 bits
    wide. Note that individual bit-fields within such units are still restricted
    to being no wider than 64 bits. #1158

  • We can now generate random C header files and test that bindgen can process
    them with the quickcheck crate. Initial support landed in #1159 with a
    few more additions in follow up pull requests.

Changed

  • The bindgen::Builder::{constified_enum_module,{bitfield,rustified}_enum}
    builder methods and their corresponding CLI flags now compare their argument
    to the C/C++ enum's "canonical path", which includes leading namespaces,
    rather than its "canonical name", which does not. This is a breaking change
    that requires callers which target a namespaced C++ enum to call e.g.
    bitfield_enum("<namespace>::<enum_name>") rather than e.g.
    bitfield_enum("<enum_name>"). #1162

  • When a struct is packed to a smaller alignment that is still greater than one,
    bindgen cannot emit Rust bindings that match the input source. Before, it
    would emit #[repr(packed)] anyways, which packs to an alignment of one, but
    this can lead to misalignment and UB. Now, bindgen will detect these
    situations and convert the struct into an opaque blob of bytes with the proper
    alignment. We are eagerly awaiting support for #[repr(packed(N))] in
    Rust. #1136

Fixed

  • There was a perfect storm of conditions that could cause bindgen not to emit
    any bindings if spawning rustfmt to format the bindings failed. This is now
    fixed. #1112

  • In some circumstances, bindgen would emit type parameters twice for
    references to template instantiations. This is now fixed. #1113

  • When a C/C++ struct had a field named with a Rust keyword, and impl_debug
    was enabled, the generated impl Debug for ... blocks could reference the
    field by the Rust keyword name, rather than the non-keyword field name we
    actually end up generating. This is now fixed. #1123

  • There was a regression in 0.31.0 where C++ template aliases to opaque types
    would sometimes not treat the aliased type as opaque. This is now
    fixed. #1118

  • There was a regression in 0.31.0 that could cause bindgen to panic when
    parsing nested template classes. This is now fixed. #1127

  • Unnamed bit-fields do not affect alignment of their struct or class in C/C++,
    however bindgen interpreted them as doing so, which could generate
    #[repr(C)] structs expecting to have an incorrect alignment. This is now
    fixed. #1076

  • When a zero-sized type was used in a bit-field, bindgen could
    divide-by-zero. This is now fixed. #1137

  • When a template parameter is used in a bit-field, bindgen would panic. This
    is now fixed. #1140

  • There was a regression in 0.31.0 where if bindgen was given a header file
    that did not exist, it would panic. This is now fixed, and it will instead
    properly report the error. #1146

  • In some cases, generated bit-field getters and setters could access memory
    beyond self. This is now fixed. #954

Friends

Thanks to everyone who contributed to the 0.31.1, 0.31.2, 0.31.3, and 0.32.0
releases!

  • Anthony Ramine
  • Bastien Orivel
  • Emilio Cobos Álvarez
  • Glyn Normington
  • Nick Fitzgerald
  • roblabla
  • seemyvest
  • Sergey Pepyakin
  • Shea Newton
  • Tamir Duberstein
  • Trevor Reiff
  • Zhiting Zhu

Contributing

Want to join us? Check out our CONTRIBUTING.md and take a look
at some of these issues:

Want to help improve our documentation?
Check out the issues labeled "docs".

Found a bug with bindgen? File an issue here.

Announcing bindgen 0.32.1 and 0.32.2

bindgen automatically generates Rust FFI bindings to C and C++ libraries.

Upgrade to this release by updating your Cargo.toml:

bindgen = "0.32.2"

Changelog

0.32.2

Released 2018/01/22

Fixed

  • Avoid symbol generation for pure virtual functions. #1197

  • Handling of _Complex _Float128. #1087

  • Regression on code generation for variadic functions. #1216

  • Enum code generation generates conflicting repr hint warning. #1224

  • Constified code generation for enums with an explicit type of bool. #1145

  • Bindgen will now call rustfmt directly instead of via rustup. #1184

0.32.1

Released 2017/12/18

Fixed

  • When translating C/C++ enums into Rust enums using rustified_enum /
    --rustified-enum, properly add #[repr(C)] to the emitted enum. #1183

Friends

Thanks to everyone who contributed to these releases!

  • Adam Baxter
  • Alex Gaynor
  • Alex McArther
  • Anthony Ramine
  • cris-b
  • Emilio Cobos Álvarez
  • Glyn Normington
  • Kobata
  • Kornel
  • Léo Gaspard
  • Manas Karekar
  • Nick Fitzgerald
  • Shea Newton

Contributing

Want to join us? Check out our CONTRIBUTING.md and take a look
at some of these issues:

Want to help improve our documentation?
Check out the issues labeled "docs".

Found a bug with bindgen? File an issue here.

3 Likes