Go to file
Nick Fitzgerald 5004ed43b2 Define extra assertion macros
This commit defines a new set of assertion macros that are only checked in
testing/CI when the `testing_only_extra_assertions` feature is enabled. This
makes it so that *users* of bindgen that happen to be making a debug build don't
enable all these extra and expensive assertions.

Additionally, this removes the `testing_only_assert_no_dangling_items` feature,
and runs the assertions that were previously gated on that feature when the new
`testing_only_extra_assertions` feature is enabled.
2017-04-07 09:58:46 -07:00
.github Create ISSUE_TEMPLATE.md 2017-02-17 08:09:00 -08:00
bindgen-integration codegen: Add integration tests for destructors. 2017-04-04 01:05:35 +02:00
ci Define extra assertion macros 2017-04-07 09:58:46 -07:00
src Define extra assertion macros 2017-04-07 09:58:46 -07:00
tests Add a test explicitly for default type parameters 2017-04-05 16:56:49 -07:00
.gitignore Fix .gitignore and extra crates' Cargo.lock files 2017-01-26 16:27:55 -08:00
.travis.yml tests: Disable rustfmt tests, for now. 2017-03-27 19:13:53 +02:00
build.rs Refactor fallibility of conversions from IR to Rust types 2017-03-15 10:50:26 -07:00
Cargo.lock Bump to v0.22.1 2017-03-05 23:46:46 +01:00
Cargo.toml Define extra assertion macros 2017-04-07 09:58:46 -07:00
CONTRIBUTING.md Clean up testing-only cargo features 2017-04-06 14:38:05 -07:00
example-graphviz-ir.png Update the example graphviz image 2017-02-17 17:45:49 -08:00
LICENSE fix build and add license 2013-08-05 10:43:15 +08:00
README.md fix clang installation instruction for debian os 2017-03-07 13:15:01 +06:00
rustfmt.toml Manual fixups, some of them pretty lame, and don't let rustfmt rewrap comments. 2016-11-01 17:15:18 +01:00

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 clang-3.9

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.