Commit 6b90c00e authored by Ryan Hunt's avatar Ryan Hunt

Update documentation

parent 68eed64f
## Overview
`cbindgen` works in four phases:
1. *Parsing* - Crate information is gathered from `cargo`, and `rust` source files are read using `syn`
1. *Loading* - `syn` AST nodes are converted into an IR of `Item`s that loosely correspond to the C types that will be output
1. *Transformation* - Several passes are run that transform the IR. Some examples:
- Generic `type` aliases are used to specialize the type they refer to
- Annotations are transferred from `type` aliases to the item they refer to
- `Option<&T>` is converted to `*const T`
- `Option<&mut T>` is converted to `*mut T`
- Generic paths in struct fields, union variants, and static globals are collected and used to generate monomorphs of the structs or unions they refer to
- The items are sorted by dependencies and type and unused items are filtered out
1. *Writing* - The IR is pretty printed to a file or `stdout`
## Process Flow
The main interface for `cbindgen` is `bindgen::Builder` which accepts configuration options and either a crate directory to parse or a list of source files.
If a list of source files is given, then `bindgen::Builder` will parse them using `parser::parse_src` which will use `syn` to parse a specific file. No `extern crate` items will be followed for dependencies, but `mod` items will be attempted to be followed.
If a crate directory is given, then `bindgen::Builder` will use `cargo::Cargo` to load a dependency graph from `Cargo.toml`, `Cargo.lock`, and `cargo metadata`. Then `parser::parse_lib` will parse each crate, following `extern crate` items when `ParseConfig::parse_deps` is enabled and the crate is not in the whitelist or blacklist of crates. In addition `bindgen::Parser` may use `cargo expand` on a crate to expand macro definitions.
Once the `syn` nodes are collected by either method, they are given to `bindgen::Parse` which will perform *Loading* by creating a `ir::Item` for each `syn` node as appropriate.
`bindgen::Builder` will then convert the resulting `bindgen::Parse`'s into a `bindgen::Library` which is the driver of all of the *Transformation* passes.
// TODO - Talk more about passes
Then finally the `bindgen::Library` will create a `bindgen::Bindings` which contains the `ir::Item`'s that are ready to be written. The `bindgen::Bindings` can then be written to `stdout` or a specific file.
# Contributing
Thanks for wanting to contribute!
If you want help or mentorship, please file a Github issue or comment on an existing one and I'll be sure to provide guidance to the best of my ability.
Otherwise be sure to check out `ARCHITECTURE.md` for an overview on the internals.
## Filing a pull request
Check out [Servo's Github workflow](https://github.com/servo/servo/wiki/Github-workflow) for an overview on creating a pull request. Don't worry about requesting code review, as there is nothing formally setup for this repository. I review each pull request as soon as I can.
There is continuous integration setup for `cbindgen` using `travis`. It will automatically run `./test.py` which tests `cbindgen` on a series of rust files in `tests/rust/` and verifes that the output compiles using `gcc` or `g++`.
Please run `./test.py` before filing a pull request to be sure that all tests pass. Bonus points if you write a new test for your pull request!
The outputed headers for each test are committed and verified as being up to date in each pull request, so be sure to run `./test.py`.
......@@ -127,7 +127,7 @@ rename_variants = "[None|GeckoCase|LowerCase|UpperCase|PascalCase|CamelCase|Snak
## Examples
See `compile-tests/` for some examples of rust source that can be handled.
See `tests/rust/` for some examples of rust source that can be handled.
## Major differences between `cbindgen` and `rusty-cheddar`
......@@ -137,20 +137,9 @@ See `compile-tests/` for some examples of rust source that can be handled.
There may be other differences, but those are the ones that I know of. Please correct me if I misrepresented anything.
## How it works
1. All the structs, unions, enums, type aliases, constants, statics, and functions that are representable in C are gathered
2. 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
3. Some code generation is done to specialize generics that are specified as type aliases
4. The items are printed in dependency order in C syntax
## Future work
1. Better support for types with fully specified names
2. Support for generating a FFI interface for a Struct+Impl
3. ...
## Prominent users
* [milksnake](https://github.com/getsentry/milksnake)
* [webrender](https://searchfox.org/mozilla-central/source/gfx/webrender_bindings/webrender_ffi_generated.h)
If you're using `cbindgen` and would like to be added to this list, please open a pull request!
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment