cbindgen
![Api Rustdoc](https://camo.githubusercontent.com/eb4f582c2b3888182376729ff8dbb1cb64c21cac8c91bcc39ea400348b2e29cd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6170692d72757374646f632d626c75652e737667)
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
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 std::env;
fn main() {
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
cbindgen::generate(&crate_dir)
.unwrap()
.write_to_file("bindings.h");
}
Configuration
There are some options that can be used to configure the binding generation. They can be specified by creating a cbindgen.toml
with the options in the binding crate root or at a path manually specified through the command line. Alternatively, build scripts can specify them using cbindgen::generate_with_config
.
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
header = "/* 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
trailer = "/* Text to put at the end of the generated file */"
# An optional name to use as an include guard
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
autogen_warning = "/* 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
include_version = true
# An optional namespace to output around the generated bindings
namespace = "ffi"
# An optional list of namespaces to output around the generated bindings
namespaces = ["mozilla", "wr"]
# The style to use for curly braces
braces = "[SameLine|NextLine]"
# The desired length of a line to use when formatting lines
line_length = 80
# The amount of spaces in a tab
tab_width = 2
# The language to output bindings in
language = "[C|C++]"
[parse]
# Whether to parse dependent crates and include their types in the generated
# bindings
parse_deps = true
# A white list of crate names that are allowed to be parsed
include = ["webrender", "webrender_traits"]
# A black list of crate names that are not allowed to be parsed
exclude = ["libc"]
# A list of crate names that should be run through `cargo expand` before
# parsing to expand any macros
expand = ["euclid"]
[fn]
# An optional prefix to put before every function declaration
prefix = "string"
# An optional postfix to put after any function declaration
postfix = "string"
# How to format function arguments
args = "[Auto|Vertical|Horizontal]"
# A rule to use to rename function argument names
rename_args = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]"
[struct]
# A rule to use to rename field names
rename_fields = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]"
# Whether to generate helper template specialization for generics
generic_template_specialization = true
# Whether to derive an operator== for all structs
derive_eq = false
# Whether to derive an operator!= for all structs
derive_neq = false
# Whether to derive an operator< for all structs
derive_lt = false
# Whether to derive an operator<= for all structs
derive_lte = false
# Whether to derive an operator> for all structs
derive_gt = false
# Whether to derive an operator>= for all structs
derive_gte = false
[enum]
# A rule to use to rename enum variants
rename_variants = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]"
Examples
See compile-tests/
for some examples of rust source that can be handled.
cbindgen
and rusty-cheddar
Major differences between 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.
How it works
- All the structs, unions, enums, type aliases, constants, statics, and functions that are representable in C are gathered
- A dependency graph is built using the extern "C" functions as roots
- This removes unneeded types from the bindings and sorts the structs that depend on each other
- Some code generation is done to specialize generics that are specified as type aliases
- The items are printed in dependency order in C syntax
Future work
- Better support for types with fully specified names
- Support for generating a FFI interface for a Struct+Impl
- ...