e57b2cb303
Rework how bitfields are handled. This fixes #111, and unblocks stylo. The problem with this as of right now is that it drops the accessors (though before that this code was buggy so I'm not sure it's a loss). I can probably try to re-implement those (though it'd be more complex). WDYT @fitzgen? Also, note that I changed the max_align_nonce because it was incorrect (we shouldn't generate padding, because `long double` was `128` bits). |
||
---|---|---|
bindgen-integration | ||
ci | ||
src | ||
tests | ||
.gitignore | ||
.travis.yml | ||
build.rs | ||
Cargo.lock | ||
Cargo.toml | ||
CONTRIBUTING.md | ||
LICENSE | ||
README.md | ||
rustfmt.toml |
bindgen
Automatically generates Rust FFI bindings to C and C++ libraries.
Usage
Requirements
It is recommended to use Clang 3.9 or greater, however bindgen
can run with
older Clangs with some features disabled.
Installing Clang 3.9
Windows
Download and install the official pre-built binary from LLVM download page.
OSX
If you use Homebrew:
$ brew install llvm
If you use MacPorts:
$ port install clang-3.9
Debian-based Linuxes
# apt-get install llvm-3.9-dev libclang-3.9-dev
Ubuntu 16.10 provides the necessary packages directly. If you are using older version of Ubuntu or other Debian-based distros, you may need to add the LLVM repos to get version 3.9. See http://apt.llvm.org/.
Arch
# pacman -S clang
From source
If your package manager doesn't yet offer Clang 3.9, you'll need to build from source. For that, follow the instructions here.
Those instructions list optional steps. For bindgen:
- Checkout and build clang
- Checkout and build the extra-clang-tools
- Checkout and build the compiler-rt
- You do not need to checkout or build libcxx
Library usage with build.rs
💡 This is the recommended way to use bindgen
. 💡
build.rs
Tutorial
Here is a step-by-step tutorial for generating FFI bindings to the bzip2
C library.
Simple Example: ./bindgen-integration
The ./bindgen-integration
directory has an example crate that
generates FFI bindings in build.rs
and can be used a template for new
projects.
Real World Example: Stylo
A real world example is the Stylo build script used for integrating Servo's layout system into Gecko.
In Cargo.toml
:
[package]
# ...
build = "build.rs"
[build-dependencies]
bindgen = "0.20"
In build.rs
:
extern crate bindgen;
use std::env;
use std::path::Path;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let _ = bindgen::builder()
.header("example.h")
.use_core()
.generate().unwrap()
.write_to_file(Path::new(&out_dir).join("example.rs"));
}
In src/main.rs
:
include!(concat!(env!("OUT_DIR"), "/example.rs"));
Command Line Usage
$ cargo install bindgen
There are a few options documented when running bindgen --help
. Bindgen is installed to ~/.cargo/bin
. You have to add that directory to your path to use bindgen
.
C++
bindgen
can handle most C++ features, but not all of them (C++ is hard!)
Notable C++ features that are unsupported or only partially supported:
- Partial template specialization
- Traits templates
- SFINAE
- Instantiating new template specializations
When passing in header files, the file will automatically be treated as C++ if
it ends in .hpp
. If it doesn't, -x c++
can be used to force C++ mode.
You must use whitelisting when working with C++ to avoid pulling in all of the
std::*
types, some of which bindgen
cannot handle. Additionally, you may
want to blacklist other types that bindgen
stumbles on, or make bindgen
treat certain types as opaque.
Annotations
The translation of classes, structs, enums, and typedefs can be adjusted using annotations. Annotations are specifically formatted html tags inside doxygen style comments.
opaque
The opaque
annotation instructs bindgen to ignore all fields defined in
a struct/class.
/// <div rustbindgen opaque></div>
hide
The hide
annotation instructs bindgen to ignore the struct/class/field/enum
completely.
/// <div rustbindgen hide></div>
replaces
The replaces
annotation can be used to use a type as a replacement for other
(presumably more complex) type. This is used in Stylo to generate bindings for
structures that for multiple reasons are too complex for bindgen to understand.
For example, in a C++ header:
/**
* <div rustbindgen replaces="nsTArray"></div>
*/
template<typename T>
class nsTArray_Simple {
T* mBuffer;
public:
// The existence of a destructor here prevents bindgen from deriving the Clone
// trait via a simple memory copy.
~nsTArray_Simple() {};
};
That way, after code generation, the bindings for the nsTArray
type are
the ones that would be generated for nsTArray_Simple
.
nocopy
The nocopy
annotation is used to prevent bindgen to autoderive the Copy
and Clone
traits for a type.