Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add no-export in cbindgen.toml config #924

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 9 additions & 3 deletions docs.md
Expand Up @@ -267,8 +267,6 @@ pub mod my_uninteresting_mod; // This won't be scanned by cbindgen.

cbindgen will usually emit all items it finds, as instructed by the parse and export config sections. This annotation will make cbindgen skip this item from the output, while still being aware of it. This is useful for a) suppressing "Can't find" errors and b) emitting `struct my_struct` for types in a different header (rather than a bare `my_struct`).

There is no equivalent config for this annotation - by comparison, the export exclude config will cause cbindgen to not be aware of the item at all.

Note that cbindgen will still traverse `no-export` structs that are `repr(C)` to emit types present in the fields. You will need to manually exclude those types in your config if desired.

```
Expand Down Expand Up @@ -575,10 +573,18 @@ usize_is_size_t = true
# default: []
include = ["MyOrphanStruct", "MyGreatTypeRename"]

# A list of items to not include in the generated bindings
# A list of items to not include in the generated bindings. The items won't get parsed
# at all.
#
# default: []
exclude = ["Bad"]

# A list of items to not export in the generated bindings. The items will still get
# parsed.
#
# default: []
tisonkun marked this conversation as resolved.
Show resolved Hide resolved
no_export = ["Inner"]

# A prefix to add before the name of every item
# default: no prefix is added
prefix = "CAPI_"
Expand Down
10 changes: 10 additions & 0 deletions src/bindgen/bindings.rs
Expand Up @@ -363,6 +363,16 @@ impl Bindings {
continue;
}

if self
.config
.export
.no_export
.iter()
.any(|i| i == item.deref().export_name())
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very sure if export_name is desired here but it works for me locally.

{
continue;
}

out.new_line_if_not_start();
match *item {
ItemContainer::Constant(..) => unreachable!(),
Expand Down
9 changes: 9 additions & 0 deletions src/bindgen/builder.rs
Expand Up @@ -179,6 +179,15 @@ impl Builder {
self
}

#[allow(unused)]
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how it works but follow the "include"/"exclude" pattern above.

pub fn no_export_item<S: AsRef<str>>(mut self, item_name: S) -> Builder {
self.config
.export
.no_export
.push(String::from(item_name.as_ref()));
self
}

#[allow(unused)]
pub fn rename_item<S: AsRef<str>>(mut self, from: S, to: S) -> Builder {
self.config
Expand Down
2 changes: 2 additions & 0 deletions src/bindgen/config.rs
Expand Up @@ -327,6 +327,8 @@ pub struct ExportConfig {
pub include: Vec<String>,
/// A list of items to not include in the generated bindings
pub exclude: Vec<String>,
/// A list of items to not export in the generated bindings
pub no_export: Vec<String>,
/// Table of name conversions to apply to item names
pub rename: HashMap<String, String>,
/// Table of raw strings to prepend to the body of items.
Expand Down
20 changes: 20 additions & 0 deletions tests/expectations/inner_no_export.compat.c
@@ -0,0 +1,20 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

/**
* Outer docs should be exported.
*/
typedef struct {
Inner *inner;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@emilio weird. When I use the same code for opendal c binding, it generates something like struct Inner *inner for such field. But in cbindgen tests it cannot generate the correct result.

} Outer;

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void root(const Outer *a);

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
14 changes: 14 additions & 0 deletions tests/rust/inner_no_export.rs
@@ -0,0 +1,14 @@
/// Inner docs should not be exported.
pub struct Inner {
a: i32,
}

/// Outer docs should be exported.
#[repr(C)]
pub struct Outer {
inner: *mut Inner,
}

#[no_mangle]
pub extern "C" fn root(a: *const Outer)
{ }
12 changes: 12 additions & 0 deletions tests/rust/inner_no_export.toml
@@ -0,0 +1,12 @@
cpp_compat = true
language = "C"
no_includes = true
sys_includes = ["stdint.h", "stddef.h", "stdbool.h"]

[parse]
parse_deps = true

[export]
no_export = [
"Inner",
]