README.md 5.67 KB
Newer Older
Ryan Hunt's avatar
Ryan Hunt committed
1
# `cbindgen`   [![Build Status]][travis] [![Latest Version]][crates.io] [![Api Rustdoc]][rustdoc]
Ryan Hunt's avatar
Ryan Hunt committed
2

Ryan Hunt's avatar
Ryan Hunt committed
3
[Build Status]: https://api.travis-ci.org/eqrion/cbindgen.svg?branch=master
Ryan Hunt's avatar
Ryan Hunt committed
4
[travis]: https://travis-ci.org/eqrion/cbindgen
Ryan Hunt's avatar
Ryan Hunt committed
5
6
[Latest Version]: https://img.shields.io/crates/v/cbindgen.svg
[crates.io]: https://crates.io/crates/cbindgen
Ryan Hunt's avatar
Ryan Hunt committed
7
8
[Api Rustdoc]: https://img.shields.io/badge/api-rustdoc-blue.svg
[rustdoc]: https://eqrion.github.io/cbindgen/cbindgen
Kartikaya Gupta's avatar
Kartikaya Gupta committed
9

Ryan Hunt's avatar
Ryan Hunt committed
10
This project can be used to generate C bindings for Rust code. It is currently being developed to support creating bindings for [WebRender](https://github.com/servo/webrender/), but has been designed to support any project.
Kartikaya Gupta's avatar
Kartikaya Gupta committed
11

12
13
14
15
## Features

  * Builds bindings for a crate, its mods, its dependent crates, and their mods
  * Only the necessary types for exposed functions are given bindings
Ryan Hunt's avatar
Ryan Hunt committed
16
  * Can specify annotations for controlling some aspects of binding
Ryan Hunt's avatar
Ryan Hunt committed
17
18
  * Support for generic structs and unions
  * Support for exporting constants and statics
Ryan Hunt's avatar
Ryan Hunt committed
19
  * Customizable formatting, can be used in C or C++ projects
Ryan Hunt's avatar
Ryan Hunt committed
20
  * Support for generating `#ifdef`'s for `#[cfg]` attributes
21

Ryan Hunt's avatar
Ryan Hunt committed
22
## Use
Kartikaya Gupta's avatar
Kartikaya Gupta committed
23

24
25
### Command line

Ryan Hunt's avatar
Ryan Hunt committed
26
`cbindgen crate/ -o crate/bindings.h`
Ryan Hunt's avatar
Ryan Hunt committed
27

28
29
30
31
32
33
34
35
36
37
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:
```rust
extern crate cbindgen;

38
use std::env;
39
40

fn main() {
Ryan Hunt's avatar
Ryan Hunt committed
41
42
    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();

43
44
45
46
    cbindgen::Builder::new()
      .with_crate(crate_dir)
      .generate()
      .expect("Unable to generate bindings")
Ryan Hunt's avatar
Ryan Hunt committed
47
      .write_to_file("bindings.h");
48
}
Ryan Hunt's avatar
Ryan Hunt committed
49

50
51
```

52
53
## Configuration

54
55
56
57
58
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_with_config`.
59
60
61
62
63

Here is a description of the options available in a config.

```toml
# An optional string of text to output at the beginning of the generated file
Ryan Hunt's avatar
Ryan Hunt committed
64
header = "/* Text to put at the beginning of the generated file. Probably a license. */"
65
# An optional string of text to output at the end of the generated file
Ryan Hunt's avatar
Ryan Hunt committed
66
trailer = "/* Text to put at the end of the generated file */"
67
# An optional name to use as an include guard
Ryan Hunt's avatar
Ryan Hunt committed
68
include_guard = "mozilla_wr_bindings_h"
69
70
# An optional string of text to output between major sections of the generated
# file as a warning against manual editing
Ryan Hunt's avatar
Ryan Hunt committed
71
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
72
73
# Whether to include a comment with the version of cbindgen used to generate the
# file
Ryan Hunt's avatar
Ryan Hunt committed
74
include_version = true
75
# An optional namespace to output around the generated bindings
Ryan Hunt's avatar
Ryan Hunt committed
76
namespace = "ffi"
77
# An optional list of namespaces to output around the generated bindings
Ryan Hunt's avatar
Ryan Hunt committed
78
namespaces = ["mozilla", "wr"]
79
# The style to use for curly braces
Ryan Hunt's avatar
Ryan Hunt committed
80
braces = "[SameLine|NextLine]"
81
# The desired length of a line to use when formatting lines
Ryan Hunt's avatar
Ryan Hunt committed
82
line_length = 80
83
# The amount of spaces in a tab
Ryan Hunt's avatar
Ryan Hunt committed
84
tab_width = 2
85
# The language to output bindings in
Ryan Hunt's avatar
Ryan Hunt committed
86
language = "[C|C++]"
87
88
89
90

[parse]
# Whether to parse dependent crates and include their types in the generated
# bindings
Ryan Hunt's avatar
Ryan Hunt committed
91
parse_deps = true
92
# A white list of crate names that are allowed to be parsed
Ryan Hunt's avatar
Ryan Hunt committed
93
include = ["webrender", "webrender_traits"]
94
# A black list of crate names that are not allowed to be parsed
Ryan Hunt's avatar
Ryan Hunt committed
95
exclude = ["libc"]
96
97
# A list of crate names that should be run through `cargo expand` before
# parsing to expand any macros
Ryan Hunt's avatar
Ryan Hunt committed
98
expand = ["euclid"]
99
100
101

[fn]
# An optional prefix to put before every function declaration
Ryan Hunt's avatar
Ryan Hunt committed
102
prefix = "string"
103
# An optional postfix to put after any function declaration
Ryan Hunt's avatar
Ryan Hunt committed
104
postfix = "string"
105
# How to format function arguments
106
args = "[Auto|Vertical|Horizontal]"
107
# A rule to use to rename function argument names
108
rename_args = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]"
109
110
111

