cbindgen

This project can be used to generate C bindings for Rust code. It is currently being developed to support creating bindings for WebRender, but has been designed to support any project.
Features
- Builds bindings for a crate, its mods, its dependent crates, and their mods
- Only the necessary types for exposed functions are given bindings
- Can specify annotations for controlling some aspects of binding
- Support for generic structs and unions
- Support for exporting constants and statics
- Customizable formatting, can be used in C or C++ projects
- Support for generating
#ifdef
's for#[cfg]
attributes - Support for
#[repr(sized)]
tagged enum's
Installation
cargo install cbindgen
or
# This will update cbindgen if it's already installed
cargo install --force cbindgen
Use
Command line
cbindgen crate/ -o crate/bindings.h
See cbindgen --help
for more options.
build.rs
cbindgen
can also be used in build scripts. How this fits into compiling the native code depends on your project.
Here's an example build.rs script:
extern crate cbindgen;
use env;
You can add configuration options using the Builder
interface.
If you'd like to use a build.rs
script with a cbindgen.toml
, consider using cbindgen::generate()
instead.
Configuration
There are some options that can be used to configure the binding generation.
For the command line, they can be specified by creating a cbindgen.toml
with the options. This can be placed in the binding crate root or at a path manually specified.
For build scripts, options can be specified on the builder or by writing a cbindgen.toml
and using the helper function cbindgen::generate
.
Here is a description of the options available in a config.
# An optional string of text to output at the beginning of the generated file
= "/* Text to put at the beginning of the generated file. Probably a license. */"
# An optional string of text to output at the end of the generated file
= "/* Text to put at the end of the generated file */"
# An optional name to use as an include guard
= "mozilla_wr_bindings_h"
# An optional string of text to output between major sections of the generated
# file as a warning against manual editing
= "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
# Whether to include a comment with the version of cbindgen used to generate the
# file
= true
# An optional namespace to output around the generated bindings
= "ffi"
# An optional list of namespaces to output around the generated bindings
= ["mozilla", "wr"]
# The style to use for curly braces
= "[SameLine|NextLine]"
# The desired length of a line to use when formatting lines
= 80
# The amount of spaces in a tab
= 2
# The language to output bindings in
= "[C|C++]"
# A rule to use to select style of declaration in C, tagname vs typedef
= "[Both|Type|Tag]"
# How the generated documentation should be commented.
# C uses /* */; C++ uses //; Doxy is like C but with leading * per line.
= "[C, C++, Doxy]"
[]
# A rule for generating `#ifdef`s for matching `#[cfg]`ed items,
# e.g. `#[cfg(foo = "bar")] ...` -> `#if defined(FOO_IS_BAR) ... #endif`
= "FOO_IS_BAR"
[]
# Whether to parse dependent crates and include their types in the generated
# bindings
= true
# A white list of crate names that are allowed to be parsed
= ["webrender", "webrender_traits"]
# A black list of crate names that are not allowed to be parsed
= ["libc"]
# Whether to use a new temporary target directory when running `rustc --pretty=expanded`.
# This may be required for some build processes.
= false
[]
# A list of crate names that should be run through `cargo expand` before
# parsing to expand any macros
= ["euclid"]
# If enabled, use the `--all-features` option when expanding. Ignored when
# `features` is set. Disabled by default, except when using the
# `expand = ["euclid"]` shorthand for backwards-compatibility.
= false
# When `all_features` is disabled and this is also disabled, use the
# `--no-default-features` option when expanding. Enabled by default.
= true
# A list of feature names that should be used when running `cargo expand`. This
# combines with `default_features` like in `Cargo.toml`. Note that the features
# listed here are features for the current crate being built, *not* the crates
# being expanded. The crate's `Cargo.toml` must take care of enabling the
# appropriate features in its dependencies
= ["cbindgen"]
[]
# A list of additional items not used by exported functions to include in
# the generated bindings
= ["Foo", "Bar"]
# A list of items to not include in the generated bindings
= ["Bad"]
# A prefix to add before the name of every item
= "CAPI_"
# Types of items that we'll generate.
= ["constants", "globals", "enums", "structs", "unions", "typedefs", "opaque", "functions"]
# Whether applying rules in export.rename prevent export.prefix from applying.
= true # default: false
# Table of name conversions to apply to item names
[]
= "CAPI_Struct"
# Table of stuff to add to an item body.
[]
= """
void cppMethod() const;
"""
[]
# An optional prefix to put before every function declaration
= "string"
# An optional postfix to put after any function declaration
= "string"
# How to format function arguments
= "[Auto|Vertical|Horizontal]"
# A rule to use to rename function argument names
= "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]"
[]
# A rule to use to rename field names
= "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]"
# Whether to derive an operator== for all structs
= false
# Whether to derive an operator!= for all structs
= false
# Whether to derive an operator< for all structs
= false
# Whether to derive an operator<= for all structs
= false
# Whether to derive an operator> for all structs
= false
# Whether to derive an operator>= for all structs
= false
[]
# A rule to use to rename enum variants
= "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]"
Examples
See tests/rust/
for some examples of rust source that can be handled.
Major differences between cbindgen
and rusty-cheddar
cbindgen
supports genericscbindgen
supports C++ output usingenum class
andtemplate specialization
cbindgen
supports generating bindings including multiple modules and crates
There may be other differences, but those are the ones that I know of. Please correct me if I misrepresented anything.
Prominent users
If you're using cbindgen
and would like to be added to this list, please open a pull request!