From f897814b9d46ad7e391b45019d0ef093f52cc004 Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Fri, 4 Apr 2025 17:20:11 +0200 Subject: [PATCH 1/3] Add ``prefix_excludes`` If a prefix is set, allow to not prefix specified objects. This is important e.g. when using 3rd Party objects in a Rust projects, that should not be renamed. --- src/bindgen/config.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bindgen/config.rs b/src/bindgen/config.rs index 31316503d..9066ee80d 100644 --- a/src/bindgen/config.rs +++ b/src/bindgen/config.rs @@ -335,6 +335,8 @@ pub struct ExportConfig { pub body: HashMap, /// A prefix to add before the name of every item pub prefix: Option, + /// A list of items not to add a prefix to (should one be specified). + pub prefix_excludes: Vec, /// Types of items to generate. pub item_types: Vec, /// Whether renaming overrides or extends prefixing. @@ -376,7 +378,9 @@ impl ExportConfig { } } if let Some(ref prefix) = self.prefix { - item_name.insert_str(0, prefix); + if !self.prefix_excludes.contains(&item_name) { + item_name.insert_str(0, prefix); + } } } } From c579815e5588bf17fe95172192f9433e53013fec Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Fri, 4 Apr 2025 17:29:31 +0200 Subject: [PATCH 2/3] Add test --- .../expectations-symbols/prefix_exclude.c.sym | 3 +++ tests/expectations/prefix_exclude.c | 18 +++++++++++++ tests/expectations/prefix_exclude.compat.c | 26 +++++++++++++++++++ tests/expectations/prefix_exclude.cpp | 23 ++++++++++++++++ tests/expectations/prefix_exclude.pyx | 19 ++++++++++++++ tests/expectations/prefix_exclude_both.c | 18 +++++++++++++ .../expectations/prefix_exclude_both.compat.c | 26 +++++++++++++++++++ tests/expectations/prefix_exclude_tag.c | 18 +++++++++++++ .../expectations/prefix_exclude_tag.compat.c | 26 +++++++++++++++++++ tests/expectations/prefix_exclude_tag.pyx | 19 ++++++++++++++ tests/rust/prefix_exclude.rs | 15 +++++++++++ tests/rust/prefix_exclude.toml | 3 +++ 12 files changed, 214 insertions(+) create mode 100644 tests/expectations-symbols/prefix_exclude.c.sym create mode 100644 tests/expectations/prefix_exclude.c create mode 100644 tests/expectations/prefix_exclude.compat.c create mode 100644 tests/expectations/prefix_exclude.cpp create mode 100644 tests/expectations/prefix_exclude.pyx create mode 100644 tests/expectations/prefix_exclude_both.c create mode 100644 tests/expectations/prefix_exclude_both.compat.c create mode 100644 tests/expectations/prefix_exclude_tag.c create mode 100644 tests/expectations/prefix_exclude_tag.compat.c create mode 100644 tests/expectations/prefix_exclude_tag.pyx create mode 100644 tests/rust/prefix_exclude.rs create mode 100644 tests/rust/prefix_exclude.toml diff --git a/tests/expectations-symbols/prefix_exclude.c.sym b/tests/expectations-symbols/prefix_exclude.c.sym new file mode 100644 index 000000000..085e953fd --- /dev/null +++ b/tests/expectations-symbols/prefix_exclude.c.sym @@ -0,0 +1,3 @@ +{ +caller; +}; \ No newline at end of file diff --git a/tests/expectations/prefix_exclude.c b/tests/expectations/prefix_exclude.c new file mode 100644 index 000000000..cc5585c84 --- /dev/null +++ b/tests/expectations/prefix_exclude.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +typedef struct { + uintptr_t id; +} Struct1; + +typedef struct { + uintptr_t id; +} PREFIX_Struct2; + +typedef int32_t PREFIX_Type1[3]; + +typedef int32_t Type2[15]; + +void caller(Struct1 s1, PREFIX_Struct2 s2, PREFIX_Type1 t1, Type2 t2); diff --git a/tests/expectations/prefix_exclude.compat.c b/tests/expectations/prefix_exclude.compat.c new file mode 100644 index 000000000..8ef2b2732 --- /dev/null +++ b/tests/expectations/prefix_exclude.compat.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +typedef struct { + uintptr_t id; +} Struct1; + +typedef struct { + uintptr_t id; +} PREFIX_Struct2; + +typedef int32_t PREFIX_Type1[3]; + +typedef int32_t Type2[15]; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void caller(Struct1 s1, PREFIX_Struct2 s2, PREFIX_Type1 t1, Type2 t2); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/prefix_exclude.cpp b/tests/expectations/prefix_exclude.cpp new file mode 100644 index 000000000..7f6a6f0f9 --- /dev/null +++ b/tests/expectations/prefix_exclude.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include + +struct Struct1 { + uintptr_t id; +}; + +struct PREFIX_Struct2 { + uintptr_t id; +}; + +using PREFIX_Type1 = int32_t[3]; + +using Type2 = int32_t[15]; + +extern "C" { + +void caller(Struct1 s1, PREFIX_Struct2 s2, PREFIX_Type1 t1, Type2 t2); + +} // extern "C" diff --git a/tests/expectations/prefix_exclude.pyx b/tests/expectations/prefix_exclude.pyx new file mode 100644 index 000000000..710122bbb --- /dev/null +++ b/tests/expectations/prefix_exclude.pyx @@ -0,0 +1,19 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + ctypedef struct Struct1: + uintptr_t id; + + ctypedef struct PREFIX_Struct2: + uintptr_t id; + + ctypedef int32_t PREFIX_Type1[3]; + + ctypedef int32_t Type2[15]; + + void caller(Struct1 s1, PREFIX_Struct2 s2, PREFIX_Type1 t1, Type2 t2); diff --git a/tests/expectations/prefix_exclude_both.c b/tests/expectations/prefix_exclude_both.c new file mode 100644 index 000000000..8abfbb429 --- /dev/null +++ b/tests/expectations/prefix_exclude_both.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +typedef struct Struct1 { + uintptr_t id; +} Struct1; + +typedef struct PREFIX_Struct2 { + uintptr_t id; +} PREFIX_Struct2; + +typedef int32_t PREFIX_Type1[3]; + +typedef int32_t Type2[15]; + +void caller(struct Struct1 s1, struct PREFIX_Struct2 s2, PREFIX_Type1 t1, Type2 t2); diff --git a/tests/expectations/prefix_exclude_both.compat.c b/tests/expectations/prefix_exclude_both.compat.c new file mode 100644 index 000000000..f54836400 --- /dev/null +++ b/tests/expectations/prefix_exclude_both.compat.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +typedef struct Struct1 { + uintptr_t id; +} Struct1; + +typedef struct PREFIX_Struct2 { + uintptr_t id; +} PREFIX_Struct2; + +typedef int32_t PREFIX_Type1[3]; + +typedef int32_t Type2[15]; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void caller(struct Struct1 s1, struct PREFIX_Struct2 s2, PREFIX_Type1 t1, Type2 t2); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/prefix_exclude_tag.c b/tests/expectations/prefix_exclude_tag.c new file mode 100644 index 000000000..d9f973cd0 --- /dev/null +++ b/tests/expectations/prefix_exclude_tag.c @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +struct Struct1 { + uintptr_t id; +}; + +struct PREFIX_Struct2 { + uintptr_t id; +}; + +typedef int32_t PREFIX_Type1[3]; + +typedef int32_t Type2[15]; + +void caller(struct Struct1 s1, struct PREFIX_Struct2 s2, PREFIX_Type1 t1, Type2 t2); diff --git a/tests/expectations/prefix_exclude_tag.compat.c b/tests/expectations/prefix_exclude_tag.compat.c new file mode 100644 index 000000000..a6ac31dba --- /dev/null +++ b/tests/expectations/prefix_exclude_tag.compat.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include + +struct Struct1 { + uintptr_t id; +}; + +struct PREFIX_Struct2 { + uintptr_t id; +}; + +typedef int32_t PREFIX_Type1[3]; + +typedef int32_t Type2[15]; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void caller(struct Struct1 s1, struct PREFIX_Struct2 s2, PREFIX_Type1 t1, Type2 t2); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/prefix_exclude_tag.pyx b/tests/expectations/prefix_exclude_tag.pyx new file mode 100644 index 000000000..c413d47d4 --- /dev/null +++ b/tests/expectations/prefix_exclude_tag.pyx @@ -0,0 +1,19 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + cdef struct Struct1: + uintptr_t id; + + cdef struct PREFIX_Struct2: + uintptr_t id; + + ctypedef int32_t PREFIX_Type1[3]; + + ctypedef int32_t Type2[15]; + + void caller(Struct1 s1, PREFIX_Struct2 s2, PREFIX_Type1 t1, Type2 t2); diff --git a/tests/rust/prefix_exclude.rs b/tests/rust/prefix_exclude.rs new file mode 100644 index 000000000..76f71a11a --- /dev/null +++ b/tests/rust/prefix_exclude.rs @@ -0,0 +1,15 @@ +pub type Type1 = [i32; 3]; +pub type Type2 = [i32; 15]; + +#[repr(C)] +pub struct Struct1 { + id: usize, +} + +#[repr(C)] +pub struct Struct2 { + id: usize, +} + +#[no_mangle] +pub extern "C" fn caller(s1: Struct1, s2: Struct2, t1: Type1, t2: Type2) {} diff --git a/tests/rust/prefix_exclude.toml b/tests/rust/prefix_exclude.toml new file mode 100644 index 000000000..d53558075 --- /dev/null +++ b/tests/rust/prefix_exclude.toml @@ -0,0 +1,3 @@ +[export] +prefix = "PREFIX_" +prefix_excludes = ["Type2", "Struct1"] From 7e7a64ee5d31b508bd653a36d94950b44a28e28c Mon Sep 17 00:00:00 2001 From: Julien Gacon Date: Mon, 7 Apr 2025 15:30:27 +0200 Subject: [PATCH 3/3] add docs and builder function --- docs.md | 4 ++++ src/bindgen/builder.rs | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/docs.md b/docs.md index 3d00d814d..ea152879c 100644 --- a/docs.md +++ b/docs.md @@ -609,6 +609,10 @@ exclude = ["Bad"] # default: no prefix is added prefix = "CAPI_" +# If specific items should not get above prefix, they can be listed here +# default: [] +prefix_excludes = ["ItemWithoutPrefix"] + # Types of items that we'll generate. If empty, then all types of item are emitted. # # possible items: (TODO: explain these in detail) diff --git a/src/bindgen/builder.rs b/src/bindgen/builder.rs index d47919b98..281d3df92 100644 --- a/src/bindgen/builder.rs +++ b/src/bindgen/builder.rs @@ -194,6 +194,15 @@ impl Builder { self } + #[allow(unused)] + pub fn exclude_item_prefix>(mut self, item_name: S) -> Builder { + self.config + .export + .prefix_excludes + .push(String::from(item_name.as_ref())); + self + } + #[allow(unused)] pub fn with_parse_deps(mut self, parse_deps: bool) -> Builder { self.config.parse.parse_deps = parse_deps;