[struct]
# A rule to use to rename field names
112
rename_fields = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]"
113
# Whether to generate helper template specialization for generics
Ryan Hunt's avatar
Ryan Hunt committed
114
generic_template_specialization = true
115
# Whether to derive an operator== for all structs
Ryan Hunt's avatar
Ryan Hunt committed
116
derive_eq = false
117
# Whether to derive an operator!= for all structs
Ryan Hunt's avatar
Ryan Hunt committed
118
derive_neq = false
119
# Whether to derive an operator< for all structs
Ryan Hunt's avatar
Ryan Hunt committed
120
derive_lt = false
121
# Whether to derive an operator<= for all structs
Ryan Hunt's avatar
Ryan Hunt committed
122
derive_lte = false
123
# Whether to derive an operator> for all structs
Ryan Hunt's avatar
Ryan Hunt committed
124
derive_gt = false
125
# Whether to derive an operator>= for all structs
Ryan Hunt's avatar
Ryan Hunt committed
126
derive_gte = false
127
128
129

[enum]
# A rule to use to rename enum variants
130
rename_variants = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]"
Ryan Hunt's avatar
Ryan Hunt committed
131

132
```
133

134
135
## Examples

Ryan Hunt's avatar
Ryan Hunt committed
136
See `tests/rust/` for some examples of rust source that can be handled.
137

138
139
140
141
142
143
144
145
## Major differences between `cbindgen` and `rusty-cheddar`

1. `cbindgen` supports generics
2. `cbindgen` supports C++ output using `enum class` and `template specialization`
3. `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.

146
## Prominent users
Ryan Hunt's avatar
Ryan Hunt committed
147

148
149
* [milksnake](https://github.com/getsentry/milksnake)
* [webrender](https://searchfox.org/mozilla-central/source/gfx/webrender_bindings/webrender_ffi_generated.h)
Ryan Hunt's avatar
Ryan Hunt committed
150
151

If you're using `cbindgen` and would like to be added to this list, please open a pull request!