Skip to content

Commit b1de604

Browse files
Gankraeqrion
authored andcommitted
Add comprehensive user docs, smooth out README
1 parent 63d28c4 commit b1de604

File tree

2 files changed

+824
-191
lines changed

2 files changed

+824
-191
lines changed

README.md

Lines changed: 33 additions & 191 deletions
Original file line numberDiff line numberDiff line change
@@ -7,223 +7,65 @@
77
[Api Rustdoc]: https://img.shields.io/badge/api-rustdoc-blue.svg
88
[rustdoc]: https://docs.rs/cbindgen
99

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.
1110

12-
## Features
1311

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
2212

23-
## Installation
13+
[Read the full user docs here!](docs.md)
2414

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-
```
3315

34-
## Use
3516

36-
### Command line
3717

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.
4119

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.
4323

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).
4526

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 :)
4728

48-
Here's an example build.rs script:
49-
```rust
50-
extern crate cbindgen;
5129

52-
use std::env;
5330

54-
fn main() {
55-
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
5631

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
6333

34+
To install cbindgen, you just need to run
35+
36+
```text
37+
cargo install --force cbindgen
6438
```
6539

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
20746

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`
20851
```
20952

210-
## Examples
53+
See `cbindgen --help` for more options.
54+
55+
[Read the full user docs here!](docs.md)
56+
21157

212-
See `tests/rust/` for some examples of rust source that can be handled.
21358

214-
## Major differences between `cbindgen` and `rusty-cheddar`
21559

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
21961

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.
22163

222-
## Prominent users
64+
You may also find it interesting to browse the projects that are using cbindgen in production:
22365

22466
* [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))
22870

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

0 commit comments

Comments
 (0)