|
7 | 7 | [Api Rustdoc]: https://img.shields.io/badge/api-rustdoc-blue.svg
|
8 | 8 | [rustdoc]: https://docs.rs/cbindgen
|
9 | 9 |
|
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. |
11 | 10 |
|
12 |
| -## Features |
13 | 11 |
|
14 |
| - * Builds bindings for a crate, its mods, its dependent crates, and their mods |
15 |
| - * Only the necessary types for exposed functions are given bindings |
16 |
| - * Can specify annotations for controlling some aspects of binding |
17 |
| - * Support for generic structs and unions |
18 |
| - * Support for exporting constants and statics |
19 |
| - * Customizable formatting, can be used in C or C++ projects |
20 |
| - * Support for generating `#ifdef`'s for `#[cfg]` attributes |
21 |
| - * Support for `#[repr(sized)]` tagged enum's |
22 | 12 |
|
23 |
| -## Installation |
| 13 | +[Read the full user docs here!](docs.md) |
24 | 14 |
|
25 |
| -``` |
26 |
| -cargo install cbindgen |
27 |
| -``` |
28 |
| -or |
29 |
| -``` |
30 |
| -# This will update cbindgen if it's already installed |
31 |
| -cargo install --force cbindgen |
32 |
| -``` |
33 | 15 |
|
34 |
| -## Use |
35 | 16 |
|
36 |
| -### Command line |
37 | 17 |
|
38 |
| -``` |
39 |
| -cbindgen crate/ -o crate/bindings.h |
40 |
| -``` |
| 18 | +cbindgen creates C/C++11 headers for Rust libraries which expose a public C API. |
41 | 19 |
|
42 |
| -See `cbindgen --help` for more options. |
| 20 | +While you could do this by hand, it's not a particularly good use of your time. It's also much more likely to be error-prone than machine-generated headers that are based on your actual Rust code. The cbindgen developers have also worked closely with the developers of Rust to ensure that the headers we generate reflect actual guarantees about Rust's type layout and ABI. |
| 21 | + |
| 22 | +C++ headers are nice because we can use operator overloads, constructors, enum classes, and templates to make the API more ergonomic and Rust-like. C headers are nice because you can be more confident that whoever you're interoperating with can handle them. With cbindgen *you don't need to choose*! You can just tell it to emit both from the same Rust library. |
43 | 23 |
|
44 |
| -### `build.rs` |
| 24 | +There are two ways to use cbindgen: as a standalone program, or as a library (presumably in your build.rs). |
| 25 | +There isn't really much practical difference, because cbindgen is a simple rust library with no interesting dependencies. Using it as a program means people building your software will need it installed. Using it in your library means people may have to build cbindgen more frequently (e.g. every time they update their rust compiler). |
45 | 26 |
|
46 |
| -`cbindgen` can also be used in build scripts. How this fits into compiling the native code depends on your project. |
| 27 | +It's worth noting that the development of cbindgen has been largely adhoc, as features have been added to support the usecases of the maintainers. This means cbindgen may randomly fail to support some particular situation simply because no one has put in the effort to handle it yet. [Please file an issue if you run into such a situation](https://github.com/eqrion/cbindgen/issues/new). Although since we all have other jobs, you might need to do the implementation work too :) |
47 | 28 |
|
48 |
| -Here's an example build.rs script: |
49 |
| -```rust |
50 |
| -extern crate cbindgen; |
51 | 29 |
|
52 |
| -use std::env; |
53 | 30 |
|
54 |
| -fn main() { |
55 |
| - let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); |
56 | 31 |
|
57 |
| - cbindgen::Builder::new() |
58 |
| - .with_crate(crate_dir) |
59 |
| - .generate() |
60 |
| - .expect("Unable to generate bindings") |
61 |
| - .write_to_file("bindings.h"); |
62 |
| -} |
| 32 | +# Quick Start |
63 | 33 |
|
| 34 | +To install cbindgen, you just need to run |
| 35 | + |
| 36 | +```text |
| 37 | +cargo install --force cbindgen |
64 | 38 | ```
|
65 | 39 |
|
66 |
| -You can add configuration options using the [`Builder`](https://docs.rs/cbindgen/*/cbindgen/struct.Builder.html#methods) interface. |
67 |
| - |
68 |
| -If you'd like to use a `build.rs` script with a `cbindgen.toml`, consider using [`cbindgen::generate()`](https://docs.rs/cbindgen/*/cbindgen/fn.generate.html) instead. |
69 |
| - |
70 |
| -## Configuration |
71 |
| - |
72 |
| -There are some options that can be used to configure the binding generation. |
73 |
| - |
74 |
| -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. |
75 |
| - |
76 |
| -For build scripts, options can be specified on the builder or by writing a `cbindgen.toml` and using the helper function `cbindgen::generate`. |
77 |
| - |
78 |
| -Here is a description of the options available in a config. |
79 |
| - |
80 |
| -```toml |
81 |
| -# An optional string of text to output at the beginning of the generated file |
82 |
| -header = "/* Text to put at the beginning of the generated file. Probably a license. */" |
83 |
| -# An optional string of text to output at the end of the generated file |
84 |
| -trailer = "/* Text to put at the end of the generated file */" |
85 |
| -# An optional name to use as an include guard |
86 |
| -include_guard = "mozilla_wr_bindings_h" |
87 |
| -# An optional string of text to output between major sections of the generated |
88 |
| -# file as a warning against manual editing |
89 |
| -autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */" |
90 |
| -# Whether to include a comment with the version of cbindgen used to generate the |
91 |
| -# file |
92 |
| -include_version = true |
93 |
| -# An optional namespace to output around the generated bindings |
94 |
| -namespace = "ffi" |
95 |
| -# An optional list of namespaces to output around the generated bindings |
96 |
| -namespaces = ["mozilla", "wr"] |
97 |
| -# The style to use for curly braces |
98 |
| -braces = "[SameLine|NextLine]" |
99 |
| -# The desired length of a line to use when formatting lines |
100 |
| -line_length = 80 |
101 |
| -# The amount of spaces in a tab |
102 |
| -tab_width = 2 |
103 |
| -# The language to output bindings in |
104 |
| -language = "[C|C++]" |
105 |
| -# Include preprocessor defines in C bindings to ensure C++ compatibility |
106 |
| -cpp_compat = true |
107 |
| -# A rule to use to select style of declaration in C, tagname vs typedef |
108 |
| -style = "[Both|Type|Tag]" |
109 |
| -# How the generated documentation should be commented. |
110 |
| -# C uses /* */; C99 uses //; C++ uses ///; Doxy is like C but with leading * per line. |
111 |
| -documentation_style = "[C, C99, C++, Doxy]" |
112 |
| - |
113 |
| - |
114 |
| -[defines] |
115 |
| -# A rule for generating `#ifdef`s for matching `#[cfg]`ed items, |
116 |
| -# e.g. `#[cfg(foo = "bar")] ...` -> `#if defined(FOO_IS_BAR) ... #endif` |
117 |
| -"foo = bar" = "FOO_IS_BAR" |
118 |
| - |
119 |
| -[parse] |
120 |
| -# Whether to parse dependent crates and include their types in the generated |
121 |
| -# bindings |
122 |
| -parse_deps = true |
123 |
| -# A white list of crate names that are allowed to be parsed |
124 |
| -include = ["webrender", "webrender_traits"] |
125 |
| -# A black list of crate names that are not allowed to be parsed |
126 |
| -exclude = ["libc"] |
127 |
| -# Whether to use a new temporary target directory when running `rustc --pretty=expanded`. |
128 |
| -# This may be required for some build processes. |
129 |
| -clean = false |
130 |
| - |
131 |
| -[parse.expand] |
132 |
| -# A list of crate names that should be run through `cargo expand` before |
133 |
| -# parsing to expand any macros |
134 |
| -crates = ["euclid"] |
135 |
| -# If enabled, use the `--all-features` option when expanding. Ignored when |
136 |
| -# `features` is set. Disabled by default, except when using the |
137 |
| -# `expand = ["euclid"]` shorthand for backwards-compatibility. |
138 |
| -all_features = false |
139 |
| -# When `all_features` is disabled and this is also disabled, use the |
140 |
| -# `--no-default-features` option when expanding. Enabled by default. |
141 |
| -default_features = true |
142 |
| -# A list of feature names that should be used when running `cargo expand`. This |
143 |
| -# combines with `default_features` like in `Cargo.toml`. Note that the features |
144 |
| -# listed here are features for the current crate being built, *not* the crates |
145 |
| -# being expanded. The crate's `Cargo.toml` must take care of enabling the |
146 |
| -# appropriate features in its dependencies |
147 |
| -features = ["cbindgen"] |
148 |
| - |
149 |
| -[export] |
150 |
| -# A list of additional items not used by exported functions to include in |
151 |
| -# the generated bindings |
152 |
| -include = ["Foo", "Bar"] |
153 |
| -# A list of items to not include in the generated bindings |
154 |
| -exclude = ["Bad"] |
155 |
| -# A prefix to add before the name of every item |
156 |
| -prefix = "CAPI_" |
157 |
| -# Types of items that we'll generate. |
158 |
| -item_types = ["constants", "globals", "enums", "structs", "unions", "typedefs", "opaque", "functions"] |
159 |
| -# Whether applying rules in export.rename prevent export.prefix from applying. |
160 |
| -renaming_overrides_prefixing = true # default: false |
161 |
| - |
162 |
| -# Table of name conversions to apply to item names |
163 |
| -[export.rename] |
164 |
| -"Struct" = "CAPI_Struct" |
165 |
| - |
166 |
| -# Table of stuff to add to an item body. |
167 |
| -[export.body] |
168 |
| -"Struct" = """ |
169 |
| - void cppMethod() const; |
170 |
| -""" |
171 |
| - |
172 |
| -[fn] |
173 |
| -# An optional prefix to put before every function declaration |
174 |
| -prefix = "string" |
175 |
| -# An optional postfix to put after any function declaration |
176 |
| -postfix = "string" |
177 |
| -# How to format function arguments |
178 |
| -args = "[Auto|Vertical|Horizontal]" |
179 |
| -# A rule to use to rename function argument names |
180 |
| -rename_args = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]" |
181 |
| - |
182 |
| -[struct] |
183 |
| -# A rule to use to rename field names |
184 |
| -rename_fields = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]" |
185 |
| -# Whether to derive an operator== for all structs |
186 |
| -derive_eq = false |
187 |
| -# Whether to derive an operator!= for all structs |
188 |
| -derive_neq = false |
189 |
| -# Whether to derive an operator< for all structs |
190 |
| -derive_lt = false |
191 |
| -# Whether to derive an operator<= for all structs |
192 |
| -derive_lte = false |
193 |
| -# Whether to derive an operator> for all structs |
194 |
| -derive_gt = false |
195 |
| -# Whether to derive an operator>= for all structs |
196 |
| -derive_gte = false |
197 |
| - |
198 |
| -[enum] |
199 |
| -# A rule to use to rename enum variants |
200 |
| -rename_variants = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|SnakeCase|ScreamingSnakeCase|QualifiedScreamingSnakeCase]" |
201 |
| -# Whether tagged enums should generate destructors. This makes them dangerous to |
202 |
| -# pass by value. |
203 |
| -derive_tagged_enum_destructor = false |
204 |
| -# Whether tagged enums should generate copy-constructor. This makes them |
205 |
| -# dangerous to pass by value. |
206 |
| -derive_tagged_enum_copy_constructor = false |
| 40 | +(--force just makes it update to the latest cbindgen if it's already installed) |
| 41 | + |
| 42 | +To use cbindgen you need two things: |
| 43 | + |
| 44 | +* A configuration (cbindgen.toml, which can be empty to start) |
| 45 | +* A Rust crate with a public C API |
207 | 46 |
|
| 47 | +Then all you need to do is run it: |
| 48 | + |
| 49 | +```text |
| 50 | +cbindgen --config cbindgen.toml --crate my_rust_library --output my_header.h` |
208 | 51 | ```
|
209 | 52 |
|
210 |
| -## Examples |
| 53 | +See `cbindgen --help` for more options. |
| 54 | + |
| 55 | +[Read the full user docs here!](docs.md) |
| 56 | + |
211 | 57 |
|
212 |
| -See `tests/rust/` for some examples of rust source that can be handled. |
213 | 58 |
|
214 |
| -## Major differences between `cbindgen` and `rusty-cheddar` |
215 | 59 |
|
216 |
| -1. `cbindgen` supports generics |
217 |
| -2. `cbindgen` supports C++ output using `enum class` and `template specialization` |
218 |
| -3. `cbindgen` supports generating bindings including multiple modules and crates |
| 60 | +# Examples |
219 | 61 |
|
220 |
| -There may be other differences, but those are the ones that I know of. Please correct me if I misrepresented anything. |
| 62 | +We don't currently have a nice tailored example application, but [the tests](tests/rust/) contain plenty of interesting examples of our features. |
221 | 63 |
|
222 |
| -## Prominent users |
| 64 | +You may also find it interesting to browse the projects that are using cbindgen in production: |
223 | 65 |
|
224 | 66 | * [milksnake](https://github.com/getsentry/milksnake)
|
225 |
| -* [webrender](https://searchfox.org/mozilla-central/source/__GENERATED__/gfx/webrender_bindings/webrender_ffi_generated.h) |
226 |
| -* [stylo](https://searchfox.org/mozilla-central/source/__GENERATED__/layout/style/ServoStyleConsts.h) |
227 |
| -* [wgpu](https://github.com/gfx-rs/wgpu/blob/master/wgpu-bindings/wgpu.h) |
| 67 | +* [webrender](https://searchfox.org/mozilla-central/source/gfx/webrender_bindings) ([generated header](https://searchfox.org/mozilla-central/source/__GENERATED__/gfx/webrender_bindings/webrender_ffi_generated.h)) |
| 68 | +* [stylo](https://searchfox.org/mozilla-central/source/layout/style) ([generated header](https://searchfox.org/mozilla-central/source/__GENERATED__/layout/style/ServoStyleConsts.h)) |
| 69 | +* [wgpu](https://github.com/gfx-rs/wgpu/tree/master/wgpu-native) ([generated header](https://github.com/gfx-rs/wgpu/blob/master/ffi/wgpu.h)) |
228 | 70 |
|
229 | 71 | If you're using `cbindgen` and would like to be added to this list, please open a pull request!
|
0 commit comments