Skip to content

Commit

Permalink
Merge tag 'v0.17.0'
Browse files Browse the repository at this point in the history
v0.17.0

 * Add with_parse_extra_bindings to builder. (mozilla#645)
 * Support NonZero and fix incorrect simplification of Option<ptr> into ptr. (mozilla#647)
 * Deal with name conflicts correctly in declaration type resolution. (mozilla#651)
 * Support pointers to ZSTs. (mozilla#656)

# Conflicts:
#	tests/expectations/simplify_option_ptr.compat.c
  • Loading branch information
mhallin committed May 25, 2024
2 parents 1fae2d3 + 8236c82 commit c42f9bb
Show file tree
Hide file tree
Showing 65 changed files with 1,508 additions and 286 deletions.
2 changes: 2 additions & 0 deletions .clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Specify the minimum supported Rust version
msrv = "1.40.0"
17 changes: 14 additions & 3 deletions .github/workflows/cbindgen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
- master

jobs:
rustfmt:
rustfmt-clippy:

runs-on: ubuntu-latest

Expand All @@ -30,6 +30,13 @@ jobs:
command: fmt
args: -- --check

- name: Install clippy
uses: dtolnay/rust-toolchain@clippy

- name: Run clippy
run: |
cargo clippy --workspace -- -D warnings
- name: Install minimum supported Rust version
uses: actions-rs/toolchain@v1
with:
Expand Down Expand Up @@ -78,10 +85,14 @@ jobs:
run: |
cargo test --verbose
- name: Cargo update minimal-versions
- name: Test package
env:
CBINDGEN_TEST_VERIFY: 1
run: |
cargo update -Zminimal-versions
cargo package --verbose
(cd target/package/cbindgen-$(cargo run -- --version | cut -d ' ' -f 2) && cargo test --verbose)
- name: Test minimal-versions
run: |
cargo update -Zminimal-versions
cargo test
10 changes: 9 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,24 @@ jobs:
run: |
strip target/release/cbindgen
- name: Get cbindgen's version
- name: Handle release data and files
id: tagName
run: |
VERSION=$(cargo pkgid | cut -d# -f2 | cut -d: -f2)
echo "::set-output name=version::$VERSION"
# Steps to extract the last release notes from CHANGES:
# 1. Remove the first three lines
# 2. Stop at the next heading level
# 3. Remove the last line
# 4. Deindent the bullet points to avoid a markdown code block
tail -n +3 CHANGES | sed '/^##/q' |
sed '$ d' | awk '{$1=$1};1' > CHANGES.txt
- name: Create a release
uses: softprops/action-gh-release@v1
with:
name: v${{ steps.tagName.outputs.version }}
body_path: CHANGES.txt
files: |
target/release/cbindgen
env:
Expand Down
7 changes: 7 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.17.0

* Add with_parse_extra_bindings to builder. (#645)
* Support NonZero and fix incorrect simplification of Option<ptr> into ptr. (#647)
* Deal with name conflicts correctly in declaration type resolution. (#651)
* Support pointers to ZSTs. (#656)

## 0.16.0

* Remove artificial restriction on lifetime parameters on enums (#604)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
[package]
name = "cbindgen"
version = "0.16.0"
authors = ["Jeff Muizelaar <jmuizelaar@mozilla.com>",
"Kartikaya Gupta <kats@mozilla.com>",
"Ryan Hunt <rhunt@eqrion.net>"]
version = "0.17.0"
authors = [
"Emilio Cobos Álvarez <emilio@crisal.io>",
"Jeff Muizelaar <jmuizelaar@mozilla.com>",
"Kartikaya Gupta <kats@mozilla.com>",
"Ryan Hunt <rhunt@eqrion.net>"
]
license = "MPL-2.0"
description = "A tool for generating C bindings to Rust code."
keywords = ["bindings", "ffi", "code-generation"]
categories = ["external-ffi-bindings", "development-tools::ffi"]
repository = "https://github.com/eqrion/cbindgen/"
edition = "2018"
exclude = [
"tests/profile.rs", # Test relies in a sub-crate, see https://github.com/rust-lang/cargo/issues/9017
]

[badges]
travis-ci = { repository = "eqrion/cbindgen" }
Expand Down
61 changes: 39 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,37 @@
[Api Rustdoc]: https://img.shields.io/badge/api-rustdoc-blue.svg
[rustdoc]: https://docs.rs/cbindgen




[Read the full user docs here!](docs.md)




cbindgen creates C/C++11 headers for Rust libraries which expose a public C API.

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.

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.

There are two ways to use cbindgen: as a standalone program, or as a library (presumably in your build.rs).
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).

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



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.

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.

There are two ways to use cbindgen: as a standalone program, or as a library
(presumably in your build.rs). 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).

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

# Quick Start

Expand Down Expand Up @@ -58,18 +68,25 @@ See `cbindgen --help` for more options.

[Get a template cbindgen.toml here.](template.toml)



# Examples

We don't currently have a nice tailored example application, but [the tests](tests/rust/) contain plenty of interesting examples of our features.
We don't currently have a nice tailored example application, but [the
tests](tests/rust/) contain plenty of interesting examples of our features.

You may also find it interesting to browse the projects that are using cbindgen in production:
You may also find it interesting to browse the projects that are using cbindgen
in production:

* [milksnake](https://github.com/getsentry/milksnake)
* [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))
* [stylo](https://searchfox.org/mozilla-central/source/layout/style) ([generated header](https://searchfox.org/mozilla-central/source/__GENERATED__/layout/style/ServoStyleConsts.h))
* [wgpu-native](https://github.com/gfx-rs/wgpu-native) ([generated header](https://github.com/gfx-rs/wgpu-native/blob/master/ffi/wgpu.h))
* [etesync-rs](https://github.com/etesync/etesync-rs)

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

# Releases

cbindgen doesn't have a fixed release calendar, please file an issue requesting
a release if there's something fixed in trunk that you need released. Ping
`@emilio` for increased effect.
3 changes: 3 additions & 0 deletions docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,9 @@ line_length = 80
# default: 2
tab_width = 3

# Include doc comments from Rust as documentation
documentation = true

# How the generated documentation should be commented.
#
# possible values:
Expand Down
9 changes: 9 additions & 0 deletions src/bindgen/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,15 @@ impl Builder {
self
}

#[allow(unused)]
pub fn with_parse_extra_bindings<S: AsRef<str>>(mut self, extra_bindings: &[S]) -> Builder {
self.config.parse.extra_bindings = extra_bindings
.iter()
.map(|x| String::from(x.as_ref()))
.collect();
self
}

#[allow(unused)]
pub fn with_documentation(mut self, documentation: bool) -> Builder {
self.config.documentation = documentation;
Expand Down
1 change: 1 addition & 0 deletions src/bindgen/cargo/cargo_expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ impl error::Error for Error {

/// Use rustc to expand and pretty print the crate into a single file,
/// removing any macros in the process.
#[allow(clippy::too_many_arguments)]
pub fn expand(
manifest_path: &Path,
crate_name: &str,
Expand Down
6 changes: 5 additions & 1 deletion src/bindgen/cdecl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,11 @@ impl CDecl {
self.declarators.push(CDeclarator::Array(len));
self.build_type(t, is_const, config);
}
Type::FuncPtr(ref ret, ref args) => {
Type::FuncPtr {
ref ret,
ref args,
is_nullable: _,
} => {
let args = args
.iter()
.map(|(ref name, ref ty)| (name.clone(), CDecl::from_type(ty, config)))
Expand Down
3 changes: 2 additions & 1 deletion src/bindgen/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ impl Language {

/// Controls what type of line endings are used in the generated code.
#[derive(Debug, Clone, Copy)]
#[allow(clippy::upper_case_acronyms)]
pub enum LineEndingStyle {
/// Use Unix-style linefeed characters
LF,
Expand Down Expand Up @@ -961,7 +962,7 @@ pub struct Config {
pub constant: ConstantConfig,
/// Preprocessor defines to use when generating #ifdef's for #[cfg]
pub defines: HashMap<String, String>,
/// Include doc comments from rust as documentation
/// Include doc comments from Rust as documentation
pub documentation: bool,
/// How documentation comments should be styled.
pub documentation_style: DocumentationStyle,
Expand Down
55 changes: 27 additions & 28 deletions src/bindgen/declarationtyperesolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::collections::HashSet;

use crate::bindgen::ir::Path;
use std::collections::hash_map::Entry;
use std::collections::HashMap;

#[derive(Default)]
pub struct DeclarationTypeResolver {
structs: HashSet<Path>,
enums: HashSet<Path>,
unions: HashSet<Path>,
impl DeclarationType {
pub fn to_str(self) -> &'static str {
match self {
DeclarationType::Struct => "struct",
DeclarationType::Enum => "enum",
DeclarationType::Union => "union",
}
}
}

#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
Expand All @@ -20,39 +23,35 @@ pub enum DeclarationType {
Union,
}

impl DeclarationType {
pub fn to_str(self) -> &'static str {
match self {
DeclarationType::Struct => "struct",
DeclarationType::Enum => "enum",
DeclarationType::Union => "union",
}
}
#[derive(Default)]
pub struct DeclarationTypeResolver {
types: HashMap<Path, Option<DeclarationType>>,
}

impl DeclarationTypeResolver {
fn insert(&mut self, path: &Path, ty: Option<DeclarationType>) {
if let Entry::Vacant(vacant_entry) = self.types.entry(path.clone()) {
vacant_entry.insert(ty);
}
}

pub fn add_enum(&mut self, path: &Path) {
self.enums.insert(path.clone());
self.insert(path, Some(DeclarationType::Enum));
}

pub fn add_struct(&mut self, path: &Path) {
self.structs.insert(path.clone());
self.insert(path, Some(DeclarationType::Struct));
}

pub fn add_union(&mut self, path: &Path) {
self.unions.insert(path.clone());
self.insert(path, Some(DeclarationType::Union));
}

pub fn add_none(&mut self, path: &Path) {
self.insert(path, None);
}

pub fn type_for(&self, path: &Path) -> Option<DeclarationType> {
// FIXME: don't look up by name, but by full path:
if self.structs.contains(path) {
Some(DeclarationType::Struct)
} else if self.enums.contains(path) {
Some(DeclarationType::Enum)
} else if self.unions.contains(path) {
Some(DeclarationType::Union)
} else {
None
}
*self.types.get(path)?
}
}
13 changes: 5 additions & 8 deletions src/bindgen/ir/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,12 @@ impl Cfg {
}
syn::NestedMeta::Meta(syn::Meta::NameValue(syn::MetaNameValue {
ref path,
ref lit,
lit: syn::Lit::Str(ref value),
..
})) => match *lit {
syn::Lit::Str(ref value) => Cfg::Named(
format!("{}", path.segments.first().unwrap().ident),
value.value(),
),
_ => return None,
},
})) => Cfg::Named(
format!("{}", path.segments.first().unwrap().ident),
value.value(),
),
syn::NestedMeta::Meta(syn::Meta::List(syn::MetaList {
ref path,
ref nested,
Expand Down
Loading

0 comments on commit c42f9bb

Please sign in to comment.