2016-10-24 14:13:13 -07:00
|
|
|
//! Generate Rust bindings for C and C++ libraries.
|
|
|
|
//!
|
|
|
|
//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
|
|
|
|
//! functions and use types defined in the header.
|
|
|
|
//!
|
2017-04-24 01:08:19 -07:00
|
|
|
//! See the [`Builder`](./struct.Builder.html) struct for usage.
|
2018-04-02 11:47:03 -07:00
|
|
|
//!
|
2018-12-10 11:50:40 +01:00
|
|
|
//! See the [Users Guide](https://rust-lang.github.io/rust-bindgen/) for
|
2018-04-02 11:47:03 -07:00
|
|
|
//! additional documentation.
|
2016-10-24 14:13:13 -07:00
|
|
|
#![deny(missing_docs)]
|
2016-12-23 12:37:16 +01:00
|
|
|
#![deny(unused_extern_crates)]
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
// To avoid rather annoying warnings when matching with CXCursor_xxx as a
|
|
|
|
// constant.
|
|
|
|
#![allow(non_upper_case_globals)]
|
2017-08-22 18:53:55 -07:00
|
|
|
// `quote!` nests quite deeply.
|
2019-09-17 09:44:06 +09:00
|
|
|
#![recursion_limit = "128"]
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
|
2018-08-10 19:16:38 -04:00
|
|
|
#[macro_use]
|
|
|
|
extern crate bitflags;
|
2016-10-24 14:58:10 -07:00
|
|
|
#[macro_use]
|
2016-11-16 09:27:13 +11:00
|
|
|
extern crate lazy_static;
|
2017-08-22 18:53:55 -07:00
|
|
|
#[macro_use]
|
|
|
|
extern crate quote;
|
2016-11-16 09:27:13 +11:00
|
|
|
|
|
|
|
#[cfg(feature = "logging")]
|
|
|
|
#[macro_use]
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
extern crate log;
|
2016-11-16 09:27:13 +11:00
|
|
|
|
|
|
|
#[cfg(not(feature = "logging"))]
|
2016-10-22 19:39:37 +08:00
|
|
|
#[macro_use]
|
2016-11-16 09:27:13 +11:00
|
|
|
mod log_stubs;
|
2014-05-15 17:33:42 +01:00
|
|
|
|
2017-04-06 15:21:33 -07:00
|
|
|
#[macro_use]
|
|
|
|
mod extra_assertions;
|
|
|
|
|
2016-10-24 14:58:10 -07:00
|
|
|
// A macro to declare an internal module for which we *must* provide
|
2017-04-06 14:38:05 -07:00
|
|
|
// documentation for. If we are building with the "testing_only_docs" feature,
|
|
|
|
// then the module is declared public, and our `#![deny(missing_docs)]` pragma
|
|
|
|
// applies to it. This feature is used in CI, so we won't let anything slip by
|
2016-10-24 14:58:10 -07:00
|
|
|
// undocumented. Normal builds, however, will leave the module private, so that
|
|
|
|
// we don't expose internals to library consumers.
|
|
|
|
macro_rules! doc_mod {
|
2016-11-01 12:39:37 +01:00
|
|
|
($m:ident, $doc_mod_name:ident) => {
|
2020-11-25 15:05:30 +01:00
|
|
|
#[cfg(feature = "testing_only_docs")]
|
|
|
|
pub mod $doc_mod_name {
|
|
|
|
//! Autogenerated documentation module.
|
|
|
|
pub use super::$m::*;
|
2016-10-24 14:58:10 -07:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
macro_rules! fn_with_regex_arg {
|
|
|
|
($(#[$attrs:meta])* pub fn $($tokens:tt)*) => {
|
|
|
|
$(#[$attrs])*
|
|
|
|
/// Check the [regular expression arguments] section and the [regex] crate
|
|
|
|
/// documentation for further information.
|
|
|
|
///
|
|
|
|
/// [regular expression arguments]: ./struct.Builder.html#regular-expression-arguments
|
|
|
|
/// [regex]: <https://docs.rs/regex>
|
|
|
|
pub fn $($tokens)*
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-11-01 12:39:37 +01:00
|
|
|
mod clang;
|
2017-08-22 18:53:55 -07:00
|
|
|
mod codegen;
|
2021-04-08 17:26:55 +00:00
|
|
|
mod deps;
|
2017-08-13 13:12:21 -07:00
|
|
|
mod features;
|
2023-01-20 15:12:42 -05:00
|
|
|
pub mod ir;
|
2016-11-01 12:39:37 +01:00
|
|
|
mod parse;
|
|
|
|
mod regex_set;
|
2017-08-29 22:08:37 -05:00
|
|
|
mod time;
|
2016-11-01 12:39:37 +01:00
|
|
|
|
2017-03-17 12:16:26 -04:00
|
|
|
pub mod callbacks;
|
2016-11-06 20:32:37 +01:00
|
|
|
|
2016-11-01 12:39:37 +01:00
|
|
|
doc_mod!(clang, clang_docs);
|
2017-08-13 13:12:21 -07:00
|
|
|
doc_mod!(features, features_docs);
|
2016-11-01 12:39:37 +01:00
|
|
|
doc_mod!(ir, ir_docs);
|
|
|
|
doc_mod!(parse, parse_docs);
|
|
|
|
doc_mod!(regex_set, regex_set_docs);
|
2016-10-24 14:58:10 -07:00
|
|
|
|
2023-02-07 10:13:48 -05:00
|
|
|
use codegen::CodegenError;
|
2022-11-22 11:25:13 -05:00
|
|
|
use ir::comment;
|
|
|
|
|
2022-09-23 08:30:49 +02:00
|
|
|
pub use crate::codegen::{
|
|
|
|
AliasVariation, EnumVariation, MacroTypeVariation, NonCopyUnionStyle,
|
|
|
|
};
|
2020-04-27 15:37:47 -04:00
|
|
|
use crate::features::RustFeatures;
|
2020-04-27 18:27:32 -04:00
|
|
|
pub use crate::features::{
|
|
|
|
RustTarget, LATEST_STABLE_RUST, RUST_TARGET_STRINGS,
|
|
|
|
};
|
2020-04-27 15:37:47 -04:00
|
|
|
use crate::ir::context::{BindgenContext, ItemId};
|
2022-11-02 15:30:34 -05:00
|
|
|
pub use crate::ir::function::Abi;
|
2020-04-27 15:37:47 -04:00
|
|
|
use crate::ir::item::Item;
|
2022-11-24 11:17:08 -05:00
|
|
|
use crate::parse::ParseError;
|
2023-01-20 15:12:42 -05:00
|
|
|
pub use crate::regex_set::RegexSet;
|
2016-10-31 16:29:02 -07:00
|
|
|
|
2017-10-28 12:31:36 +02:00
|
|
|
use std::borrow::Cow;
|
2022-10-03 13:57:04 -05:00
|
|
|
use std::env;
|
2017-07-13 14:17:53 -07:00
|
|
|
use std::fs::{File, OpenOptions};
|
2016-11-01 12:56:14 +01:00
|
|
|
use std::io::{self, Write};
|
2017-07-13 14:17:53 -07:00
|
|
|
use std::path::{Path, PathBuf};
|
2017-07-17 10:03:55 -07:00
|
|
|
use std::process::{Command, Stdio};
|
2022-09-26 13:22:15 -05:00
|
|
|
use std::rc::Rc;
|
2014-06-15 17:48:18 +08:00
|
|
|
|
2018-12-23 19:20:50 +01:00
|
|
|
// Some convenient typedefs for a fast hash map and hash set.
|
2019-09-22 16:55:50 +03:00
|
|
|
type HashMap<K, V> = ::rustc_hash::FxHashMap<K, V>;
|
|
|
|
type HashSet<K> = ::rustc_hash::FxHashSet<K>;
|
2019-09-17 09:44:06 +09:00
|
|
|
pub(crate) use std::collections::hash_map::Entry;
|
2018-12-23 19:20:50 +01:00
|
|
|
|
2020-08-04 14:04:35 +08:00
|
|
|
/// Default prefix for the anon fields.
|
2021-10-25 22:06:54 +09:00
|
|
|
pub const DEFAULT_ANON_FIELDS_PREFIX: &str = "__bindgen_anon_";
|
2023-02-07 10:13:48 -05:00
|
|
|
const DEFAULT_NON_EXTERN_FNS_SUFFIX: &str = "__extern";
|
2020-08-04 14:04:35 +08:00
|
|
|
|
2020-11-26 12:09:15 +01:00
|
|
|
fn file_is_cpp(name_file: &str) -> bool {
|
|
|
|
name_file.ends_with(".hpp") ||
|
|
|
|
name_file.ends_with(".hxx") ||
|
|
|
|
name_file.ends_with(".hh") ||
|
|
|
|
name_file.ends_with(".h++")
|
|
|
|
}
|
|
|
|
|
2018-07-26 15:08:50 -04:00
|
|
|
fn args_are_cpp(clang_args: &[String]) -> bool {
|
2020-11-26 12:09:15 +01:00
|
|
|
for w in clang_args.windows(2) {
|
|
|
|
if w[0] == "-xc++" || w[1] == "-xc++" {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if w[0] == "-x" && w[1] == "c++" {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if w[0] == "-include" && file_is_cpp(&w[1]) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
false
|
2018-07-26 15:08:50 -04:00
|
|
|
}
|
|
|
|
|
2018-08-10 19:16:38 -04:00
|
|
|
bitflags! {
|
|
|
|
/// A type used to indicate which kind of items we have to generate.
|
|
|
|
pub struct CodegenConfig: u32 {
|
|
|
|
/// Whether to generate functions.
|
2018-08-13 20:23:38 -04:00
|
|
|
const FUNCTIONS = 1 << 0;
|
2018-08-10 19:16:38 -04:00
|
|
|
/// Whether to generate types.
|
2018-08-13 20:23:38 -04:00
|
|
|
const TYPES = 1 << 1;
|
2018-08-10 19:16:38 -04:00
|
|
|
/// Whether to generate constants.
|
2018-08-13 20:23:38 -04:00
|
|
|
const VARS = 1 << 2;
|
2018-08-10 19:16:38 -04:00
|
|
|
/// Whether to generate methods.
|
2018-08-13 20:23:38 -04:00
|
|
|
const METHODS = 1 << 3;
|
2018-08-10 19:16:38 -04:00
|
|
|
/// Whether to generate constructors
|
2018-08-13 20:23:38 -04:00
|
|
|
const CONSTRUCTORS = 1 << 4;
|
2018-08-10 19:16:38 -04:00
|
|
|
/// Whether to generate destructors.
|
2018-08-13 20:23:38 -04:00
|
|
|
const DESTRUCTORS = 1 << 5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CodegenConfig {
|
|
|
|
/// Returns true if functions should be generated.
|
|
|
|
pub fn functions(self) -> bool {
|
|
|
|
self.contains(CodegenConfig::FUNCTIONS)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns true if types should be generated.
|
|
|
|
pub fn types(self) -> bool {
|
|
|
|
self.contains(CodegenConfig::TYPES)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns true if constants should be generated.
|
|
|
|
pub fn vars(self) -> bool {
|
|
|
|
self.contains(CodegenConfig::VARS)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns true if methds should be generated.
|
|
|
|
pub fn methods(self) -> bool {
|
|
|
|
self.contains(CodegenConfig::METHODS)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns true if constructors should be generated.
|
|
|
|
pub fn constructors(self) -> bool {
|
|
|
|
self.contains(CodegenConfig::CONSTRUCTORS)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns true if destructors should be generated.
|
|
|
|
pub fn destructors(self) -> bool {
|
|
|
|
self.contains(CodegenConfig::DESTRUCTORS)
|
2016-12-04 15:15:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for CodegenConfig {
|
|
|
|
fn default() -> Self {
|
|
|
|
CodegenConfig::all()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Configure and generate Rust bindings for a C/C++ header.
|
|
|
|
///
|
|
|
|
/// This is the main entry point to the library.
|
|
|
|
///
|
|
|
|
/// ```ignore
|
|
|
|
/// use bindgen::builder;
|
|
|
|
///
|
|
|
|
/// // Configure and generate bindings.
|
2018-03-04 14:43:13 +01:00
|
|
|
/// let bindings = builder().header("path/to/input/header")
|
2021-02-11 08:58:46 +01:00
|
|
|
/// .allowlist_type("SomeCoolClass")
|
|
|
|
/// .allowlist_function("do_some_cool_thing")
|
2021-12-08 09:10:05 +09:00
|
|
|
/// .generate()?;
|
2016-10-24 14:13:13 -07:00
|
|
|
///
|
|
|
|
/// // Write the generated bindings to an output file.
|
2018-03-04 14:43:13 +01:00
|
|
|
/// bindings.write_to_file("path/to/output.rs")?;
|
2016-10-24 14:13:13 -07:00
|
|
|
/// ```
|
2018-03-12 22:48:17 -04:00
|
|
|
///
|
|
|
|
/// # Enums
|
|
|
|
///
|
|
|
|
/// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on
|
|
|
|
/// the pattern passed to several methods:
|
|
|
|
///
|
2018-03-17 16:55:53 -04:00
|
|
|
/// 1. [`constified_enum_module()`](#method.constified_enum_module)
|
|
|
|
/// 2. [`bitfield_enum()`](#method.bitfield_enum)
|
2019-11-14 22:55:05 +11:00
|
|
|
/// 3. [`newtype_enum()`](#method.newtype_enum)
|
|
|
|
/// 4. [`rustified_enum()`](#method.rustified_enum)
|
2018-03-12 22:48:17 -04:00
|
|
|
///
|
|
|
|
/// For each C enum, bindgen tries to match the pattern in the following order:
|
|
|
|
///
|
2018-03-17 16:55:53 -04:00
|
|
|
/// 1. Constified enum module
|
|
|
|
/// 2. Bitfield enum
|
2019-11-14 22:55:05 +11:00
|
|
|
/// 3. Newtype enum
|
|
|
|
/// 4. Rustified enum
|
2018-03-12 22:48:17 -04:00
|
|
|
///
|
|
|
|
/// If none of the above patterns match, then bindgen will generate a set of Rust constants.
|
2020-06-04 23:50:01 -04:00
|
|
|
///
|
|
|
|
/// # Clang arguments
|
|
|
|
///
|
|
|
|
/// Extra arguments can be passed to with clang:
|
|
|
|
/// 1. [`clang_arg()`](#method.clang_arg): takes a single argument
|
|
|
|
/// 2. [`clang_args()`](#method.clang_args): takes an iterator of arguments
|
|
|
|
/// 3. `BINDGEN_EXTRA_CLANG_ARGS` environment variable: whitespace separate
|
|
|
|
/// environment variable of arguments
|
|
|
|
///
|
|
|
|
/// Clang arguments specific to your crate should be added via the
|
|
|
|
/// `clang_arg()`/`clang_args()` methods.
|
|
|
|
///
|
|
|
|
/// End-users of the crate may need to set the `BINDGEN_EXTRA_CLANG_ARGS` environment variable to
|
|
|
|
/// add additional arguments. For example, to build against a different sysroot a user could set
|
|
|
|
/// `BINDGEN_EXTRA_CLANG_ARGS` to `--sysroot=/path/to/sysroot`.
|
2022-11-14 12:34:05 -05:00
|
|
|
///
|
|
|
|
/// # Regular expression arguments
|
|
|
|
///
|
|
|
|
/// Some [`Builder`] methods like the `allowlist_*` and `blocklist_*` family of methods allow
|
|
|
|
/// regular expressions as arguments. These regular expressions will be parenthesized and wrapped
|
|
|
|
/// in `^` and `$`. So if `<regex>` is passed as argument, the regular expression to be stored will
|
|
|
|
/// be `^(<regex>)$`.
|
2022-12-15 16:02:28 -05:00
|
|
|
///
|
|
|
|
/// Releases of `bindgen` with a version lesser or equal to `0.62.0` used to accept the wildcard
|
|
|
|
/// pattern `*` as a valid regular expression. This behavior has been deprecated and the `.*`
|
|
|
|
/// pattern must be used instead.
|
2022-10-03 13:57:04 -05:00
|
|
|
#[derive(Debug, Default, Clone)]
|
2016-10-07 23:27:43 +11:00
|
|
|
pub struct Builder {
|
2015-05-06 12:27:56 +01:00
|
|
|
options: BindgenOptions,
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Construct a new [`Builder`](./struct.Builder.html).
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn builder() -> Builder {
|
2015-05-06 12:27:56 +01:00
|
|
|
Default::default()
|
|
|
|
}
|
|
|
|
|
2021-08-04 23:32:20 +02:00
|
|
|
fn get_extra_clang_args() -> Vec<String> {
|
|
|
|
// Add any extra arguments from the environment to the clang command line.
|
|
|
|
let extra_clang_args =
|
|
|
|
match get_target_dependent_env_var("BINDGEN_EXTRA_CLANG_ARGS") {
|
|
|
|
None => return vec![],
|
|
|
|
Some(s) => s,
|
|
|
|
};
|
|
|
|
// Try to parse it with shell quoting. If we fail, make it one single big argument.
|
|
|
|
if let Some(strings) = shlex::split(&extra_clang_args) {
|
|
|
|
return strings;
|
|
|
|
}
|
|
|
|
vec![extra_clang_args]
|
|
|
|
}
|
|
|
|
|
2016-10-07 23:27:43 +11:00
|
|
|
impl Builder {
|
2017-08-04 17:15:41 +02:00
|
|
|
/// Generates the command line flags use for creating `Builder`.
|
2017-04-13 08:15:11 +05:45
|
|
|
pub fn command_line_flags(&self) -> Vec<String> {
|
|
|
|
let mut output_vector: Vec<String> = Vec::new();
|
|
|
|
|
2022-10-03 13:57:04 -05:00
|
|
|
if let Some(header) = self.options.input_headers.last().cloned() {
|
2017-07-13 13:19:33 -07:00
|
|
|
// Positional argument 'header'
|
|
|
|
output_vector.push(header);
|
2017-04-13 08:15:11 +05:45
|
|
|
}
|
|
|
|
|
2017-12-09 12:05:41 -05:00
|
|
|
output_vector.push("--rust-target".into());
|
2017-08-13 13:12:21 -07:00
|
|
|
output_vector.push(self.options.rust_target.into());
|
|
|
|
|
2020-06-29 04:07:30 +02:00
|
|
|
// FIXME(emilio): This is a bit hacky, maybe we should stop re-using the
|
|
|
|
// RustFeatures to store the "disable_untagged_union" call, and make it
|
2021-12-08 09:10:05 +09:00
|
|
|
// a different flag that we check elsewhere / in generate().
|
2020-06-29 04:07:30 +02:00
|
|
|
if !self.options.rust_features.untagged_union &&
|
|
|
|
RustFeatures::from(self.options.rust_target).untagged_union
|
|
|
|
{
|
|
|
|
output_vector.push("--disable-untagged-union".into());
|
|
|
|
}
|
|
|
|
|
2018-06-04 05:35:17 -07:00
|
|
|
if self.options.default_enum_style != Default::default() {
|
2020-06-29 04:07:30 +02:00
|
|
|
output_vector.push("--default-enum-style".into());
|
2019-09-17 09:44:06 +09:00
|
|
|
output_vector.push(
|
|
|
|
match self.options.default_enum_style {
|
|
|
|
codegen::EnumVariation::Rust {
|
|
|
|
non_exhaustive: false,
|
|
|
|
} => "rust",
|
|
|
|
codegen::EnumVariation::Rust {
|
|
|
|
non_exhaustive: true,
|
|
|
|
} => "rust_non_exhaustive",
|
2022-09-06 16:59:49 -05:00
|
|
|
codegen::EnumVariation::NewType {
|
|
|
|
is_bitfield: true,
|
|
|
|
..
|
|
|
|
} => "bitfield",
|
|
|
|
codegen::EnumVariation::NewType {
|
|
|
|
is_bitfield: false,
|
|
|
|
is_global,
|
|
|
|
} => {
|
|
|
|
if is_global {
|
|
|
|
"newtype_global"
|
|
|
|
} else {
|
|
|
|
"newtype"
|
|
|
|
}
|
2019-11-15 00:26:41 +11:00
|
|
|
}
|
2019-09-17 09:44:06 +09:00
|
|
|
codegen::EnumVariation::Consts => "consts",
|
|
|
|
codegen::EnumVariation::ModuleConsts => "moduleconsts",
|
|
|
|
}
|
|
|
|
.into(),
|
|
|
|
)
|
2018-06-04 05:35:17 -07:00
|
|
|
}
|
2018-06-03 11:35:07 -07:00
|
|
|
|
2020-08-08 16:20:47 -07:00
|
|
|
if self.options.default_macro_constant_type != Default::default() {
|
|
|
|
output_vector.push("--default-macro-constant-type".into());
|
|
|
|
output_vector
|
|
|
|
.push(self.options.default_macro_constant_type.as_str().into());
|
|
|
|
}
|
|
|
|
|
2019-10-26 17:57:13 +08:00
|
|
|
if self.options.default_alias_style != Default::default() {
|
2020-06-29 04:07:30 +02:00
|
|
|
output_vector.push("--default-alias-style".into());
|
2019-10-26 17:57:13 +08:00
|
|
|
output_vector
|
|
|
|
.push(self.options.default_alias_style.as_str().into());
|
|
|
|
}
|
|
|
|
|
2022-09-23 08:30:49 +02:00
|
|
|
if self.options.default_non_copy_union_style != Default::default() {
|
|
|
|
output_vector.push("--default-non-copy-union-style".into());
|
|
|
|
output_vector.push(
|
|
|
|
self.options.default_non_copy_union_style.as_str().into(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-06-29 03:19:18 +02:00
|
|
|
let regex_sets = &[
|
|
|
|
(&self.options.bitfield_enums, "--bitfield-enum"),
|
|
|
|
(&self.options.newtype_enums, "--newtype-enum"),
|
2022-09-12 13:45:54 -05:00
|
|
|
(&self.options.newtype_global_enums, "--newtype-global-enum"),
|
2020-06-29 03:19:18 +02:00
|
|
|
(&self.options.rustified_enums, "--rustified-enum"),
|
|
|
|
(
|
|
|
|
&self.options.rustified_non_exhaustive_enums,
|
|
|
|
"--rustified-enum-non-exhaustive",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
&self.options.constified_enum_modules,
|
|
|
|
"--constified-enum-module",
|
|
|
|
),
|
|
|
|
(&self.options.constified_enums, "--constified-enum"),
|
|
|
|
(&self.options.type_alias, "--type-alias"),
|
|
|
|
(&self.options.new_type_alias, "--new-type-alias"),
|
|
|
|
(&self.options.new_type_alias_deref, "--new-type-alias-deref"),
|
2022-09-23 08:30:49 +02:00
|
|
|
(
|
|
|
|
&self.options.bindgen_wrapper_union,
|
|
|
|
"--bindgen-wrapper-union",
|
|
|
|
),
|
|
|
|
(&self.options.manually_drop_union, "--manually-drop-union"),
|
2021-02-11 08:58:46 +01:00
|
|
|
(&self.options.blocklisted_types, "--blocklist-type"),
|
|
|
|
(&self.options.blocklisted_functions, "--blocklist-function"),
|
|
|
|
(&self.options.blocklisted_items, "--blocklist-item"),
|
2021-11-26 01:42:47 +00:00
|
|
|
(&self.options.blocklisted_files, "--blocklist-file"),
|
2020-06-29 03:19:18 +02:00
|
|
|
(&self.options.opaque_types, "--opaque-type"),
|
2021-02-11 08:58:46 +01:00
|
|
|
(&self.options.allowlisted_functions, "--allowlist-function"),
|
|
|
|
(&self.options.allowlisted_types, "--allowlist-type"),
|
|
|
|
(&self.options.allowlisted_vars, "--allowlist-var"),
|
2021-11-29 13:03:26 +00:00
|
|
|
(&self.options.allowlisted_files, "--allowlist-file"),
|
2020-06-29 03:19:18 +02:00
|
|
|
(&self.options.no_partialeq_types, "--no-partialeq"),
|
|
|
|
(&self.options.no_copy_types, "--no-copy"),
|
2020-08-02 09:48:40 +08:00
|
|
|
(&self.options.no_debug_types, "--no-debug"),
|
2020-11-25 17:24:46 +08:00
|
|
|
(&self.options.no_default_types, "--no-default"),
|
2020-06-29 03:19:18 +02:00
|
|
|
(&self.options.no_hash_types, "--no-hash"),
|
2021-07-23 17:43:44 +02:00
|
|
|
(&self.options.must_use_types, "--must-use-type"),
|
2020-06-29 03:19:18 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
for (set, flag) in regex_sets {
|
|
|
|
for item in set.get_items() {
|
|
|
|
output_vector.push((*flag).to_owned());
|
2019-10-26 17:57:13 +08:00
|
|
|
output_vector.push(item.to_owned());
|
2020-06-29 03:19:18 +02:00
|
|
|
}
|
|
|
|
}
|
2018-10-12 17:31:36 -04:00
|
|
|
|
2022-11-02 15:30:34 -05:00
|
|
|
for (abi, set) in &self.options.abi_overrides {
|
|
|
|
for item in set.get_items() {
|
|
|
|
output_vector.push("--override-abi".to_owned());
|
|
|
|
output_vector.push(format!("{}={}", item, abi));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.layout_tests {
|
|
|
|
output_vector.push("--no-layout-tests".into());
|
|
|
|
}
|
|
|
|
|
2017-09-23 01:48:19 +03:00
|
|
|
if self.options.impl_debug {
|
|
|
|
output_vector.push("--impl-debug".into());
|
|
|
|
}
|
|
|
|
|
|
|
|
if self.options.impl_partialeq {
|
|
|
|
output_vector.push("--impl-partialeq".into());
|
|
|
|
}
|
|
|
|
|
2017-09-06 16:42:53 +01:00
|
|
|
if !self.options.derive_copy {
|
|
|
|
output_vector.push("--no-derive-copy".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.derive_debug {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-derive-debug".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.derive_default {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-derive-default".into());
|
|
|
|
} else {
|
|
|
|
output_vector.push("--with-derive-default".into());
|
|
|
|
}
|
|
|
|
|
2017-08-02 11:19:14 -07:00
|
|
|
if self.options.derive_hash {
|
|
|
|
output_vector.push("--with-derive-hash".into());
|
|
|
|
}
|
|
|
|
|
2017-09-19 17:13:14 +03:00
|
|
|
if self.options.derive_partialord {
|
|
|
|
output_vector.push("--with-derive-partialord".into());
|
|
|
|
}
|
|
|
|
|
2017-09-19 22:42:22 +03:00
|
|
|
if self.options.derive_ord {
|
|
|
|
output_vector.push("--with-derive-ord".into());
|
|
|
|
}
|
|
|
|
|
2017-08-10 16:22:48 -07:00
|
|
|
if self.options.derive_partialeq {
|
|
|
|
output_vector.push("--with-derive-partialeq".into());
|
|
|
|
}
|
|
|
|
|
2017-08-16 19:34:51 -05:00
|
|
|
if self.options.derive_eq {
|
|
|
|
output_vector.push("--with-derive-eq".into());
|
|
|
|
}
|
|
|
|
|
2017-08-29 22:08:37 -05:00
|
|
|
if self.options.time_phases {
|
|
|
|
output_vector.push("--time-phases".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.generate_comments {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-doc-comments".into());
|
|
|
|
}
|
|
|
|
|
2021-02-11 08:58:46 +01:00
|
|
|
if !self.options.allowlist_recursively {
|
|
|
|
output_vector.push("--no-recursive-allowlist".into());
|
2017-04-13 08:15:11 +05:45
|
|
|
}
|
2017-04-14 14:37:09 -07:00
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.objc_extern_crate {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--objc-extern-crate".into());
|
|
|
|
}
|
2017-04-14 14:37:09 -07:00
|
|
|
|
2018-10-04 16:14:27 +02:00
|
|
|
if self.options.generate_block {
|
|
|
|
output_vector.push("--generate-block".into());
|
|
|
|
}
|
|
|
|
|
2018-09-01 00:55:43 +08:00
|
|
|
if self.options.block_extern_crate {
|
|
|
|
output_vector.push("--block-extern-crate".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.builtins {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--builtins".into());
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(ref prefix) = self.options.ctypes_prefix {
|
|
|
|
output_vector.push("--ctypes-prefix".into());
|
|
|
|
output_vector.push(prefix.clone());
|
|
|
|
}
|
|
|
|
|
2020-08-04 14:04:35 +08:00
|
|
|
if self.options.anon_fields_prefix != DEFAULT_ANON_FIELDS_PREFIX {
|
|
|
|
output_vector.push("--anon-fields-prefix".into());
|
|
|
|
output_vector.push(self.options.anon_fields_prefix.clone());
|
|
|
|
}
|
2019-10-31 23:32:45 +08:00
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.emit_ast {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--emit-clang-ast".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.emit_ir {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--emit-ir".into());
|
|
|
|
}
|
|
|
|
if let Some(ref graph) = self.options.emit_ir_graphviz {
|
|
|
|
output_vector.push("--emit-ir-graphviz".into());
|
|
|
|
output_vector.push(graph.clone())
|
|
|
|
}
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.enable_cxx_namespaces {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--enable-cxx-namespaces".into());
|
|
|
|
}
|
2018-12-14 12:24:14 +01:00
|
|
|
if self.options.enable_function_attribute_detection {
|
|
|
|
output_vector.push("--enable-function-attribute-detection".into());
|
|
|
|
}
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.disable_name_namespacing {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--disable-name-namespacing".into());
|
|
|
|
}
|
2019-09-17 21:44:34 +03:00
|
|
|
if self.options.disable_nested_struct_naming {
|
|
|
|
output_vector.push("--disable-nested-struct-naming".into());
|
|
|
|
}
|
2017-04-13 08:15:11 +05:45
|
|
|
|
2020-06-22 18:03:48 -07:00
|
|
|
if self.options.disable_header_comment {
|
|
|
|
output_vector.push("--disable-header-comment".into());
|
|
|
|
}
|
|
|
|
|
2018-08-14 22:09:52 +02:00
|
|
|
if !self.options.codegen_config.functions() {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--ignore-functions".into());
|
|
|
|
}
|
|
|
|
|
|
|
|
output_vector.push("--generate".into());
|
|
|
|
|
|
|
|
//Temporary placeholder for below 4 options
|
2017-08-04 17:15:41 +02:00
|
|
|
let mut options: Vec<String> = Vec::new();
|
2018-08-14 22:09:52 +02:00
|
|
|
if self.options.codegen_config.functions() {
|
2018-11-08 14:29:35 +00:00
|
|
|
options.push("functions".into());
|
2017-04-13 08:15:11 +05:45
|
|
|
}
|
2018-08-14 22:09:52 +02:00
|
|
|
if self.options.codegen_config.types() {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("types".into());
|
|
|
|
}
|
2018-08-14 22:09:52 +02:00
|
|
|
if self.options.codegen_config.vars() {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("vars".into());
|
|
|
|
}
|
2018-08-14 22:09:52 +02:00
|
|
|
if self.options.codegen_config.methods() {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("methods".into());
|
|
|
|
}
|
2018-08-14 22:09:52 +02:00
|
|
|
if self.options.codegen_config.constructors() {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("constructors".into());
|
|
|
|
}
|
2018-08-14 22:09:52 +02:00
|
|
|
if self.options.codegen_config.destructors() {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("destructors".into());
|
|
|
|
}
|
2017-04-14 14:37:09 -07:00
|
|
|
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push(options.join(","));
|
|
|
|
|
2018-08-14 22:09:52 +02:00
|
|
|
if !self.options.codegen_config.methods() {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--ignore-methods".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.convert_floats {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-convert-floats".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.prepend_enum_name {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-prepend-enum-name".into());
|
|
|
|
}
|
|
|
|
|
2020-12-15 17:18:16 +01:00
|
|
|
if self.options.fit_macro_constants {
|
|
|
|
output_vector.push("--fit-macro-constant-types".into());
|
|
|
|
}
|
|
|
|
|
2019-05-20 15:56:03 +03:00
|
|
|
if self.options.array_pointers_in_arguments {
|
|
|
|
output_vector.push("--use-array-pointers-in-arguments".into());
|
|
|
|
}
|
|
|
|
|
2019-12-10 16:12:16 +01:00
|
|
|
if let Some(ref wasm_import_module_name) =
|
|
|
|
self.options.wasm_import_module_name
|
|
|
|
{
|
|
|
|
output_vector.push("--wasm-import-module-name".into());
|
|
|
|
output_vector.push(wasm_import_module_name.clone());
|
|
|
|
}
|
|
|
|
|
2020-06-29 03:19:18 +02:00
|
|
|
for line in &self.options.raw_lines {
|
|
|
|
output_vector.push("--raw-line".into());
|
2020-06-29 15:36:48 +02:00
|
|
|
output_vector.push(line.clone());
|
2020-06-29 03:19:18 +02:00
|
|
|
}
|
2017-04-13 08:15:11 +05:45
|
|
|
|
2020-12-01 20:59:36 +01:00
|
|
|
for (module, lines) in &self.options.module_lines {
|
|
|
|
for line in lines.iter() {
|
|
|
|
output_vector.push("--module-raw-line".into());
|
|
|
|
output_vector.push(module.clone());
|
|
|
|
output_vector.push(line.clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.use_core {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--use-core".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.conservative_inline_namespaces {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--conservative-inline-namespaces".into());
|
|
|
|
}
|
|
|
|
|
2020-06-29 04:07:30 +02:00
|
|
|
if self.options.generate_inline_functions {
|
|
|
|
output_vector.push("--generate-inline-functions".into());
|
|
|
|
}
|
|
|
|
|
2018-12-23 18:52:08 +01:00
|
|
|
if !self.options.record_matches {
|
|
|
|
output_vector.push("--no-record-matches".into());
|
|
|
|
}
|
|
|
|
|
Map size_t to usize by default and check compatibility (fixes #1901, #1903)
This addresses the underlying issue identified in #1671, that size_t
(integer that can hold any object size) isn't guaranteed to match usize,
which is defined more like uintptr_t (integer that can hold any
pointer). However, on almost all platforms, this is true, and in fact
Rust already uses usize extensively in contexts where size_t would be
more appropriate, such as slice indexing. So, it's better for ergonomics
when interfacing with C code to map the C size_t type to usize. (See
also discussion in rust-lang/rust#65473 about how usize really should be
defined as size_t, not uintptr_t.)
The previous fix for #1671 removed the special case for size_t and
defaulted to binding it as a normal typedef. This change effectively
reverts that and goes back to mapping size_t to usize (and ssize_t to
isize), but also ensures that if size_t is emitted, the typedef'd type
of size_t in fact is compatible with usize (defined by checking that the
size and alignment match the target pointer width). For (hypothetical)
platforms where this is not true, or for compatibility with the default
behavior of bindgen between 0.53 and this commit, onwards, you can
disable this mapping with --no-size_t-is-usize.
2021-06-03 10:47:26 -04:00
|
|
|
if !self.options.size_t_is_usize {
|
|
|
|
output_vector.push("--no-size_t-is-usize".into());
|
2020-02-03 12:03:15 +01:00
|
|
|
}
|
|
|
|
|
2017-08-11 22:38:33 +02:00
|
|
|
if !self.options.rustfmt_bindings {
|
2017-09-22 15:58:23 -04:00
|
|
|
output_vector.push("--no-rustfmt-bindings".into());
|
2017-08-11 17:59:32 +02:00
|
|
|
}
|
|
|
|
|
2019-09-17 09:44:06 +09:00
|
|
|
if let Some(path) = self
|
|
|
|
.options
|
2017-08-11 22:38:33 +02:00
|
|
|
.rustfmt_configuration_file
|
|
|
|
.as_ref()
|
|
|
|
.and_then(|f| f.to_str())
|
|
|
|
{
|
|
|
|
output_vector.push("--rustfmt-configuration-file".into());
|
2017-08-11 17:59:32 +02:00
|
|
|
output_vector.push(path.into());
|
|
|
|
}
|
|
|
|
|
2020-11-26 13:39:06 +01:00
|
|
|
if let Some(ref name) = self.options.dynamic_library_name {
|
2020-07-27 10:26:38 +01:00
|
|
|
output_vector.push("--dynamic-loading".into());
|
2020-11-26 13:39:06 +01:00
|
|
|
output_vector.push(name.clone());
|
2020-07-27 10:26:38 +01:00
|
|
|
}
|
|
|
|
|
2021-03-26 17:12:23 -05:00
|
|
|
if self.options.dynamic_link_require_all {
|
|
|
|
output_vector.push("--dynamic-link-require-all".into());
|
|
|
|
}
|
|
|
|
|
2021-01-13 10:04:50 -08:00
|
|
|
if self.options.respect_cxx_access_specs {
|
|
|
|
output_vector.push("--respect-cxx-access-specs".into());
|
|
|
|
}
|
|
|
|
|
2021-03-10 13:25:53 +01:00
|
|
|
if self.options.translate_enum_integer_types {
|
|
|
|
output_vector.push("--translate-enum-integer-types".into());
|
|
|
|
}
|
|
|
|
|
2021-04-30 02:16:49 +02:00
|
|
|
if self.options.c_naming {
|
|
|
|
output_vector.push("--c-naming".into());
|
|
|
|
}
|
|
|
|
|
2021-07-16 12:22:02 -07:00
|
|
|
if self.options.force_explicit_padding {
|
|
|
|
output_vector.push("--explicit-padding".into());
|
|
|
|
}
|
|
|
|
|
2022-02-18 19:45:20 +01:00
|
|
|
if self.options.vtable_generation {
|
|
|
|
output_vector.push("--vtable-generation".into());
|
|
|
|
}
|
|
|
|
|
2022-08-24 18:45:03 -04:00
|
|
|
if self.options.sort_semantically {
|
|
|
|
output_vector.push("--sort-semantically".into());
|
|
|
|
}
|
|
|
|
|
2022-09-23 02:04:28 -05:00
|
|
|
if self.options.merge_extern_blocks {
|
|
|
|
output_vector.push("--merge-extern-blocks".into());
|
|
|
|
}
|
|
|
|
|
2022-11-22 11:41:32 -05:00
|
|
|
if self.options.wrap_unsafe_ops {
|
|
|
|
output_vector.push("--wrap-unsafe-ops".into());
|
|
|
|
}
|
|
|
|
|
2023-01-20 15:12:42 -05:00
|
|
|
#[cfg(feature = "cli")]
|
|
|
|
for callbacks in &self.options.parse_callbacks {
|
|
|
|
output_vector.extend(callbacks.cli_args());
|
|
|
|
}
|
2023-02-07 10:13:48 -05:00
|
|
|
if self.options.wrap_static_fns {
|
|
|
|
output_vector.push("--wrap-static-fns".into())
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(ref path) = self.options.wrap_static_fns_path {
|
|
|
|
output_vector.push("--wrap-static-fns-path".into());
|
|
|
|
output_vector.push(path.display().to_string());
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(ref suffix) = self.options.wrap_static_fns_suffix {
|
|
|
|
output_vector.push("--wrap-static-fns-suffix".into());
|
|
|
|
output_vector.push(suffix.clone());
|
|
|
|
}
|
|
|
|
|
|
|
|
if cfg!(feature = "experimental") {
|
|
|
|
output_vector.push("--experimental".into());
|
|
|
|
}
|
2023-01-20 15:12:42 -05:00
|
|
|
|
2020-06-27 01:41:35 -04:00
|
|
|
// Add clang arguments
|
|
|
|
|
|
|
|
output_vector.push("--".into());
|
|
|
|
|
|
|
|
if !self.options.clang_args.is_empty() {
|
|
|
|
output_vector.extend(self.options.clang_args.iter().cloned());
|
|
|
|
}
|
|
|
|
|
2022-10-03 13:57:04 -05:00
|
|
|
// To pass more than one header, we need to pass all but the last
|
|
|
|
// header via the `-include` clang arg
|
|
|
|
for header in &self.options.input_headers
|
|
|
|
[..self.options.input_headers.len().saturating_sub(1)]
|
|
|
|
{
|
|
|
|
output_vector.push("-include".to_string());
|
|
|
|
output_vector.push(header.clone());
|
2020-06-27 01:41:35 -04:00
|
|
|
}
|
|
|
|
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector
|
|
|
|
}
|
|
|
|
|
2017-05-01 13:37:42 -07:00
|
|
|
/// Add an input C/C++ header to generate bindings for.
|
|
|
|
///
|
|
|
|
/// This can be used to generate bindings to a single header:
|
|
|
|
///
|
|
|
|
/// ```ignore
|
|
|
|
/// let bindings = bindgen::Builder::default()
|
|
|
|
/// .header("input.h")
|
2021-12-08 09:10:05 +09:00
|
|
|
/// .generate()
|
2017-05-01 13:37:42 -07:00
|
|
|
/// .unwrap();
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Or you can invoke it multiple times to generate bindings to multiple
|
|
|
|
/// headers:
|
|
|
|
///
|
|
|
|
/// ```ignore
|
|
|
|
/// let bindings = bindgen::Builder::default()
|
|
|
|
/// .header("first.h")
|
|
|
|
/// .header("second.h")
|
|
|
|
/// .header("third.h")
|
2021-12-08 09:10:05 +09:00
|
|
|
/// .generate()
|
2017-05-01 13:37:42 -07:00
|
|
|
/// .unwrap();
|
|
|
|
/// ```
|
2016-10-31 16:29:02 -07:00
|
|
|
pub fn header<T: Into<String>>(mut self, header: T) -> Builder {
|
2022-10-03 13:57:04 -05:00
|
|
|
self.options.input_headers.push(header.into());
|
2016-12-11 09:46:49 +01:00
|
|
|
self
|
2015-06-07 18:25:33 -04:00
|
|
|
}
|
|
|
|
|
2021-04-08 17:26:55 +00:00
|
|
|
/// Add a depfile output which will be written alongside the generated bindings.
|
|
|
|
pub fn depfile<H: Into<String>, D: Into<PathBuf>>(
|
|
|
|
mut self,
|
|
|
|
output_module: H,
|
|
|
|
depfile: D,
|
|
|
|
) -> Builder {
|
|
|
|
self.options.depfile = Some(deps::DepfileSpec {
|
|
|
|
output_module: output_module.into(),
|
|
|
|
depfile_path: depfile.into(),
|
|
|
|
});
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-03-27 13:02:33 -04:00
|
|
|
/// Add `contents` as an input C/C++ header named `name`.
|
|
|
|
///
|
|
|
|
/// The file `name` will be added to the clang arguments.
|
|
|
|
pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
|
2020-08-01 19:26:16 +03:00
|
|
|
// Apparently clang relies on having virtual FS correspondent to
|
|
|
|
// the real one, so we need absolute paths here
|
|
|
|
let absolute_path = env::current_dir()
|
|
|
|
.expect("Cannot retrieve current directory")
|
|
|
|
.join(name)
|
|
|
|
.to_str()
|
|
|
|
.expect("Cannot convert current directory name to string")
|
|
|
|
.to_owned();
|
2022-10-03 13:57:04 -05:00
|
|
|
self.options
|
|
|
|
.input_header_contents
|
2020-08-01 19:26:16 +03:00
|
|
|
.push((absolute_path, contents.into()));
|
2017-03-27 13:02:33 -04:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-08-13 13:12:21 -07:00
|
|
|
/// Specify the rust target
|
|
|
|
///
|
|
|
|
/// The default is the latest stable Rust version
|
|
|
|
pub fn rust_target(mut self, rust_target: RustTarget) -> Self {
|
2022-11-22 12:31:14 -05:00
|
|
|
#[allow(deprecated)]
|
|
|
|
if rust_target <= RustTarget::Stable_1_30 {
|
|
|
|
warn!(
|
|
|
|
"The {} rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues",
|
|
|
|
String::from(rust_target)
|
|
|
|
);
|
|
|
|
}
|
2017-08-13 13:12:21 -07:00
|
|
|
self.options.set_rust_target(rust_target);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-03-10 07:15:10 +01:00
|
|
|
/// Disable support for native Rust unions, if supported.
|
|
|
|
pub fn disable_untagged_union(mut self) -> Self {
|
|
|
|
self.options.rust_features.untagged_union = false;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-06-22 18:03:48 -07:00
|
|
|
/// Disable insertion of bindgen's version identifier into generated
|
|
|
|
/// bindings.
|
|
|
|
pub fn disable_header_comment(mut self) -> Self {
|
|
|
|
self.options.disable_header_comment = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-02-13 22:35:28 +03:00
|
|
|
/// Set the output graphviz file.
|
|
|
|
pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
|
|
|
|
let path = path.into();
|
|
|
|
self.options.emit_ir_graphviz = Some(path);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-04-22 19:02:22 +02:00
|
|
|
/// Whether the generated bindings should contain documentation comments
|
2021-03-09 11:58:32 +00:00
|
|
|
/// (docstrings) or not. This is set to true by default.
|
2020-04-22 19:02:22 +02:00
|
|
|
///
|
|
|
|
/// Note that clang by default excludes comments from system headers, pass
|
|
|
|
/// `-fretain-comments-from-system-headers` as
|
|
|
|
/// [`clang_arg`][Builder::clang_arg] to include them. It can also be told
|
|
|
|
/// to process all comments (not just documentation ones) using the
|
|
|
|
/// `-fparse-all-comments` flag. See [slides on clang comment parsing](
|
|
|
|
/// https://llvm.org/devmtg/2012-11/Gribenko_CommentParsing.pdf) for
|
|
|
|
/// background and examples.
|
2017-01-26 17:09:28 +01:00
|
|
|
pub fn generate_comments(mut self, doit: bool) -> Self {
|
|
|
|
self.options.generate_comments = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2021-02-11 08:58:46 +01:00
|
|
|
/// Whether to allowlist recursively or not. Defaults to true.
|
2017-01-26 17:26:02 +01:00
|
|
|
///
|
2021-02-11 08:58:46 +01:00
|
|
|
/// Given that we have explicitly allowlisted the "initiate_dance_party"
|
2017-09-07 10:34:14 -07:00
|
|
|
/// function in this C header:
|
|
|
|
///
|
|
|
|
/// ```c
|
|
|
|
/// typedef struct MoonBoots {
|
|
|
|
/// int bouncy_level;
|
|
|
|
/// } MoonBoots;
|
|
|
|
///
|
|
|
|
/// void initiate_dance_party(MoonBoots* boots);
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// We would normally generate bindings to both the `initiate_dance_party`
|
|
|
|
/// function and the `MoonBoots` struct that it transitively references. By
|
2021-02-11 08:58:46 +01:00
|
|
|
/// configuring with `allowlist_recursively(false)`, `bindgen` will not emit
|
|
|
|
/// bindings for anything except the explicitly allowlisted items, and there
|
2017-09-07 10:34:14 -07:00
|
|
|
/// would be no emitted struct definition for `MoonBoots`. However, the
|
|
|
|
/// `initiate_dance_party` function would still reference `MoonBoots`!
|
|
|
|
///
|
|
|
|
/// **Disabling this feature will almost certainly cause `bindgen` to emit
|
|
|
|
/// bindings that will not compile!** If you disable this feature, then it
|
2018-06-13 11:08:17 +07:00
|
|
|
/// is *your* responsibility to provide definitions for every type that is
|
2021-02-11 08:58:46 +01:00
|
|
|
/// referenced from an explicitly allowlisted item. One way to provide the
|
2017-09-07 10:34:14 -07:00
|
|
|
/// definitions is by using the [`Builder::raw_line`](#method.raw_line)
|
|
|
|
/// method, another would be to define them in Rust and then `include!(...)`
|
|
|
|
/// the bindings immediately afterwards.
|
2021-02-11 08:58:46 +01:00
|
|
|
pub fn allowlist_recursively(mut self, doit: bool) -> Self {
|
|
|
|
self.options.allowlist_recursively = doit;
|
2017-01-26 17:26:02 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Generate `#[macro_use] extern crate objc;` instead of `use objc;`
|
2017-01-29 01:10:38 +02:00
|
|
|
/// in the prologue of the files generated from objective-c files
|
|
|
|
pub fn objc_extern_crate(mut self, doit: bool) -> Self {
|
|
|
|
self.options.objc_extern_crate = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-10-04 16:14:27 +02:00
|
|
|
/// Generate proper block signatures instead of void pointers.
|
|
|
|
pub fn generate_block(mut self, doit: bool) -> Self {
|
|
|
|
self.options.generate_block = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-09-01 00:55:43 +08:00
|
|
|
/// Generate `#[macro_use] extern crate block;` instead of `use block;`
|
|
|
|
/// in the prologue of the files generated from apple block files
|
|
|
|
pub fn block_extern_crate(mut self, doit: bool) -> Self {
|
|
|
|
self.options.block_extern_crate = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Whether to use the clang-provided name mangling. This is true by default
|
|
|
|
/// and probably needed for C++ features.
|
2017-02-18 19:30:00 +01:00
|
|
|
///
|
|
|
|
/// However, some old libclang versions seem to return incorrect results in
|
|
|
|
/// some cases for non-mangled functions, see [1], so we allow disabling it.
|
|
|
|
///
|
2019-05-20 17:14:30 -07:00
|
|
|
/// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
|
2017-02-18 19:30:00 +01:00
|
|
|
pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
|
|
|
|
self.options.enable_mangling = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Hide the given type from the generated bindings. Regular expressions are
|
|
|
|
/// supported.
|
|
|
|
///
|
|
|
|
/// To blocklist types prefixed with "mylib" use `"mylib_.*"`.
|
|
|
|
pub fn blocklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.blocklisted_types.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2016-03-20 18:30:54 +01:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Hide the given function from the generated bindings. Regular expressions
|
|
|
|
/// are supported.
|
|
|
|
///
|
|
|
|
/// Methods can be blocklisted by prefixing the name of the type implementing
|
|
|
|
/// them followed by an underscore. So if `Foo` has a method `bar`, it can
|
|
|
|
/// be blocklisted as `Foo_bar`.
|
|
|
|
///
|
|
|
|
/// To blocklist functions prefixed with "mylib" use `"mylib_.*"`.
|
|
|
|
pub fn blocklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.blocklisted_functions.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2021-02-11 08:58:46 +01:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Hide the given item from the generated bindings, regardless of
|
|
|
|
/// whether it's a type, function, module, etc. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
///
|
|
|
|
/// To blocklist items prefixed with "mylib" use `"mylib_.*"`.
|
|
|
|
pub fn blocklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.blocklisted_items.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2018-10-12 17:31:36 -04:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Hide any contents of the given file from the generated bindings,
|
|
|
|
/// regardless of whether it's a type, function, module etc.
|
|
|
|
pub fn blocklist_file<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.blocklisted_files.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2021-11-26 01:42:47 +00:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Treat the given type as opaque in the generated bindings. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
///
|
|
|
|
/// To change types prefixed with "mylib" into opaque, use `"mylib_.*"`.
|
|
|
|
pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.opaque_types.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Allowlist the given type so that it (and all types that it transitively
|
|
|
|
/// refers to) appears in the generated bindings. Regular expressions are
|
|
|
|
/// supported.
|
|
|
|
///
|
|
|
|
/// To allowlist types prefixed with "mylib" use `"mylib_.*"`.
|
|
|
|
pub fn allowlist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.allowlisted_types.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2016-03-23 22:45:09 +01:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Allowlist the given function so that it (and all types that it
|
|
|
|
/// transitively refers to) appears in the generated bindings. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
///
|
|
|
|
/// Methods can be allowlisted by prefixing the name of the type
|
|
|
|
/// implementing them followed by an underscore. So if `Foo` has a method
|
|
|
|
/// `bar`, it can be allowlisted as `Foo_bar`.
|
|
|
|
///
|
|
|
|
/// To allowlist functions prefixed with "mylib" use `"mylib_.*"`.
|
|
|
|
pub fn allowlist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.allowlisted_functions.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2016-10-08 00:20:11 +11:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Allowlist the given variable so that it (and all types that it
|
|
|
|
/// transitively refers to) appears in the generated bindings. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
///
|
|
|
|
/// To allowlist variables prefixed with "mylib" use `"mylib_.*"`.
|
|
|
|
pub fn allowlist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.allowlisted_vars.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2016-10-08 00:58:33 +11:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Allowlist the given file so that its contents appear in the generated bindings.
|
|
|
|
pub fn allowlist_file<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.allowlisted_files.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2021-11-29 13:03:26 +00:00
|
|
|
}
|
|
|
|
|
2018-06-04 05:35:17 -07:00
|
|
|
/// Set the default style of code to generate for enums
|
2019-09-17 09:44:06 +09:00
|
|
|
pub fn default_enum_style(
|
|
|
|
mut self,
|
|
|
|
arg: codegen::EnumVariation,
|
|
|
|
) -> Builder {
|
2018-06-04 05:35:17 -07:00
|
|
|
self.options.default_enum_style = arg;
|
2018-06-03 11:35:07 -07:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as being
|
|
|
|
/// bitfield-like. Regular expressions are supported.
|
|
|
|
///
|
|
|
|
/// This makes bindgen generate a type that isn't a rust `enum`. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
///
|
|
|
|
/// This is similar to the newtype enum style, but with the bitwise
|
|
|
|
/// operators implemented.
|
|
|
|
pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.bitfield_enums.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as a newtype.
|
|
|
|
/// Regular expressions are supported.
|
|
|
|
///
|
|
|
|
/// This makes bindgen generate a type that isn't a Rust `enum`. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
pub fn newtype_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.newtype_enums.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as a newtype
|
|
|
|
/// whose variants are exposed as global constants.
|
|
|
|
///
|
|
|
|
/// Regular expressions are supported.
|
|
|
|
///
|
|
|
|
/// This makes bindgen generate a type that isn't a Rust `enum`. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
pub fn newtype_global_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.newtype_global_enums.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as a Rust
|
|
|
|
/// enum.
|
|
|
|
///
|
|
|
|
/// This makes bindgen generate enums instead of constants. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
///
|
|
|
|
/// **Use this with caution**, creating this in unsafe code
|
|
|
|
/// (including FFI) with an invalid value will invoke undefined behaviour.
|
|
|
|
/// You may want to use the newtype enum style instead.
|
|
|
|
pub fn rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.rustified_enums.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as a Rust
|
|
|
|
/// enum with the `#[non_exhaustive]` attribute.
|
|
|
|
///
|
|
|
|
/// This makes bindgen generate enums instead of constants. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
///
|
|
|
|
/// **Use this with caution**, creating this in unsafe code
|
|
|
|
/// (including FFI) with an invalid value will invoke undefined behaviour.
|
|
|
|
/// You may want to use the newtype enum style instead.
|
|
|
|
pub fn rustified_non_exhaustive_enum<T: AsRef<str>>(
|
|
|
|
mut self,
|
|
|
|
arg: T,
|
|
|
|
) -> Builder {
|
|
|
|
self.options.rustified_non_exhaustive_enums.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as a set of
|
|
|
|
/// constants that are not to be put into a module.
|
|
|
|
pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.constified_enums.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as a set of
|
|
|
|
/// constants that should be put into a module.
|
|
|
|
///
|
|
|
|
/// This makes bindgen generate modules containing constants instead of
|
|
|
|
/// just constants. Regular expressions are supported.
|
|
|
|
pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.constified_enum_modules.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2017-06-11 13:26:13 -07:00
|
|
|
}
|
|
|
|
|
2020-08-08 16:20:47 -07:00
|
|
|
/// Set the default type for macro constants
|
|
|
|
pub fn default_macro_constant_type(
|
|
|
|
mut self,
|
|
|
|
arg: codegen::MacroTypeVariation,
|
|
|
|
) -> Builder {
|
|
|
|
self.options.default_macro_constant_type = arg;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-10-26 17:57:13 +08:00
|
|
|
/// Set the default style of code to generate for typedefs
|
|
|
|
pub fn default_alias_style(
|
|
|
|
mut self,
|
|
|
|
arg: codegen::AliasVariation,
|
|
|
|
) -> Builder {
|
|
|
|
self.options.default_alias_style = arg;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given typedef alias (or set of aliases, if using a pattern) to
|
|
|
|
/// use regular Rust type aliasing.
|
|
|
|
///
|
|
|
|
/// This is the default behavior and should be used if `default_alias_style`
|
|
|
|
/// was set to NewType or NewTypeDeref and you want to override it for a
|
|
|
|
/// set of typedefs.
|
|
|
|
pub fn type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.type_alias.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2019-10-26 17:57:13 +08:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given typedef alias (or set of aliases, if using a pattern) to
|
|
|
|
/// be generated as a new type by having the aliased type be wrapped in a
|
|
|
|
/// #[repr(transparent)] struct.
|
|
|
|
///
|
|
|
|
/// Used to enforce stricter type checking.
|
|
|
|
pub fn new_type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.new_type_alias.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2019-10-26 17:57:13 +08:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given typedef alias (or set of aliases, if using a pattern) to
|
|
|
|
/// be generated as a new type by having the aliased type be wrapped in a
|
|
|
|
/// #[repr(transparent)] struct and also have an automatically generated
|
|
|
|
/// impl's of `Deref` and `DerefMut` to their aliased type.
|
|
|
|
pub fn new_type_alias_deref<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.new_type_alias_deref.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2019-10-26 17:57:13 +08:00
|
|
|
}
|
|
|
|
|
2022-09-23 08:30:49 +02:00
|
|
|
/// Set the default style of code to generate for unions with a non-Copy member.
|
|
|
|
pub fn default_non_copy_union_style(
|
|
|
|
mut self,
|
|
|
|
arg: codegen::NonCopyUnionStyle,
|
|
|
|
) -> Self {
|
|
|
|
self.options.default_non_copy_union_style = arg;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given union (or set of union, if using a pattern) to use
|
|
|
|
/// a bindgen-generated wrapper for its members if at least one is non-Copy.
|
|
|
|
pub fn bindgen_wrapper_union<T: AsRef<str>>(mut self, arg: T) -> Self {
|
|
|
|
self.options.bindgen_wrapper_union.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2022-09-23 08:30:49 +02:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Mark the given union (or set of union, if using a pattern) to use
|
|
|
|
/// [`::core::mem::ManuallyDrop`] for its members if at least one is non-Copy.
|
|
|
|
///
|
|
|
|
/// Note: `ManuallyDrop` was stabilized in Rust 1.20.0, do not use it if your
|
|
|
|
/// MSRV is lower.
|
|
|
|
pub fn manually_drop_union<T: AsRef<str>>(mut self, arg: T) -> Self {
|
|
|
|
self.options.manually_drop_union.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
2022-09-23 08:30:49 +02:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Add a string to prepend to the generated bindings. The string is passed
|
|
|
|
/// through without any modification.
|
|
|
|
pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Self {
|
|
|
|
self.options.raw_lines.push(arg.into());
|
|
|
|
self
|
|
|
|
}
|
2016-04-03 01:03:06 +02:00
|
|
|
}
|
|
|
|
|
2018-05-03 04:21:08 +02:00
|
|
|
/// Add a given line to the beginning of module `mod`.
|
|
|
|
pub fn module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self
|
|
|
|
where
|
|
|
|
T: Into<String>,
|
|
|
|
U: Into<String>,
|
|
|
|
{
|
|
|
|
self.options
|
|
|
|
.module_lines
|
|
|
|
.entry(mod_.into())
|
|
|
|
.or_insert_with(Vec::new)
|
|
|
|
.push(line.into());
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-05-03 04:46:48 +02:00
|
|
|
/// Add a given set of lines to the beginning of module `mod`.
|
|
|
|
pub fn module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self
|
|
|
|
where
|
|
|
|
T: Into<String>,
|
|
|
|
I: IntoIterator,
|
|
|
|
I::Item: Into<String>,
|
|
|
|
{
|
|
|
|
self.options
|
|
|
|
.module_lines
|
|
|
|
.entry(mod_.into())
|
|
|
|
.or_insert_with(Vec::new)
|
|
|
|
.extend(lines.into_iter().map(Into::into));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Add an argument to be passed straight through to clang.
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
|
2015-06-07 18:25:33 -04:00
|
|
|
self.options.clang_args.push(arg.into());
|
2015-05-06 12:27:56 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-17 18:28:51 +09:00
|
|
|
/// Add arguments to be passed straight through to clang.
|
|
|
|
pub fn clang_args<I>(mut self, iter: I) -> Builder
|
2017-08-04 17:15:41 +02:00
|
|
|
where
|
|
|
|
I: IntoIterator,
|
|
|
|
I::Item: AsRef<str>,
|
|
|
|
{
|
2017-04-17 18:28:51 +09:00
|
|
|
for arg in iter {
|
|
|
|
self = self.clang_arg(arg.as_ref())
|
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Emit bindings for builtin definitions (for example `__builtin_va_list`)
|
|
|
|
/// in the generated Rust.
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn emit_builtins(mut self) -> Builder {
|
2015-05-06 12:27:56 +01:00
|
|
|
self.options.builtins = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Avoid converting floats to `f32`/`f64` by default.
|
2016-11-06 20:52:01 +01:00
|
|
|
pub fn no_convert_floats(mut self) -> Self {
|
|
|
|
self.options.convert_floats = false;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
/// Set whether layout tests should be generated.
|
|
|
|
pub fn layout_tests(mut self, doit: bool) -> Self {
|
|
|
|
self.options.layout_tests = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-09-23 01:48:19 +03:00
|
|
|
/// Set whether `Debug` should be implemented, if it can not be derived automatically.
|
|
|
|
pub fn impl_debug(mut self, doit: bool) -> Self {
|
|
|
|
self.options.impl_debug = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Set whether `PartialEq` should be implemented, if it can not be derived automatically.
|
|
|
|
pub fn impl_partialeq(mut self, doit: bool) -> Self {
|
|
|
|
self.options.impl_partialeq = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-09-06 16:42:53 +01:00
|
|
|
/// Set whether `Copy` should be derived by default.
|
|
|
|
pub fn derive_copy(mut self, doit: bool) -> Self {
|
|
|
|
self.options.derive_copy = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-01-24 09:49:49 +01:00
|
|
|
/// Set whether `Debug` should be derived by default.
|
|
|
|
pub fn derive_debug(mut self, doit: bool) -> Self {
|
|
|
|
self.options.derive_debug = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-02-05 17:12:05 +08:00
|
|
|
/// Set whether `Default` should be derived by default.
|
|
|
|
pub fn derive_default(mut self, doit: bool) -> Self {
|
|
|
|
self.options.derive_default = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-08-02 11:19:14 -07:00
|
|
|
/// Set whether `Hash` should be derived by default.
|
|
|
|
pub fn derive_hash(mut self, doit: bool) -> Self {
|
|
|
|
self.options.derive_hash = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-09-19 17:13:14 +03:00
|
|
|
/// Set whether `PartialOrd` should be derived by default.
|
2017-09-19 22:42:22 +03:00
|
|
|
/// If we don't compute partialord, we also cannot compute
|
|
|
|
/// ord. Set the derive_ord to `false` when doit is `false`.
|
2017-09-19 17:13:14 +03:00
|
|
|
pub fn derive_partialord(mut self, doit: bool) -> Self {
|
2017-09-19 22:42:22 +03:00
|
|
|
self.options.derive_partialord = doit;
|
|
|
|
if !doit {
|
|
|
|
self.options.derive_ord = false;
|
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Set whether `Ord` should be derived by default.
|
2017-10-12 12:02:47 -07:00
|
|
|
/// We can't compute `Ord` without computing `PartialOrd`,
|
2017-09-19 22:42:22 +03:00
|
|
|
/// so we set the same option to derive_partialord.
|
|
|
|
pub fn derive_ord(mut self, doit: bool) -> Self {
|
|
|
|
self.options.derive_ord = doit;
|
2017-09-19 17:13:14 +03:00
|
|
|
self.options.derive_partialord = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-08-10 16:22:48 -07:00
|
|
|
/// Set whether `PartialEq` should be derived by default.
|
2017-09-19 13:53:11 -07:00
|
|
|
///
|
|
|
|
/// If we don't derive `PartialEq`, we also cannot derive `Eq`, so deriving
|
|
|
|
/// `Eq` is also disabled when `doit` is `false`.
|
2017-08-10 16:22:48 -07:00
|
|
|
pub fn derive_partialeq(mut self, doit: bool) -> Self {
|
2017-08-16 19:34:51 -05:00
|
|
|
self.options.derive_partialeq = doit;
|
|
|
|
if !doit {
|
|
|
|
self.options.derive_eq = false;
|
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Set whether `Eq` should be derived by default.
|
2017-09-19 13:53:11 -07:00
|
|
|
///
|
|
|
|
/// We can't derive `Eq` without also deriving `PartialEq`, so we also
|
|
|
|
/// enable deriving `PartialEq` when `doit` is `true`.
|
2017-08-16 19:34:51 -05:00
|
|
|
pub fn derive_eq(mut self, doit: bool) -> Self {
|
|
|
|
self.options.derive_eq = doit;
|
2017-09-19 13:53:11 -07:00
|
|
|
if doit {
|
|
|
|
self.options.derive_partialeq = doit;
|
|
|
|
}
|
2017-08-10 16:22:48 -07:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-09-19 13:53:11 -07:00
|
|
|
/// Set whether or not to time bindgen phases, and print information to
|
|
|
|
/// stderr.
|
2017-08-29 22:08:37 -05:00
|
|
|
pub fn time_phases(mut self, doit: bool) -> Self {
|
|
|
|
self.options.time_phases = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-08 19:55:49 +11:00
|
|
|
/// Emit Clang AST.
|
|
|
|
pub fn emit_clang_ast(mut self) -> Builder {
|
|
|
|
self.options.emit_ast = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-15 10:26:26 -08:00
|
|
|
/// Emit IR.
|
|
|
|
pub fn emit_ir(mut self) -> Builder {
|
|
|
|
self.options.emit_ir = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-08 19:55:49 +11:00
|
|
|
/// Enable C++ namespaces.
|
|
|
|
pub fn enable_cxx_namespaces(mut self) -> Builder {
|
|
|
|
self.options.enable_cxx_namespaces = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-12-14 12:24:14 +01:00
|
|
|
/// Enable detecting must_use attributes on C functions.
|
|
|
|
///
|
|
|
|
/// This is quite slow in some cases (see #1465), so it's disabled by
|
|
|
|
/// default.
|
|
|
|
///
|
|
|
|
/// Note that for this to do something meaningful for now at least, the rust
|
|
|
|
/// target version has to have support for `#[must_use]`.
|
|
|
|
pub fn enable_function_attribute_detection(mut self) -> Self {
|
|
|
|
self.options.enable_function_attribute_detection = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Disable name auto-namespacing.
|
2016-11-24 21:06:42 +01:00
|
|
|
///
|
2017-04-24 01:08:19 -07:00
|
|
|
/// By default, bindgen mangles names like `foo::bar::Baz` to look like
|
|
|
|
/// `foo_bar_Baz` instead of just `Baz`.
|
2016-11-24 21:06:42 +01:00
|
|
|
///
|
2017-04-24 01:08:19 -07:00
|
|
|
/// This method disables that behavior.
|
2016-11-24 21:06:42 +01:00
|
|
|
///
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Note that this intentionally does not change the names used for
|
2021-02-11 08:58:46 +01:00
|
|
|
/// allowlisting and blocklisting, which should still be mangled with the
|
2016-11-24 21:06:42 +01:00
|
|
|
/// namespaces.
|
2016-11-29 20:37:22 +01:00
|
|
|
///
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Note, also, that this option may cause bindgen to generate duplicate
|
|
|
|
/// names.
|
2016-11-24 21:06:42 +01:00
|
|
|
pub fn disable_name_namespacing(mut self) -> Builder {
|
|
|
|
self.options.disable_name_namespacing = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-09-17 21:44:34 +03:00
|
|
|
/// Disable nested struct naming.
|
|
|
|
///
|
|
|
|
/// The following structs have different names for C and C++. In case of C
|
|
|
|
/// they are visible as `foo` and `bar`. In case of C++ they are visible as
|
|
|
|
/// `foo` and `foo::bar`.
|
|
|
|
///
|
|
|
|
/// ```c
|
|
|
|
/// struct foo {
|
|
|
|
/// struct bar {
|
|
|
|
/// } b;
|
|
|
|
/// };
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Bindgen wants to avoid duplicate names by default so it follows C++ naming
|
|
|
|
/// and it generates `foo`/`foo_bar` instead of just `foo`/`bar`.
|
|
|
|
///
|
|
|
|
/// This method disables this behavior and it is indented to be used only
|
|
|
|
/// for headers that were written for C.
|
|
|
|
pub fn disable_nested_struct_naming(mut self) -> Builder {
|
|
|
|
self.options.disable_nested_struct_naming = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-01-07 02:30:51 +01:00
|
|
|
/// Treat inline namespaces conservatively.
|
|
|
|
///
|
|
|
|
/// This is tricky, because in C++ is technically legal to override an item
|
|
|
|
/// defined in an inline namespace:
|
|
|
|
///
|
|
|
|
/// ```cpp
|
|
|
|
/// inline namespace foo {
|
|
|
|
/// using Bar = int;
|
|
|
|
/// }
|
|
|
|
/// using Bar = long;
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Even though referencing `Bar` is a compiler error.
|
|
|
|
///
|
|
|
|
/// We want to support this (arguably esoteric) use case, but we don't want
|
|
|
|
/// to make the rest of bindgen users pay an usability penalty for that.
|
|
|
|
///
|
|
|
|
/// To support this, we need to keep all the inline namespaces around, but
|
|
|
|
/// then bindgen usage is a bit more difficult, because you cannot
|
|
|
|
/// reference, e.g., `std::string` (you'd need to use the proper inline
|
|
|
|
/// namespace).
|
|
|
|
///
|
|
|
|
/// We could complicate a lot of the logic to detect name collisions, and if
|
|
|
|
/// not detected generate a `pub use inline_ns::*` or something like that.
|
|
|
|
///
|
|
|
|
/// That's probably something we can do if we see this option is needed in a
|
|
|
|
/// lot of cases, to improve it's usability, but my guess is that this is
|
|
|
|
/// not going to be too useful.
|
|
|
|
pub fn conservative_inline_namespaces(mut self) -> Builder {
|
|
|
|
self.options.conservative_inline_namespaces = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-03-20 14:37:41 +01:00
|
|
|
/// Whether inline functions should be generated or not.
|
|
|
|
///
|
|
|
|
/// Note that they will usually not work. However you can use
|
|
|
|
/// `-fkeep-inline-functions` or `-fno-inline-functions` if you are
|
|
|
|
/// responsible of compiling the library to make them callable.
|
|
|
|
pub fn generate_inline_functions(mut self, doit: bool) -> Self {
|
|
|
|
self.options.generate_inline_functions = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-08 19:55:49 +11:00
|
|
|
/// Ignore functions.
|
|
|
|
pub fn ignore_functions(mut self) -> Builder {
|
2018-08-10 19:16:38 -04:00
|
|
|
self.options.codegen_config.remove(CodegenConfig::FUNCTIONS);
|
2016-11-08 19:55:49 +11:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Ignore methods.
|
|
|
|
pub fn ignore_methods(mut self) -> Builder {
|
2018-08-10 19:16:38 -04:00
|
|
|
self.options.codegen_config.remove(CodegenConfig::METHODS);
|
2016-11-08 19:55:49 +11:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-06 12:02:44 +01:00
|
|
|
/// Use core instead of libstd in the generated bindings.
|
|
|
|
pub fn use_core(mut self) -> Builder {
|
|
|
|
self.options.use_core = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Use the given prefix for the raw types instead of `::std::os::raw`.
|
|
|
|
pub fn ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
|
|
|
|
self.options.ctypes_prefix = Some(prefix.into());
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-08-02 14:49:48 -07:00
|
|
|
/// Use the given prefix for the anon fields.
|
2019-10-31 23:32:45 +08:00
|
|
|
pub fn anon_fields_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
|
2020-08-02 14:49:48 -07:00
|
|
|
self.options.anon_fields_prefix = prefix.into();
|
2019-10-31 23:32:45 +08:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Allows configuring types in different situations, see the
|
|
|
|
/// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation.
|
2017-08-04 17:15:41 +02:00
|
|
|
pub fn parse_callbacks(
|
|
|
|
mut self,
|
2019-07-27 13:56:01 +02:00
|
|
|
cb: Box<dyn callbacks::ParseCallbacks>,
|
2017-08-04 17:15:41 +02:00
|
|
|
) -> Self {
|
2022-11-02 13:46:22 -05:00
|
|
|
self.options.parse_callbacks.push(Rc::from(cb));
|
2016-11-06 20:32:37 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Choose what to generate using a
|
|
|
|
/// [`CodegenConfig`](./struct.CodegenConfig.html).
|
2016-12-04 15:15:56 +01:00
|
|
|
pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self {
|
|
|
|
self.options.codegen_config = config;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-03-26 13:24:00 +01:00
|
|
|
/// Whether to detect include paths using clang_sys.
|
|
|
|
pub fn detect_include_paths(mut self, doit: bool) -> Self {
|
|
|
|
self.options.detect_include_paths = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-12-15 17:18:16 +01:00
|
|
|
/// Whether to try to fit macro constants to types smaller than u32/i32
|
|
|
|
pub fn fit_macro_constants(mut self, doit: bool) -> Self {
|
|
|
|
self.options.fit_macro_constants = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2019-11-14 22:55:05 +11:00
|
|
|
/// Prepend the enum name to constant or newtype variants.
|
2017-02-27 18:17:28 +01:00
|
|
|
pub fn prepend_enum_name(mut self, doit: bool) -> Self {
|
|
|
|
self.options.prepend_enum_name = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2020-02-03 12:03:15 +01:00
|
|
|
/// Set whether `size_t` should be translated to `usize` automatically.
|
|
|
|
pub fn size_t_is_usize(mut self, is: bool) -> Self {
|
|
|
|
self.options.size_t_is_usize = is;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-08-11 17:59:32 +02:00
|
|
|
/// Set whether rustfmt should format the generated bindings.
|
2017-08-11 22:38:33 +02:00
|
|
|
pub fn rustfmt_bindings(mut self, doit: bool) -> Self {
|
|
|
|
self.options.rustfmt_bindings = doit;
|
2017-08-11 17:59:32 +02:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-12-23 18:52:08 +01:00
|
|
|
/// Set whether we should record matched items in our regex sets.
|
|
|
|
pub fn record_matches(mut self, doit: bool) -> Self {
|
|
|
|
self.options.record_matches = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-08-11 17:59:32 +02:00
|
|
|
/// Set the absolute path to the rustfmt configuration file, if None, the standard rustfmt
|
|
|
|
/// options are used.
|
2017-08-11 22:38:33 +02:00
|
|
|
pub fn rustfmt_configuration_file(mut self, path: Option<PathBuf>) -> Self {
|
|
|
|
self = self.rustfmt_bindings(true);
|
|
|
|
self.options.rustfmt_configuration_file = path;
|
2017-08-11 17:59:32 +02:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2018-01-26 21:09:42 +01:00
|
|
|
/// Sets an explicit path to rustfmt, to be used when rustfmt is enabled.
|
|
|
|
pub fn with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self {
|
|
|
|
self.options.rustfmt_path = Some(path.into());
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2021-07-16 12:22:02 -07:00
|
|
|
/// If true, always emit explicit padding fields.
|
|
|
|
///
|
|
|
|
/// If a struct needs to be serialized in its native format (padding bytes
|
|
|
|
/// and all), for example writing it to a file or sending it on the network,
|
|
|
|
/// then this should be enabled, as anything reading the padding bytes of
|
|
|
|
/// a struct may lead to Undefined Behavior.
|
|
|
|
pub fn explicit_padding(mut self, doit: bool) -> Self {
|
|
|
|
self.options.force_explicit_padding = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2022-02-18 19:45:20 +01:00
|
|
|
/// If true, enables experimental support to generate vtable functions.
|
|
|
|
///
|
|
|
|
/// Should mostly work, though some edge cases are likely to be broken.
|
|
|
|
pub fn vtable_generation(mut self, doit: bool) -> Self {
|
|
|
|
self.options.vtable_generation = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2022-09-23 02:04:28 -05:00
|
|
|
/// If true, enables the sorting of the output in a predefined manner.
|
2022-08-24 18:45:03 -04:00
|
|
|
///
|
|
|
|
/// TODO: Perhaps move the sorting order out into a config
|
|
|
|
pub fn sort_semantically(mut self, doit: bool) -> Self {
|
|
|
|
self.options.sort_semantically = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2022-09-23 02:04:28 -05:00
|
|
|
/// If true, merges extern blocks.
|
|
|
|
pub fn merge_extern_blocks(mut self, doit: bool) -> Self {
|
|
|
|
self.options.merge_extern_blocks = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Generate the Rust bindings using the options built up thus far.
|
2023-02-07 10:13:48 -05:00
|
|
|
pub fn generate(mut self) -> Result<Bindings, BindgenError> {
|
2021-12-04 16:46:39 +09:00
|
|
|
// Add any extra arguments from the environment to the clang command line.
|
2023-02-07 10:13:48 -05:00
|
|
|
self.options.clang_args.extend(get_extra_clang_args());
|
2021-12-04 16:46:39 +09:00
|
|
|
|
|
|
|
// Transform input headers to arguments on the clang command line.
|
2023-02-07 10:13:48 -05:00
|
|
|
self.options.clang_args.extend(
|
|
|
|
self.options.input_headers
|
|
|
|
[..self.options.input_headers.len().saturating_sub(1)]
|
2022-10-03 13:57:04 -05:00
|
|
|
.iter()
|
|
|
|
.flat_map(|header| ["-include".into(), header.to_string()]),
|
2021-12-04 16:46:39 +09:00
|
|
|
);
|
|
|
|
|
2022-10-03 13:57:04 -05:00
|
|
|
let input_unsaved_files =
|
2023-02-07 10:13:48 -05:00
|
|
|
std::mem::take(&mut self.options.input_header_contents)
|
2022-10-03 13:57:04 -05:00
|
|
|
.into_iter()
|
|
|
|
.map(|(name, contents)| clang::UnsavedFile::new(name, contents))
|
|
|
|
.collect::<Vec<_>>();
|
2021-12-04 16:46:39 +09:00
|
|
|
|
2023-02-07 10:13:48 -05:00
|
|
|
Bindings::generate(self.options, input_unsaved_files)
|
2015-05-06 12:27:56 +01:00
|
|
|
}
|
2017-07-13 14:17:53 -07:00
|
|
|
|
|
|
|
/// Preprocess and dump the input header files to disk.
|
|
|
|
///
|
|
|
|
/// This is useful when debugging bindgen, using C-Reduce, or when filing
|
|
|
|
/// issues. The resulting file will be named something like `__bindgen.i` or
|
|
|
|
/// `__bindgen.ii`
|
|
|
|
pub fn dump_preprocessed_input(&self) -> io::Result<()> {
|
2019-09-17 09:44:06 +09:00
|
|
|
let clang =
|
|
|
|
clang_sys::support::Clang::find(None, &[]).ok_or_else(|| {
|
|
|
|
io::Error::new(
|
|
|
|
io::ErrorKind::Other,
|
|
|
|
"Cannot find clang executable",
|
|
|
|
)
|
|
|
|
})?;
|
2017-07-13 14:17:53 -07:00
|
|
|
|
|
|
|
// The contents of a wrapper file that includes all the input header
|
|
|
|
// files.
|
|
|
|
let mut wrapper_contents = String::new();
|
|
|
|
|
|
|
|
// Whether we are working with C or C++ inputs.
|
2018-07-26 15:08:50 -04:00
|
|
|
let mut is_cpp = args_are_cpp(&self.options.clang_args);
|
2017-07-13 14:17:53 -07:00
|
|
|
|
|
|
|
// For each input header, add `#include "$header"`.
|
2022-10-03 13:57:04 -05:00
|
|
|
for header in &self.options.input_headers {
|
2020-11-26 12:09:15 +01:00
|
|
|
is_cpp |= file_is_cpp(header);
|
2017-07-13 14:17:53 -07:00
|
|
|
|
|
|
|
wrapper_contents.push_str("#include \"");
|
|
|
|
wrapper_contents.push_str(header);
|
|
|
|
wrapper_contents.push_str("\"\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
// For each input header content, add a prefix line of `#line 0 "$name"`
|
|
|
|
// followed by the contents.
|
2022-11-24 10:50:15 -05:00
|
|
|
for (name, contents) in &self.options.input_header_contents {
|
2020-11-26 12:09:15 +01:00
|
|
|
is_cpp |= file_is_cpp(name);
|
2017-07-13 14:17:53 -07:00
|
|
|
|
|
|
|
wrapper_contents.push_str("#line 0 \"");
|
|
|
|
wrapper_contents.push_str(name);
|
|
|
|
wrapper_contents.push_str("\"\n");
|
|
|
|
wrapper_contents.push_str(contents);
|
|
|
|
}
|
|
|
|
|
|
|
|
let wrapper_path = PathBuf::from(if is_cpp {
|
|
|
|
"__bindgen.cpp"
|
|
|
|
} else {
|
|
|
|
"__bindgen.c"
|
|
|
|
});
|
|
|
|
|
|
|
|
{
|
|
|
|
let mut wrapper_file = File::create(&wrapper_path)?;
|
2020-08-08 21:57:41 +08:00
|
|
|
wrapper_file.write_all(wrapper_contents.as_bytes())?;
|
2017-07-13 14:17:53 -07:00
|
|
|
}
|
|
|
|
|
2022-11-02 13:32:32 -05:00
|
|
|
let mut cmd = Command::new(clang.path);
|
2017-07-13 14:17:53 -07:00
|
|
|
cmd.arg("-save-temps")
|
2017-07-17 10:03:55 -07:00
|
|
|
.arg("-E")
|
|
|
|
.arg("-C")
|
2017-07-13 14:17:53 -07:00
|
|
|
.arg("-c")
|
2017-07-17 10:03:55 -07:00
|
|
|
.arg(&wrapper_path)
|
|
|
|
.stdout(Stdio::piped());
|
2017-07-13 14:17:53 -07:00
|
|
|
|
|
|
|
for a in &self.options.clang_args {
|
|
|
|
cmd.arg(a);
|
|
|
|
}
|
|
|
|
|
2021-08-04 23:32:20 +02:00
|
|
|
for a in get_extra_clang_args() {
|
|
|
|
cmd.arg(a);
|
|
|
|
}
|
|
|
|
|
2017-07-17 10:03:55 -07:00
|
|
|
let mut child = cmd.spawn()?;
|
|
|
|
|
|
|
|
let mut preprocessed = child.stdout.take().unwrap();
|
|
|
|
let mut file = File::create(if is_cpp {
|
|
|
|
"__bindgen.ii"
|
|
|
|
} else {
|
|
|
|
"__bindgen.i"
|
|
|
|
})?;
|
|
|
|
io::copy(&mut preprocessed, &mut file)?;
|
2017-07-17 12:54:51 -07:00
|
|
|
|
|
|
|
if child.wait()?.success() {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
2017-08-04 17:15:41 +02:00
|
|
|
Err(io::Error::new(
|
|
|
|
io::ErrorKind::Other,
|
|
|
|
"clang exited with non-zero status",
|
|
|
|
))
|
2017-07-17 12:54:51 -07:00
|
|
|
}
|
2017-07-13 14:17:53 -07:00
|
|
|
}
|
2017-09-16 18:41:34 -04:00
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Don't derive `PartialEq` for a given type. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
pub fn no_partialeq<T: Into<String>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.no_partialeq_types.insert(arg.into());
|
|
|
|
self
|
|
|
|
}
|
2017-09-16 18:41:34 -04:00
|
|
|
}
|
2017-10-19 13:48:16 -04:00
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Don't derive `Copy` for a given type. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
pub fn no_copy<T: Into<String>>(mut self, arg: T) -> Self {
|
|
|
|
self.options.no_copy_types.insert(arg.into());
|
|
|
|
self
|
|
|
|
}
|
2017-10-19 13:48:16 -04:00
|
|
|
}
|
2017-10-26 11:23:30 +11:00
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Don't derive `Debug` for a given type. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
pub fn no_debug<T: Into<String>>(mut self, arg: T) -> Self {
|
|
|
|
self.options.no_debug_types.insert(arg.into());
|
|
|
|
self
|
|
|
|
}
|
2020-08-02 09:48:40 +08:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Don't derive/impl `Default` for a given type. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
pub fn no_default<T: Into<String>>(mut self, arg: T) -> Self {
|
|
|
|
self.options.no_default_types.insert(arg.into());
|
|
|
|
self
|
|
|
|
}
|
2020-11-25 17:24:46 +08:00
|
|
|
}
|
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Don't derive `Hash` for a given type. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
pub fn no_hash<T: Into<String>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.no_hash_types.insert(arg.into());
|
|
|
|
self
|
|
|
|
}
|
2017-10-26 11:23:30 +11:00
|
|
|
}
|
2019-05-20 13:54:50 +03:00
|
|
|
|
2022-11-14 12:34:05 -05:00
|
|
|
fn_with_regex_arg! {
|
|
|
|
/// Add `#[must_use]` for the given type. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
pub fn must_use_type<T: Into<String>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.must_use_types.insert(arg.into());
|
|
|
|
self
|
|
|
|
}
|
2021-07-23 17:43:44 +02:00
|
|
|
}
|
|
|
|
|
2019-05-20 13:54:50 +03:00
|
|
|
/// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut)
|
|
|
|
pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self {
|
|
|
|
self.options.array_pointers_in_arguments = doit;
|
|
|
|
self
|
|
|
|
}
|
2019-12-10 16:12:16 +01:00
|
|
|
|
|
|
|
/// Set the wasm import module name
|
|
|
|
pub fn wasm_import_module_name<T: Into<String>>(
|
|
|
|
mut self,
|
|
|
|
import_name: T,
|
|
|
|
) -> Self {
|
|
|
|
self.options.wasm_import_module_name = Some(import_name.into());
|
|
|
|
self
|
|
|
|
}
|
2020-07-27 10:26:38 +01:00
|
|
|
|
|
|
|
/// Specify the dynamic library name if we are generating bindings for a shared library.
|
|
|
|
pub fn dynamic_library_name<T: Into<String>>(
|
|
|
|
mut self,
|
|
|
|
dynamic_library_name: T,
|
|
|
|
) -> Self {
|
|
|
|
self.options.dynamic_library_name = Some(dynamic_library_name.into());
|
|
|
|
self
|
|
|
|
}
|
2021-01-13 10:04:50 -08:00
|
|
|
|
2021-03-26 17:12:23 -05:00
|
|
|
/// Require successful linkage for all routines in a shared library.
|
|
|
|
/// This allows us to optimize function calls by being able to safely assume function pointers
|
|
|
|
/// are valid.
|
|
|
|
pub fn dynamic_link_require_all(mut self, req: bool) -> Self {
|
|
|
|
self.options.dynamic_link_require_all = req;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2021-01-13 10:04:50 -08:00
|
|
|
/// Generate bindings as `pub` only if the bound item is publically accessible by C++.
|
|
|
|
pub fn respect_cxx_access_specs(mut self, doit: bool) -> Self {
|
|
|
|
self.options.respect_cxx_access_specs = doit;
|
|
|
|
self
|
|
|
|
}
|
2021-03-10 13:25:53 +01:00
|
|
|
|
|
|
|
/// Always translate enum integer types to native Rust integer types.
|
|
|
|
///
|
|
|
|
/// This will result in enums having types such as `u32` and `i16` instead
|
|
|
|
/// of `c_uint` and `c_short`. Types for Rustified enums are always
|
|
|
|
/// translated.
|
|
|
|
pub fn translate_enum_integer_types(mut self, doit: bool) -> Self {
|
|
|
|
self.options.translate_enum_integer_types = doit;
|
|
|
|
self
|
|
|
|
}
|
2021-04-30 02:16:49 +02:00
|
|
|
|
|
|
|
/// Generate types with C style naming.
|
|
|
|
///
|
|
|
|
/// This will add prefixes to the generated type names. For example instead of a struct `A` we
|
|
|
|
/// will generate struct `struct_A`. Currently applies to structs, unions, and enums.
|
|
|
|
pub fn c_naming(mut self, doit: bool) -> Self {
|
|
|
|
self.options.c_naming = doit;
|
|
|
|
self
|
|
|
|
}
|
2022-11-02 15:30:34 -05:00
|
|
|
|
|
|
|
/// Override the ABI of a given function. Regular expressions are supported.
|
|
|
|
pub fn override_abi<T: Into<String>>(mut self, abi: Abi, arg: T) -> Self {
|
|
|
|
self.options
|
|
|
|
.abi_overrides
|
|
|
|
.entry(abi)
|
|
|
|
.or_default()
|
|
|
|
.insert(arg.into());
|
|
|
|
self
|
|
|
|
}
|
2022-11-22 11:41:32 -05:00
|
|
|
|
|
|
|
/// If true, wraps unsafe operations in unsafe blocks.
|
|
|
|
pub fn wrap_unsafe_ops(mut self, doit: bool) -> Self {
|
|
|
|
self.options.wrap_unsafe_ops = doit;
|
|
|
|
self
|
|
|
|
}
|
2023-02-07 10:13:48 -05:00
|
|
|
|
|
|
|
#[cfg(feature = "experimental")]
|
|
|
|
/// Whether to generate extern wrappers for `static` and `static inline` functions. Defaults to
|
|
|
|
/// false.
|
|
|
|
pub fn wrap_static_fns(mut self, doit: bool) -> Self {
|
|
|
|
self.options.wrap_static_fns = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "experimental")]
|
|
|
|
/// Set the path for the source code file that would be created if any wrapper functions must
|
|
|
|
/// be generated due to the presence of static functions.
|
|
|
|
///
|
|
|
|
/// Bindgen will automatically add the right extension to the header and source code files.
|
|
|
|
pub fn wrap_static_fns_path<T: AsRef<Path>>(mut self, path: T) -> Self {
|
|
|
|
self.options.wrap_static_fns_path = Some(path.as_ref().to_owned());
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "experimental")]
|
|
|
|
/// Set the suffix added to the extern wrapper functions generated for `static` and `static
|
|
|
|
/// inline` functions.
|
|
|
|
pub fn wrap_static_fns_suffix<T: AsRef<str>>(mut self, suffix: T) -> Self {
|
|
|
|
self.options.wrap_static_fns_suffix = Some(suffix.as_ref().to_owned());
|
|
|
|
self
|
|
|
|
}
|
2015-05-06 12:27:56 +01:00
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Configuration options for generated bindings.
|
2022-09-26 13:22:15 -05:00
|
|
|
#[derive(Clone, Debug)]
|
2017-09-18 22:36:50 +03:00
|
|
|
struct BindgenOptions {
|
2021-02-11 08:58:46 +01:00
|
|
|
/// The set of types that have been blocklisted and should not appear
|
2016-10-24 14:13:13 -07:00
|
|
|
/// anywhere in the generated code.
|
2021-02-11 08:58:46 +01:00
|
|
|
blocklisted_types: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2021-02-11 08:58:46 +01:00
|
|
|
/// The set of functions that have been blocklisted and should not appear
|
2018-08-13 17:03:10 +02:00
|
|
|
/// in the generated code.
|
2021-02-11 08:58:46 +01:00
|
|
|
blocklisted_functions: RegexSet,
|
2018-08-13 17:03:10 +02:00
|
|
|
|
2018-10-13 08:15:08 -04:00
|
|
|
/// The set of items, regardless of item-type, that have been
|
2021-02-11 08:58:46 +01:00
|
|
|
/// blocklisted and should not appear in the generated code.
|
|
|
|
blocklisted_items: RegexSet,
|
2018-10-12 17:31:36 -04:00
|
|
|
|
2021-11-26 01:42:47 +00:00
|
|
|
/// The set of files whose contents should be blocklisted and should not
|
|
|
|
/// appear in the generated code.
|
|
|
|
blocklisted_files: RegexSet,
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// The set of types that should be treated as opaque structures in the
|
|
|
|
/// generated code.
|
2017-09-18 22:36:50 +03:00
|
|
|
opaque_types: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2018-01-26 21:09:42 +01:00
|
|
|
/// The explicit rustfmt path.
|
|
|
|
rustfmt_path: Option<PathBuf>,
|
|
|
|
|
2021-04-08 17:26:55 +00:00
|
|
|
/// The path to which we should write a Makefile-syntax depfile (if any).
|
|
|
|
depfile: Option<deps::DepfileSpec>,
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// The set of types that we should have bindings for in the generated
|
|
|
|
/// code.
|
|
|
|
///
|
|
|
|
/// This includes all types transitively reachable from any type in this
|
2021-02-11 08:58:46 +01:00
|
|
|
/// set. One might think of allowlisted types/vars/functions as GC roots,
|
2016-10-24 14:13:13 -07:00
|
|
|
/// and the generated Rust code as including everything that gets marked.
|
2021-02-11 08:58:46 +01:00
|
|
|
allowlisted_types: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2021-02-11 08:58:46 +01:00
|
|
|
/// Allowlisted functions. See docs for `allowlisted_types` for more.
|
|
|
|
allowlisted_functions: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2021-02-11 08:58:46 +01:00
|
|
|
/// Allowlisted variables. See docs for `allowlisted_types` for more.
|
|
|
|
allowlisted_vars: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2021-11-29 13:03:26 +00:00
|
|
|
/// The set of files whose contents should be allowlisted.
|
|
|
|
allowlisted_files: RegexSet,
|
|
|
|
|
2018-06-04 05:35:17 -07:00
|
|
|
/// The default style of code to generate for enums
|
|
|
|
default_enum_style: codegen::EnumVariation,
|
2018-06-03 11:35:07 -07:00
|
|
|
|
2019-11-14 22:55:05 +11:00
|
|
|
/// The enum patterns to mark an enum as a bitfield
|
|
|
|
/// (newtype with bitwise operations).
|
2017-09-18 22:36:50 +03:00
|
|
|
bitfield_enums: RegexSet,
|
2016-11-08 07:31:53 +01:00
|
|
|
|
2019-11-14 22:55:05 +11:00
|
|
|
/// The enum patterns to mark an enum as a newtype.
|
|
|
|
newtype_enums: RegexSet,
|
|
|
|
|
2022-09-06 16:59:49 -05:00
|
|
|
/// The enum patterns to mark an enum as a global newtype.
|
|
|
|
newtype_global_enums: RegexSet,
|
|
|
|
|
2017-09-08 20:04:33 -04:00
|
|
|
/// The enum patterns to mark an enum as a Rust enum.
|
2017-09-18 22:36:50 +03:00
|
|
|
rustified_enums: RegexSet,
|
2017-01-24 10:51:19 +01:00
|
|
|
|
2019-10-03 13:40:43 +10:00
|
|
|
/// The enum patterns to mark an enum as a non-exhaustive Rust enum.
|
2019-06-11 11:19:59 -03:00
|
|
|
rustified_non_exhaustive_enums: RegexSet,
|
2019-06-10 15:16:19 -03:00
|
|
|
|
2017-06-11 13:26:13 -07:00
|
|
|
/// The enum patterns to mark an enum as a module of constants.
|
2017-09-18 22:36:50 +03:00
|
|
|
constified_enum_modules: RegexSet,
|
2017-06-11 13:26:13 -07:00
|
|
|
|
2018-06-04 10:04:02 -07:00
|
|
|
/// The enum patterns to mark an enum as a set of constants.
|
|
|
|
constified_enums: RegexSet,
|
|
|
|
|
2020-08-08 16:20:47 -07:00
|
|
|
/// The default type for C macro constants.
|
|
|
|
default_macro_constant_type: codegen::MacroTypeVariation,
|
|
|
|
|
2019-10-26 17:57:13 +08:00
|
|
|
/// The default style of code to generate for typedefs.
|
|
|
|
default_alias_style: codegen::AliasVariation,
|
|
|
|
|
|
|
|
/// Typedef patterns that will use regular type aliasing.
|
|
|
|
type_alias: RegexSet,
|
|
|
|
|
|
|
|
/// Typedef patterns that will be aliased by creating a new struct.
|
|
|
|
new_type_alias: RegexSet,
|
|
|
|
|
|
|
|
/// Typedef patterns that will be wrapped in a new struct and have
|
|
|
|
/// Deref and Deref to their aliased type.
|
|
|
|
new_type_alias_deref: RegexSet,
|
|
|
|
|
2022-09-23 08:30:49 +02:00
|
|
|
/// The default style of code to generate for union containing non-Copy
|
|
|
|
/// members.
|
|
|
|
default_non_copy_union_style: codegen::NonCopyUnionStyle,
|
|
|
|
|
|
|
|
/// The union patterns to mark an non-Copy union as using the bindgen
|
|
|
|
/// generated wrapper.
|
|
|
|
bindgen_wrapper_union: RegexSet,
|
|
|
|
|
|
|
|
/// The union patterns to mark an non-Copy union as using the
|
|
|
|
/// `::core::mem::ManuallyDrop` wrapper.
|
|
|
|
manually_drop_union: RegexSet,
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Whether we should generate builtins or not.
|
2017-09-18 22:36:50 +03:00
|
|
|
builtins: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
/// True if we should dump the Clang AST for debugging purposes.
|
2017-09-18 22:36:50 +03:00
|
|
|
emit_ast: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2016-11-15 10:26:26 -08:00
|
|
|
/// True if we should dump our internal IR for debugging purposes.
|
2017-09-18 22:36:50 +03:00
|
|
|
emit_ir: bool,
|
2016-11-15 10:26:26 -08:00
|
|
|
|
2017-02-13 22:35:28 +03:00
|
|
|
/// Output graphviz dot file.
|
2017-09-18 22:36:50 +03:00
|
|
|
emit_ir_graphviz: Option<String>,
|
2017-02-13 22:35:28 +03:00
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// True if we should emulate C++ namespaces with Rust modules in the
|
|
|
|
/// generated bindings.
|
2017-09-18 22:36:50 +03:00
|
|
|
enable_cxx_namespaces: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2018-12-14 12:24:14 +01:00
|
|
|
/// True if we should try to find unexposed attributes in functions, in
|
|
|
|
/// order to be able to generate #[must_use] attributes in Rust.
|
|
|
|
enable_function_attribute_detection: bool,
|
|
|
|
|
2016-11-24 21:06:42 +01:00
|
|
|
/// True if we should avoid mangling names with namespaces.
|
2017-09-18 22:36:50 +03:00
|
|
|
disable_name_namespacing: bool,
|
2016-11-24 21:06:42 +01:00
|
|
|
|
2019-09-17 21:44:34 +03:00
|
|
|
/// True if we should avoid generating nested struct names.
|
|
|
|
disable_nested_struct_naming: bool,
|
|
|
|
|
2020-06-22 18:03:48 -07:00
|
|
|
/// True if we should avoid embedding version identifiers into source code.
|
|
|
|
disable_header_comment: bool,
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
/// True if we should generate layout tests for generated structures.
|
2017-09-18 22:36:50 +03:00
|
|
|
layout_tests: bool,
|
2017-04-14 12:37:44 +01:00
|
|
|
|
2017-09-23 01:48:19 +03:00
|
|
|
/// True if we should implement the Debug trait for C/C++ structures and types
|
|
|
|
/// that do not support automatically deriving Debug.
|
|
|
|
impl_debug: bool,
|
|
|
|
|
|
|
|
/// True if we should implement the PartialEq trait for C/C++ structures and types
|
2018-06-13 11:08:17 +07:00
|
|
|
/// that do not support automatically deriving PartialEq.
|
2017-09-23 01:48:19 +03:00
|
|
|
impl_partialeq: bool,
|
|
|
|
|
2017-09-06 16:42:53 +01:00
|
|
|
/// True if we should derive Copy trait implementations for C/C++ structures
|
|
|
|
/// and types.
|
2017-09-18 22:36:50 +03:00
|
|
|
derive_copy: bool,
|
2017-09-06 16:42:53 +01:00
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
/// True if we should derive Debug trait implementations for C/C++ structures
|
2016-10-24 14:13:13 -07:00
|
|
|
/// and types.
|
2017-09-18 22:36:50 +03:00
|
|
|
derive_debug: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
/// True if we should derive Default trait implementations for C/C++ structures
|
2017-02-05 17:12:05 +08:00
|
|
|
/// and types.
|
2017-09-18 22:36:50 +03:00
|
|
|
derive_default: bool,
|
2017-02-05 17:12:05 +08:00
|
|
|
|
2017-08-02 11:19:14 -07:00
|
|
|
/// True if we should derive Hash trait implementations for C/C++ structures
|
|
|
|
/// and types.
|
2017-09-18 22:36:50 +03:00
|
|
|
derive_hash: bool,
|
2017-08-02 11:19:14 -07:00
|
|
|
|
2017-09-19 17:13:14 +03:00
|
|
|
/// True if we should derive PartialOrd trait implementations for C/C++ structures
|
|
|
|
/// and types.
|
|
|
|
derive_partialord: bool,
|
|
|
|
|
2017-09-19 22:42:22 +03:00
|
|
|
/// True if we should derive Ord trait implementations for C/C++ structures
|
|
|
|
/// and types.
|
|
|
|
derive_ord: bool,
|
|
|
|
|
2017-08-10 16:22:48 -07:00
|
|
|
/// True if we should derive PartialEq trait implementations for C/C++ structures
|
|
|
|
/// and types.
|
2017-09-18 22:36:50 +03:00
|
|
|
derive_partialeq: bool,
|
2017-08-10 16:22:48 -07:00
|
|
|
|
2017-08-16 19:34:51 -05:00
|
|
|
/// True if we should derive Eq trait implementations for C/C++ structures
|
|
|
|
/// and types.
|
2017-09-18 22:36:50 +03:00
|
|
|
derive_eq: bool,
|
2017-08-16 19:34:51 -05:00
|
|
|
|
2016-11-06 12:02:44 +01:00
|
|
|
/// True if we should avoid using libstd to use libcore instead.
|
2017-09-18 22:36:50 +03:00
|
|
|
use_core: bool,
|
2016-11-06 12:02:44 +01:00
|
|
|
|
|
|
|
/// An optional prefix for the "raw" types, like `c_int`, `c_void`...
|
2017-09-18 22:36:50 +03:00
|
|
|
ctypes_prefix: Option<String>,
|
2016-11-06 12:02:44 +01:00
|
|
|
|
2020-08-02 14:49:48 -07:00
|
|
|
/// The prefix for the anon fields.
|
|
|
|
anon_fields_prefix: String,
|
2019-10-31 23:32:45 +08:00
|
|
|
|
2017-08-29 22:08:37 -05:00
|
|
|
/// Whether to time the bindgen phases.
|
2017-09-18 22:36:50 +03:00
|
|
|
time_phases: bool,
|
2017-08-29 22:08:37 -05:00
|
|
|
|
2016-11-06 20:52:01 +01:00
|
|
|
/// Whether we should convert float types to f32/f64 types.
|
2017-09-18 22:36:50 +03:00
|
|
|
convert_floats: bool,
|
2016-11-06 20:52:01 +01:00
|
|
|
|
2018-05-03 04:21:08 +02:00
|
|
|
/// The set of raw lines to prepend to the top-level module of generated
|
|
|
|
/// Rust code.
|
2017-09-18 22:36:50 +03:00
|
|
|
raw_lines: Vec<String>,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2018-05-03 04:21:08 +02:00
|
|
|
/// The set of raw lines to prepend to each of the modules.
|
|
|
|
///
|
|
|
|
/// This only makes sense if the `enable_cxx_namespaces` option is set.
|
|
|
|
module_lines: HashMap<String, Vec<String>>,
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// The set of arguments to pass straight through to Clang.
|
2017-09-18 22:36:50 +03:00
|
|
|
clang_args: Vec<String>,
|
2016-10-31 16:29:02 -07:00
|
|
|
|
2022-10-03 13:57:04 -05:00
|
|
|
/// The input header files.
|
|
|
|
input_headers: Vec<String>,
|
2016-10-31 16:29:02 -07:00
|
|
|
|
2022-10-03 13:57:04 -05:00
|
|
|
/// Tuples of unsaved file contents of the form (name, contents).
|
|
|
|
input_header_contents: Vec<(String, String)>,
|
2021-04-08 17:26:55 +00:00
|
|
|
|
2017-03-17 12:16:26 -04:00
|
|
|
/// A user-provided visitor to allow customizing different kinds of
|
2016-11-06 20:32:37 +01:00
|
|
|
/// situations.
|
2022-11-02 13:46:22 -05:00
|
|
|
parse_callbacks: Vec<Rc<dyn callbacks::ParseCallbacks>>,
|
2016-12-04 15:15:56 +01:00
|
|
|
|
|
|
|
/// Which kind of items should we generate? By default, we'll generate all
|
|
|
|
/// of them.
|
2017-09-18 22:36:50 +03:00
|
|
|
codegen_config: CodegenConfig,
|
2017-01-07 02:30:51 +01:00
|
|
|
|
|
|
|
/// Whether to treat inline namespaces conservatively.
|
|
|
|
///
|
|
|
|
/// See the builder method description for more details.
|
2017-09-18 22:36:50 +03:00
|
|
|
conservative_inline_namespaces: bool,
|
2017-01-26 17:09:28 +01:00
|
|
|
|
2018-06-13 11:08:17 +07:00
|
|
|
/// Whether to keep documentation comments in the generated output. See the
|
2021-03-09 11:58:32 +00:00
|
|
|
/// documentation for more details. Defaults to true.
|
2017-09-18 22:36:50 +03:00
|
|
|
generate_comments: bool,
|
2017-01-26 17:26:02 +01:00
|
|
|
|
2017-03-20 14:37:41 +01:00
|
|
|
/// Whether to generate inline functions. Defaults to false.
|
2017-09-18 22:36:50 +03:00
|
|
|
generate_inline_functions: bool,
|
2017-03-20 14:37:41 +01:00
|
|
|
|
2021-02-11 08:58:46 +01:00
|
|
|
/// Whether to allowlist types recursively. Defaults to true.
|
|
|
|
allowlist_recursively: bool,
|
2017-01-29 01:10:38 +02:00
|
|
|
|
2018-06-13 11:08:17 +07:00
|
|
|
/// Instead of emitting 'use objc;' to files generated from objective c files,
|
2017-01-29 01:10:38 +02:00
|
|
|
/// generate '#[macro_use] extern crate objc;'
|
2017-09-18 22:36:50 +03:00
|
|
|
objc_extern_crate: bool,
|
2017-02-18 19:30:00 +01:00
|
|
|
|
2018-10-04 16:14:27 +02:00
|
|
|
/// Instead of emitting 'use block;' to files generated from objective c files,
|
|
|
|
/// generate '#[macro_use] extern crate block;'
|
|
|
|
generate_block: bool,
|
|
|
|
|
2018-09-01 00:55:43 +08:00
|
|
|
/// Instead of emitting 'use block;' to files generated from objective c files,
|
|
|
|
/// generate '#[macro_use] extern crate block;'
|
|
|
|
block_extern_crate: bool,
|
|
|
|
|
2017-02-18 19:30:00 +01:00
|
|
|
/// Whether to use the clang-provided name mangling. This is true and
|
|
|
|
/// probably needed for C++ features.
|
|
|
|
///
|
|
|
|
/// However, some old libclang versions seem to return incorrect results in
|
|
|
|
/// some cases for non-mangled functions, see [1], so we allow disabling it.
|
|
|
|
///
|
2019-05-20 17:14:30 -07:00
|
|
|
/// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
|
2017-09-18 22:36:50 +03:00
|
|
|
enable_mangling: bool,
|
2017-02-27 18:17:28 +01:00
|
|
|
|
2019-03-26 13:24:00 +01:00
|
|
|
/// Whether to detect include paths using clang_sys.
|
|
|
|
detect_include_paths: bool,
|
|
|
|
|
2020-12-15 17:18:16 +01:00
|
|
|
/// Whether to try to fit macro constants into types smaller than u32/i32
|
|
|
|
fit_macro_constants: bool,
|
|
|
|
|
2019-11-14 22:55:05 +11:00
|
|
|
/// Whether to prepend the enum name to constant or newtype variants.
|
2017-09-18 22:36:50 +03:00
|
|
|
prepend_enum_name: bool,
|
2017-08-13 13:12:21 -07:00
|
|
|
|
|
|
|
/// Version of the Rust compiler to target
|
|
|
|
rust_target: RustTarget,
|
|
|
|
|
|
|
|
/// Features to enable, derived from `rust_target`
|
|
|
|
rust_features: RustFeatures,
|
2017-08-11 17:59:32 +02:00
|
|
|
|
2018-12-23 18:52:08 +01:00
|
|
|
/// Whether we should record which items in the regex sets ever matched.
|
|
|
|
///
|
2021-02-11 08:58:46 +01:00
|
|
|
/// This may be a bit slower, but will enable reporting of unused allowlist
|
2018-12-23 18:52:08 +01:00
|
|
|
/// items via the `error!` log.
|
|
|
|
record_matches: bool,
|
|
|
|
|
2020-02-03 12:03:15 +01:00
|
|
|
/// Whether `size_t` should be translated to `usize` automatically.
|
|
|
|
size_t_is_usize: bool,
|
|
|
|
|
2017-08-11 17:59:32 +02:00
|
|
|
/// Whether rustfmt should format the generated bindings.
|
2017-09-18 22:36:50 +03:00
|
|
|
rustfmt_bindings: bool,
|
2017-08-11 17:59:32 +02:00
|
|
|
|
|
|
|
/// The absolute path to the rustfmt configuration file, if None, the standard rustfmt
|
|
|
|
/// options are used.
|
2017-09-18 22:36:50 +03:00
|
|
|
rustfmt_configuration_file: Option<PathBuf>,
|
2017-09-16 18:41:34 -04:00
|
|
|
|
|
|
|
/// The set of types that we should not derive `PartialEq` for.
|
|
|
|
no_partialeq_types: RegexSet,
|
2017-10-19 13:48:16 -04:00
|
|
|
|
|
|
|
/// The set of types that we should not derive `Copy` for.
|
|
|
|
no_copy_types: RegexSet,
|
2017-10-26 11:23:30 +11:00
|
|
|
|
2020-08-02 09:48:40 +08:00
|
|
|
/// The set of types that we should not derive `Debug` for.
|
|
|
|
no_debug_types: RegexSet,
|
|
|
|
|
2020-11-25 17:24:46 +08:00
|
|
|
/// The set of types that we should not derive/impl `Default` for.
|
|
|
|
no_default_types: RegexSet,
|
|
|
|
|
2017-10-26 11:23:30 +11:00
|
|
|
/// The set of types that we should not derive `Hash` for.
|
|
|
|
no_hash_types: RegexSet,
|
2019-05-20 13:54:50 +03:00
|
|
|
|
2021-07-23 17:43:44 +02:00
|
|
|
/// The set of types that we should be annotated with `#[must_use]`.
|
|
|
|
must_use_types: RegexSet,
|
|
|
|
|
2019-05-20 13:54:50 +03:00
|
|
|
/// Decide if C arrays should be regular pointers in rust or array pointers
|
|
|
|
array_pointers_in_arguments: bool,
|
2019-12-10 16:12:16 +01:00
|
|
|
|
|
|
|
/// Wasm import module name.
|
|
|
|
wasm_import_module_name: Option<String>,
|
2020-07-27 10:26:38 +01:00
|
|
|
|
|
|
|
/// The name of the dynamic library (if we are generating bindings for a shared library). If
|
|
|
|
/// this is None, no dynamic bindings are created.
|
|
|
|
dynamic_library_name: Option<String>,
|
2021-01-13 10:04:50 -08:00
|
|
|
|
2021-03-26 17:12:23 -05:00
|
|
|
/// Require successful linkage for all routines in a shared library.
|
|
|
|
/// This allows us to optimize function calls by being able to safely assume function pointers
|
|
|
|
/// are valid. No effect if `dynamic_library_name` is None.
|
|
|
|
dynamic_link_require_all: bool,
|
|
|
|
|
2021-01-13 10:04:50 -08:00
|
|
|
/// Only make generated bindings `pub` if the items would be publically accessible
|
|
|
|
/// by C++.
|
|
|
|
respect_cxx_access_specs: bool,
|
2021-03-10 13:25:53 +01:00
|
|
|
|
|
|
|
/// Always translate enum integer types to native Rust integer types.
|
|
|
|
translate_enum_integer_types: bool,
|
2021-04-30 02:16:49 +02:00
|
|
|
|
|
|
|
/// Generate types with C style naming.
|
|
|
|
c_naming: bool,
|
2021-07-16 12:22:02 -07:00
|
|
|
|
|
|
|
/// Always output explicit padding fields
|
|
|
|
force_explicit_padding: bool,
|
2022-02-18 19:45:20 +01:00
|
|
|
|
|
|
|
/// Emit vtable functions.
|
|
|
|
vtable_generation: bool,
|
2022-08-24 18:45:03 -04:00
|
|
|
|
2022-09-23 02:04:28 -05:00
|
|
|
/// Sort the code generation.
|
2022-08-24 18:45:03 -04:00
|
|
|
sort_semantically: bool,
|
2022-09-23 02:04:28 -05:00
|
|
|
|
|
|
|
/// Deduplicate `extern` blocks.
|
|
|
|
merge_extern_blocks: bool,
|
2022-11-02 15:30:34 -05:00
|
|
|
|
|
|
|
abi_overrides: HashMap<Abi, RegexSet>,
|
2022-11-22 11:41:32 -05:00
|
|
|
|
|
|
|
/// Whether to wrap unsafe operations in unsafe blocks or not.
|
|
|
|
wrap_unsafe_ops: bool,
|
2023-02-07 10:13:48 -05:00
|
|
|
|
|
|
|
wrap_static_fns: bool,
|
|
|
|
|
|
|
|
wrap_static_fns_suffix: Option<String>,
|
|
|
|
|
|
|
|
wrap_static_fns_path: Option<PathBuf>,
|
2014-05-16 19:56:47 +01:00
|
|
|
}
|
|
|
|
|
2017-01-05 23:59:47 -08:00
|
|
|
impl BindgenOptions {
|
|
|
|
fn build(&mut self) {
|
2022-11-02 15:30:34 -05:00
|
|
|
let regex_sets = [
|
2021-02-11 08:58:46 +01:00
|
|
|
&mut self.allowlisted_vars,
|
|
|
|
&mut self.allowlisted_types,
|
|
|
|
&mut self.allowlisted_functions,
|
2021-11-29 13:03:26 +00:00
|
|
|
&mut self.allowlisted_files,
|
2021-02-11 08:58:46 +01:00
|
|
|
&mut self.blocklisted_types,
|
|
|
|
&mut self.blocklisted_functions,
|
|
|
|
&mut self.blocklisted_items,
|
2021-11-26 01:42:47 +00:00
|
|
|
&mut self.blocklisted_files,
|
2018-12-23 18:52:08 +01:00
|
|
|
&mut self.opaque_types,
|
|
|
|
&mut self.bitfield_enums,
|
|
|
|
&mut self.constified_enums,
|
|
|
|
&mut self.constified_enum_modules,
|
2019-11-14 22:55:05 +11:00
|
|
|
&mut self.newtype_enums,
|
2022-09-12 13:45:54 -05:00
|
|
|
&mut self.newtype_global_enums,
|
2018-12-23 18:52:08 +01:00
|
|
|
&mut self.rustified_enums,
|
2019-10-03 13:40:43 +10:00
|
|
|
&mut self.rustified_non_exhaustive_enums,
|
2019-10-26 17:57:13 +08:00
|
|
|
&mut self.type_alias,
|
|
|
|
&mut self.new_type_alias,
|
|
|
|
&mut self.new_type_alias_deref,
|
2022-09-23 08:30:49 +02:00
|
|
|
&mut self.bindgen_wrapper_union,
|
|
|
|
&mut self.manually_drop_union,
|
2018-12-23 18:52:08 +01:00
|
|
|
&mut self.no_partialeq_types,
|
|
|
|
&mut self.no_copy_types,
|
2020-08-02 09:48:40 +08:00
|
|
|
&mut self.no_debug_types,
|
2020-11-25 17:24:46 +08:00
|
|
|
&mut self.no_default_types,
|
2018-12-23 18:52:08 +01:00
|
|
|
&mut self.no_hash_types,
|
2021-07-23 17:43:44 +02:00
|
|
|
&mut self.must_use_types,
|
2018-12-23 18:52:08 +01:00
|
|
|
];
|
|
|
|
let record_matches = self.record_matches;
|
2022-11-02 15:30:34 -05:00
|
|
|
for regex_set in self.abi_overrides.values_mut().chain(regex_sets) {
|
2018-12-23 18:52:08 +01:00
|
|
|
regex_set.build(record_matches);
|
|
|
|
}
|
2017-01-05 23:59:47 -08:00
|
|
|
}
|
2017-08-13 13:12:21 -07:00
|
|
|
|
|
|
|
/// Update rust target version
|
|
|
|
pub fn set_rust_target(&mut self, rust_target: RustTarget) {
|
|
|
|
self.rust_target = rust_target;
|
|
|
|
|
|
|
|
// Keep rust_features synced with rust_target
|
|
|
|
self.rust_features = rust_target.into();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get features supported by target Rust version
|
|
|
|
pub fn rust_features(&self) -> RustFeatures {
|
|
|
|
self.rust_features
|
|
|
|
}
|
2022-11-02 13:46:22 -05:00
|
|
|
|
|
|
|
fn last_callback<T>(
|
|
|
|
&self,
|
|
|
|
f: impl Fn(&dyn callbacks::ParseCallbacks) -> Option<T>,
|
|
|
|
) -> Option<T> {
|
|
|
|
self.parse_callbacks
|
|
|
|
.iter()
|
|
|
|
.filter_map(|cb| f(cb.as_ref()))
|
|
|
|
.last()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn all_callbacks<T>(
|
|
|
|
&self,
|
|
|
|
f: impl Fn(&dyn callbacks::ParseCallbacks) -> Vec<T>,
|
|
|
|
) -> Vec<T> {
|
|
|
|
self.parse_callbacks
|
|
|
|
.iter()
|
|
|
|
.flat_map(|cb| f(cb.as_ref()))
|
|
|
|
.collect()
|
|
|
|
}
|
2022-11-22 11:25:13 -05:00
|
|
|
|
|
|
|
fn process_comment(&self, comment: &str) -> String {
|
|
|
|
let comment = comment::preprocess(comment);
|
|
|
|
self.parse_callbacks
|
|
|
|
.last()
|
|
|
|
.and_then(|cb| cb.process_comment(&comment))
|
|
|
|
.unwrap_or(comment)
|
|
|
|
}
|
2017-01-05 23:59:47 -08:00
|
|
|
}
|
|
|
|
|
2014-05-16 19:56:47 +01:00
|
|
|
impl Default for BindgenOptions {
|
|
|
|
fn default() -> BindgenOptions {
|
2022-11-04 13:08:14 -05:00
|
|
|
macro_rules! options {
|
|
|
|
($($field:ident $(: $value:expr)?,)* --default-fields-- $($default_field:ident,)*) => {
|
|
|
|
BindgenOptions {
|
|
|
|
$($field $(: $value)*,)*
|
|
|
|
$($default_field: Default::default(),)*
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-08-13 13:12:21 -07:00
|
|
|
let rust_target = RustTarget::default();
|
|
|
|
|
2022-11-04 13:08:14 -05:00
|
|
|
options! {
|
2018-08-13 17:03:10 +02:00
|
|
|
rust_target,
|
2017-08-13 13:12:21 -07:00
|
|
|
rust_features: rust_target.into(),
|
2017-04-14 12:37:44 +01:00
|
|
|
layout_tests: true,
|
2017-09-06 16:42:53 +01:00
|
|
|
derive_copy: true,
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
derive_debug: true,
|
2020-08-04 14:04:35 +08:00
|
|
|
anon_fields_prefix: DEFAULT_ANON_FIELDS_PREFIX.into(),
|
2016-11-06 20:52:01 +01:00
|
|
|
convert_floats: true,
|
2016-12-04 15:15:56 +01:00
|
|
|
codegen_config: CodegenConfig::all(),
|
2017-01-26 17:09:28 +01:00
|
|
|
generate_comments: true,
|
2021-02-11 08:58:46 +01:00
|
|
|
allowlist_recursively: true,
|
2017-02-18 19:30:00 +01:00
|
|
|
enable_mangling: true,
|
2019-03-26 13:24:00 +01:00
|
|
|
detect_include_paths: true,
|
2017-02-27 18:17:28 +01:00
|
|
|
prepend_enum_name: true,
|
2018-12-23 18:52:08 +01:00
|
|
|
record_matches: true,
|
2017-09-22 15:58:23 -04:00
|
|
|
rustfmt_bindings: true,
|
Map size_t to usize by default and check compatibility (fixes #1901, #1903)
This addresses the underlying issue identified in #1671, that size_t
(integer that can hold any object size) isn't guaranteed to match usize,
which is defined more like uintptr_t (integer that can hold any
pointer). However, on almost all platforms, this is true, and in fact
Rust already uses usize extensively in contexts where size_t would be
more appropriate, such as slice indexing. So, it's better for ergonomics
when interfacing with C code to map the C size_t type to usize. (See
also discussion in rust-lang/rust#65473 about how usize really should be
defined as size_t, not uintptr_t.)
The previous fix for #1671 removed the special case for size_t and
defaulted to binding it as a normal typedef. This change effectively
reverts that and goes back to mapping size_t to usize (and ssize_t to
isize), but also ensures that if size_t is emitted, the typedef'd type
of size_t in fact is compatible with usize (defined by checking that the
size and alignment match the target pointer width). For (hypothetical)
platforms where this is not true, or for compatibility with the default
behavior of bindgen between 0.53 and this commit, onwards, you can
disable this mapping with --no-size_t-is-usize.
2021-06-03 10:47:26 -04:00
|
|
|
size_t_is_usize: true,
|
2022-11-04 13:08:14 -05:00
|
|
|
|
|
|
|
--default-fields--
|
|
|
|
blocklisted_types,
|
|
|
|
blocklisted_functions,
|
|
|
|
blocklisted_items,
|
|
|
|
blocklisted_files,
|
|
|
|
opaque_types,
|
|
|
|
rustfmt_path,
|
|
|
|
depfile,
|
|
|
|
allowlisted_types,
|
|
|
|
allowlisted_functions,
|
|
|
|
allowlisted_vars,
|
|
|
|
allowlisted_files,
|
|
|
|
default_enum_style,
|
|
|
|
bitfield_enums,
|
|
|
|
newtype_enums,
|
|
|
|
newtype_global_enums,
|
|
|
|
rustified_enums,
|
|
|
|
rustified_non_exhaustive_enums,
|
|
|
|
constified_enums,
|
|
|
|
constified_enum_modules,
|
|
|
|
default_macro_constant_type,
|
|
|
|
default_alias_style,
|
|
|
|
type_alias,
|
|
|
|
new_type_alias,
|
|
|
|
new_type_alias_deref,
|
|
|
|
default_non_copy_union_style,
|
|
|
|
bindgen_wrapper_union,
|
|
|
|
manually_drop_union,
|
|
|
|
builtins,
|
|
|
|
emit_ast,
|
|
|
|
emit_ir,
|
|
|
|
emit_ir_graphviz,
|
|
|
|
impl_debug,
|
|
|
|
impl_partialeq,
|
|
|
|
derive_default,
|
|
|
|
derive_hash,
|
|
|
|
derive_partialord,
|
|
|
|
derive_ord,
|
|
|
|
derive_partialeq,
|
|
|
|
derive_eq,
|
|
|
|
enable_cxx_namespaces,
|
|
|
|
enable_function_attribute_detection,
|
|
|
|
disable_name_namespacing,
|
|
|
|
disable_nested_struct_naming,
|
|
|
|
disable_header_comment,
|
|
|
|
use_core,
|
|
|
|
ctypes_prefix,
|
|
|
|
raw_lines,
|
|
|
|
module_lines,
|
|
|
|
clang_args,
|
|
|
|
input_headers,
|
|
|
|
input_header_contents,
|
|
|
|
parse_callbacks,
|
|
|
|
conservative_inline_namespaces,
|
|
|
|
generate_inline_functions,
|
|
|
|
generate_block,
|
|
|
|
objc_extern_crate,
|
|
|
|
block_extern_crate,
|
|
|
|
fit_macro_constants,
|
|
|
|
time_phases,
|
|
|
|
rustfmt_configuration_file,
|
|
|
|
no_partialeq_types,
|
|
|
|
no_copy_types,
|
|
|
|
no_debug_types,
|
|
|
|
no_default_types,
|
|
|
|
no_hash_types,
|
|
|
|
must_use_types,
|
|
|
|
array_pointers_in_arguments,
|
|
|
|
wasm_import_module_name,
|
|
|
|
dynamic_library_name,
|
|
|
|
dynamic_link_require_all,
|
|
|
|
respect_cxx_access_specs,
|
|
|
|
translate_enum_integer_types,
|
|
|
|
c_naming,
|
|
|
|
force_explicit_padding,
|
|
|
|
vtable_generation,
|
|
|
|
sort_semantically,
|
|
|
|
merge_extern_blocks,
|
|
|
|
abi_overrides,
|
2022-11-22 11:41:32 -05:00
|
|
|
wrap_unsafe_ops,
|
2023-02-07 10:13:48 -05:00
|
|
|
wrap_static_fns,
|
|
|
|
wrap_static_fns_suffix,
|
|
|
|
wrap_static_fns_path,
|
2014-05-16 19:56:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-15 23:09:22 -07:00
|
|
|
#[cfg(feature = "runtime")]
|
2016-12-21 16:07:09 -08:00
|
|
|
fn ensure_libclang_is_loaded() {
|
|
|
|
if clang_sys::is_loaded() {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX (issue #350): Ensure that our dynamically loaded `libclang`
|
|
|
|
// doesn't get dropped prematurely, nor is loaded multiple times
|
|
|
|
// across different threads.
|
|
|
|
|
|
|
|
lazy_static! {
|
2019-09-15 23:09:22 -07:00
|
|
|
static ref LIBCLANG: std::sync::Arc<clang_sys::SharedLibrary> = {
|
2017-02-19 12:51:30 +01:00
|
|
|
clang_sys::load().expect("Unable to find libclang");
|
2019-09-17 09:44:06 +09:00
|
|
|
clang_sys::get_library().expect(
|
|
|
|
"We just loaded libclang and it had better still be \
|
|
|
|
here!",
|
|
|
|
)
|
2016-12-21 16:07:09 -08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-02-19 12:51:30 +01:00
|
|
|
clang_sys::set_library(Some(LIBCLANG.clone()));
|
2016-12-21 16:07:09 -08:00
|
|
|
}
|
|
|
|
|
2019-09-15 23:09:22 -07:00
|
|
|
#[cfg(not(feature = "runtime"))]
|
2019-10-14 16:45:36 +02:00
|
|
|
fn ensure_libclang_is_loaded() {}
|
2019-09-15 23:09:22 -07:00
|
|
|
|
2021-12-04 16:46:39 +09:00
|
|
|
/// Error type for rust-bindgen.
|
2021-12-08 13:51:57 +09:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
2021-12-05 09:51:30 +09:00
|
|
|
#[non_exhaustive]
|
2021-12-04 16:46:39 +09:00
|
|
|
pub enum BindgenError {
|
2021-12-08 13:49:54 +09:00
|
|
|
/// The header was a folder.
|
2021-12-09 09:50:21 +09:00
|
|
|
FolderAsHeader(PathBuf),
|
2021-12-08 13:49:54 +09:00
|
|
|
/// Permissions to read the header is insufficient.
|
2021-12-09 09:50:21 +09:00
|
|
|
InsufficientPermissions(PathBuf),
|
2021-12-08 13:49:54 +09:00
|
|
|
/// The header does not exist.
|
2021-12-09 09:50:21 +09:00
|
|
|
NotExist(PathBuf),
|
2021-12-04 16:46:39 +09:00
|
|
|
/// Clang diagnosed an error.
|
|
|
|
ClangDiagnostic(String),
|
2023-02-07 10:13:48 -05:00
|
|
|
/// Code generation reported an error.
|
|
|
|
Codegen(CodegenError),
|
2021-12-04 16:46:39 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
impl std::fmt::Display for BindgenError {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
match self {
|
2021-12-09 09:50:21 +09:00
|
|
|
BindgenError::FolderAsHeader(h) => {
|
|
|
|
write!(f, "'{}' is a folder", h.display())
|
|
|
|
}
|
2021-12-08 13:49:54 +09:00
|
|
|
BindgenError::InsufficientPermissions(h) => {
|
2021-12-09 09:50:21 +09:00
|
|
|
write!(f, "insufficient permissions to read '{}'", h.display())
|
2021-12-08 13:49:54 +09:00
|
|
|
}
|
|
|
|
BindgenError::NotExist(h) => {
|
2021-12-09 09:50:21 +09:00
|
|
|
write!(f, "header '{}' does not exist.", h.display())
|
2021-12-04 16:46:39 +09:00
|
|
|
}
|
|
|
|
BindgenError::ClangDiagnostic(message) => {
|
|
|
|
write!(f, "clang diagnosed error: {}", message)
|
|
|
|
}
|
2023-02-07 10:13:48 -05:00
|
|
|
BindgenError::Codegen(err) => {
|
|
|
|
write!(f, "codegen error: {}", err)
|
|
|
|
}
|
2021-12-04 16:46:39 +09:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-04 16:53:35 +09:00
|
|
|
impl std::error::Error for BindgenError {}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Generated Rust bindings.
|
2016-10-31 16:29:02 -07:00
|
|
|
#[derive(Debug)]
|
2017-08-22 18:53:55 -07:00
|
|
|
pub struct Bindings {
|
2017-10-12 12:02:47 -07:00
|
|
|
options: BindgenOptions,
|
2022-08-10 12:51:38 -05:00
|
|
|
warnings: Vec<String>,
|
2018-05-29 12:33:02 +02:00
|
|
|
module: proc_macro2::TokenStream,
|
2014-05-16 19:56:47 +01:00
|
|
|
}
|
|
|
|
|
2021-10-25 22:06:54 +09:00
|
|
|
pub(crate) const HOST_TARGET: &str =
|
2020-08-14 11:29:08 +09:00
|
|
|
include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
|
|
|
|
|
2020-08-23 20:37:53 +02:00
|
|
|
// Some architecture triplets are different between rust and libclang, see #1211
|
|
|
|
// and duplicates.
|
|
|
|
fn rust_to_clang_target(rust_target: &str) -> String {
|
|
|
|
if rust_target.starts_with("aarch64-apple-") {
|
|
|
|
let mut clang_target = "arm64-apple-".to_owned();
|
2021-10-25 22:06:54 +09:00
|
|
|
clang_target
|
|
|
|
.push_str(rust_target.strip_prefix("aarch64-apple-").unwrap());
|
2020-08-23 20:37:53 +02:00
|
|
|
return clang_target;
|
2021-12-12 15:09:30 +11:00
|
|
|
} else if rust_target.starts_with("riscv64gc-") {
|
|
|
|
let mut clang_target = "riscv64-".to_owned();
|
|
|
|
clang_target.push_str(rust_target.strip_prefix("riscv64gc-").unwrap());
|
|
|
|
return clang_target;
|
2023-01-25 14:54:19 -08:00
|
|
|
} else if rust_target.ends_with("-espidf") {
|
|
|
|
let mut clang_target =
|
|
|
|
rust_target.strip_suffix("-espidf").unwrap().to_owned();
|
|
|
|
clang_target.push_str("-elf");
|
|
|
|
if clang_target.starts_with("riscv32imc-") {
|
|
|
|
clang_target = "riscv32-".to_owned() +
|
|
|
|
clang_target.strip_prefix("riscv32imc-").unwrap();
|
|
|
|
}
|
|
|
|
return clang_target;
|
2020-08-23 20:37:53 +02:00
|
|
|
}
|
|
|
|
rust_target.to_owned()
|
|
|
|
}
|
|
|
|
|
2020-08-14 11:29:08 +09:00
|
|
|
/// Returns the effective target, and whether it was explicitly specified on the
|
|
|
|
/// clang flags.
|
|
|
|
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
|
|
|
|
let mut args = clang_args.iter();
|
|
|
|
while let Some(opt) = args.next() {
|
|
|
|
if opt.starts_with("--target=") {
|
|
|
|
let mut split = opt.split('=');
|
|
|
|
split.next();
|
|
|
|
return (split.next().unwrap().to_owned(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if opt == "-target" {
|
|
|
|
if let Some(target) = args.next() {
|
|
|
|
return (target.clone(), true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we're running from a build script, try to find the cargo target.
|
|
|
|
if let Ok(t) = env::var("TARGET") {
|
2020-08-23 20:37:53 +02:00
|
|
|
return (rust_to_clang_target(&t), false);
|
2020-08-14 11:29:08 +09:00
|
|
|
}
|
|
|
|
|
2020-08-23 20:37:53 +02:00
|
|
|
(rust_to_clang_target(HOST_TARGET), false)
|
2020-08-14 11:29:08 +09:00
|
|
|
}
|
|
|
|
|
2017-08-22 18:53:55 -07:00
|
|
|
impl Bindings {
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Generate bindings for the given options.
|
2017-09-18 22:36:50 +03:00
|
|
|
pub(crate) fn generate(
|
2017-08-04 17:15:41 +02:00
|
|
|
mut options: BindgenOptions,
|
2022-09-26 13:22:15 -05:00
|
|
|
input_unsaved_files: Vec<clang::UnsavedFile>,
|
2023-02-07 10:13:48 -05:00
|
|
|
) -> Result<Bindings, BindgenError> {
|
2016-12-21 16:07:09 -08:00
|
|
|
ensure_libclang_is_loaded();
|
2014-12-23 20:46:13 +01:00
|
|
|
|
2019-09-15 23:09:22 -07:00
|
|
|
#[cfg(feature = "runtime")]
|
2019-09-17 09:44:06 +09:00
|
|
|
debug!(
|
|
|
|
"Generating bindings, libclang at {}",
|
|
|
|
clang_sys::get_library().unwrap().path().display()
|
|
|
|
);
|
2019-09-15 23:09:22 -07:00
|
|
|
#[cfg(not(feature = "runtime"))]
|
|
|
|
debug!("Generating bindings, libclang linked");
|
2018-12-30 13:06:26 +01:00
|
|
|
|
2017-01-05 23:59:47 -08:00
|
|
|
options.build();
|
|
|
|
|
2020-08-14 11:29:08 +09:00
|
|
|
let (effective_target, explicit_target) =
|
|
|
|
find_effective_target(&options.clang_args);
|
|
|
|
|
2020-08-23 20:37:53 +02:00
|
|
|
let is_host_build =
|
|
|
|
rust_to_clang_target(HOST_TARGET) == effective_target;
|
|
|
|
|
|
|
|
// NOTE: The is_host_build check wouldn't be sound normally in some
|
|
|
|
// cases if we were to call a binary (if you have a 32-bit clang and are
|
|
|
|
// building on a 64-bit system for example). But since we rely on
|
|
|
|
// opening libclang.so, it has to be the same architecture and thus the
|
|
|
|
// check is fine.
|
|
|
|
if !explicit_target && !is_host_build {
|
2020-08-14 11:29:08 +09:00
|
|
|
options
|
|
|
|
.clang_args
|
|
|
|
.insert(0, format!("--target={}", effective_target));
|
|
|
|
};
|
|
|
|
|
2019-03-26 13:24:00 +01:00
|
|
|
fn detect_include_paths(options: &mut BindgenOptions) {
|
|
|
|
if !options.detect_include_paths {
|
|
|
|
return;
|
|
|
|
}
|
2017-07-27 18:33:18 +02:00
|
|
|
|
2019-03-26 13:24:00 +01:00
|
|
|
// Filter out include paths and similar stuff, so we don't incorrectly
|
|
|
|
// promote them to `-isystem`.
|
|
|
|
let clang_args_for_clang_sys = {
|
|
|
|
let mut last_was_include_prefix = false;
|
2019-09-17 09:44:06 +09:00
|
|
|
options
|
|
|
|
.clang_args
|
|
|
|
.iter()
|
|
|
|
.filter(|arg| {
|
|
|
|
if last_was_include_prefix {
|
|
|
|
last_was_include_prefix = false;
|
|
|
|
return false;
|
|
|
|
}
|
2017-07-27 18:33:18 +02:00
|
|
|
|
2019-09-17 09:44:06 +09:00
|
|
|
let arg = &**arg;
|
2017-07-27 18:33:18 +02:00
|
|
|
|
2019-09-17 09:44:06 +09:00
|
|
|
// https://clang.llvm.org/docs/ClangCommandLineReference.html
|
|
|
|
// -isystem and -isystem-after are harmless.
|
|
|
|
if arg == "-I" || arg == "--include-directory" {
|
|
|
|
last_was_include_prefix = true;
|
|
|
|
return false;
|
|
|
|
}
|
2017-07-27 18:33:18 +02:00
|
|
|
|
2019-09-17 09:44:06 +09:00
|
|
|
if arg.starts_with("-I") ||
|
|
|
|
arg.starts_with("--include-directory=")
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2019-03-26 13:24:00 +01:00
|
|
|
|
2019-09-17 09:44:06 +09:00
|
|
|
true
|
|
|
|
})
|
|
|
|
.cloned()
|
|
|
|
.collect::<Vec<_>>()
|
2019-03-26 13:24:00 +01:00
|
|
|
};
|
|
|
|
|
2019-09-17 09:44:06 +09:00
|
|
|
debug!(
|
|
|
|
"Trying to find clang with flags: {:?}",
|
|
|
|
clang_args_for_clang_sys
|
|
|
|
);
|
2017-07-27 18:33:18 +02:00
|
|
|
|
2019-09-17 09:44:06 +09:00
|
|
|
let clang = match clang_sys::support::Clang::find(
|
|
|
|
None,
|
|
|
|
&clang_args_for_clang_sys,
|
|
|
|
) {
|
2019-03-26 13:24:00 +01:00
|
|
|
None => return,
|
|
|
|
Some(clang) => clang,
|
|
|
|
};
|
2018-12-23 18:17:04 +01:00
|
|
|
|
|
|
|
debug!("Found clang: {:?}", clang);
|
|
|
|
|
2019-03-26 13:24:00 +01:00
|
|
|
// Whether we are working with C or C++ inputs.
|
2020-11-26 12:09:15 +01:00
|
|
|
let is_cpp = args_are_cpp(&options.clang_args) ||
|
2022-10-03 13:57:04 -05:00
|
|
|
options.input_headers.iter().any(|h| file_is_cpp(h));
|
2020-11-26 12:09:15 +01:00
|
|
|
|
2019-03-26 13:24:00 +01:00
|
|
|
let search_paths = if is_cpp {
|
2019-09-17 09:44:06 +09:00
|
|
|
clang.cpp_search_paths
|
2019-03-26 13:24:00 +01:00
|
|
|
} else {
|
2019-09-17 09:44:06 +09:00
|
|
|
clang.c_search_paths
|
2019-03-26 13:24:00 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
if let Some(search_paths) = search_paths {
|
|
|
|
for path in search_paths.into_iter() {
|
|
|
|
if let Ok(path) = path.into_os_string().into_string() {
|
|
|
|
options.clang_args.push("-isystem".to_owned());
|
|
|
|
options.clang_args.push(path);
|
2016-12-11 15:38:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-26 13:24:00 +01:00
|
|
|
detect_include_paths(&mut options);
|
|
|
|
|
2017-10-23 12:03:36 +11:00
|
|
|
#[cfg(unix)]
|
|
|
|
fn can_read(perms: &std::fs::Permissions) -> bool {
|
|
|
|
use std::os::unix::fs::PermissionsExt;
|
|
|
|
perms.mode() & 0o444 > 0
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(not(unix))]
|
|
|
|
fn can_read(_: &std::fs::Permissions) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-10-03 13:57:04 -05:00
|
|
|
if let Some(h) = options.input_headers.last() {
|
2021-12-09 09:50:21 +09:00
|
|
|
let path = Path::new(h);
|
|
|
|
if let Ok(md) = std::fs::metadata(path) {
|
2017-12-11 11:18:40 +01:00
|
|
|
if md.is_dir() {
|
2023-02-07 10:13:48 -05:00
|
|
|
return Err(BindgenError::FolderAsHeader(path.into()));
|
2017-11-10 11:32:32 +11:00
|
|
|
}
|
|
|
|
if !can_read(&md.permissions()) {
|
2023-02-07 10:13:48 -05:00
|
|
|
return Err(BindgenError::InsufficientPermissions(
|
|
|
|
path.into(),
|
|
|
|
));
|
2017-11-10 11:32:32 +11:00
|
|
|
}
|
2022-10-03 13:57:04 -05:00
|
|
|
let h = h.clone();
|
|
|
|
options.clang_args.push(h);
|
2017-11-10 11:32:32 +11:00
|
|
|
} else {
|
2023-02-07 10:13:48 -05:00
|
|
|
return Err(BindgenError::NotExist(path.into()));
|
2017-10-23 12:03:36 +11:00
|
|
|
}
|
2016-12-11 09:46:49 +01:00
|
|
|
}
|
|
|
|
|
2022-09-26 13:22:15 -05:00
|
|
|
for (idx, f) in input_unsaved_files.iter().enumerate() {
|
2022-10-03 13:57:04 -05:00
|
|
|
if idx != 0 || !options.input_headers.is_empty() {
|
2020-08-01 19:26:16 +03:00
|
|
|
options.clang_args.push("-include".to_owned());
|
|
|
|
}
|
2017-03-27 13:02:33 -04:00
|
|
|
options.clang_args.push(f.name.to_str().unwrap().to_owned())
|
|
|
|
}
|
|
|
|
|
2018-12-23 18:17:04 +01:00
|
|
|
debug!("Fixed-up options: {:?}", options);
|
|
|
|
|
2017-08-29 22:08:37 -05:00
|
|
|
let time_phases = options.time_phases;
|
2022-09-26 13:22:15 -05:00
|
|
|
let mut context = BindgenContext::new(options, &input_unsaved_files);
|
2017-08-22 18:53:55 -07:00
|
|
|
|
2020-08-23 20:37:53 +02:00
|
|
|
if is_host_build {
|
|
|
|
debug_assert_eq!(
|
|
|
|
context.target_pointer_size(),
|
|
|
|
std::mem::size_of::<*mut ()>(),
|
|
|
|
"{:?} {:?}",
|
|
|
|
effective_target,
|
|
|
|
HOST_TARGET
|
|
|
|
);
|
2020-08-14 11:29:08 +09:00
|
|
|
}
|
|
|
|
|
2017-08-29 22:08:37 -05:00
|
|
|
{
|
2019-09-17 09:44:06 +09:00
|
|
|
let _t = time::Timer::new("parse").with_output(time_phases);
|
2023-02-07 10:13:48 -05:00
|
|
|
parse(&mut context)?;
|
2017-08-29 22:08:37 -05:00
|
|
|
}
|
2014-12-23 20:46:13 +01:00
|
|
|
|
2023-02-07 10:13:48 -05:00
|
|
|
let (module, options, warnings) =
|
|
|
|
codegen::codegen(context).map_err(BindgenError::Codegen)?;
|
2022-08-24 18:45:03 -04:00
|
|
|
|
2023-02-07 10:13:48 -05:00
|
|
|
Ok(Bindings {
|
2020-08-23 20:37:53 +02:00
|
|
|
options,
|
2022-08-10 12:51:38 -05:00
|
|
|
warnings,
|
2022-09-06 15:30:29 -05:00
|
|
|
module,
|
2023-02-07 10:13:48 -05:00
|
|
|
})
|
2014-12-23 20:46:13 +01:00
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Write these bindings as source text to a file.
|
2015-05-06 12:27:56 +01:00
|
|
|
pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
2017-09-26 07:45:51 -04:00
|
|
|
let file = OpenOptions::new()
|
|
|
|
.write(true)
|
|
|
|
.truncate(true)
|
|
|
|
.create(true)
|
|
|
|
.open(path.as_ref())?;
|
|
|
|
self.write(Box::new(file))?;
|
|
|
|
Ok(())
|
2015-05-06 12:27:56 +01:00
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Write these bindings as source text to the given `Write`able.
|
2019-07-27 13:56:01 +02:00
|
|
|
pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()> {
|
2020-06-22 18:07:08 -07:00
|
|
|
if !self.options.disable_header_comment {
|
|
|
|
let version = option_env!("CARGO_PKG_VERSION");
|
|
|
|
let header = format!(
|
|
|
|
"/* automatically generated by rust-bindgen {} */\n\n",
|
|
|
|
version.unwrap_or("(unknown version)")
|
|
|
|
);
|
2020-08-08 21:57:41 +08:00
|
|
|
writer.write_all(header.as_bytes())?;
|
2020-06-22 18:07:08 -07:00
|
|
|
}
|
2016-04-03 01:03:06 +02:00
|
|
|
|
2017-10-12 12:02:47 -07:00
|
|
|
for line in self.options.raw_lines.iter() {
|
2020-08-08 21:57:41 +08:00
|
|
|
writer.write_all(line.as_bytes())?;
|
|
|
|
writer.write_all("\n".as_bytes())?;
|
2016-04-03 01:03:06 +02:00
|
|
|
}
|
2017-09-26 07:45:51 -04:00
|
|
|
|
2017-10-12 12:02:47 -07:00
|
|
|
if !self.options.raw_lines.is_empty() {
|
2020-08-08 21:57:41 +08:00
|
|
|
writer.write_all("\n".as_bytes())?;
|
2016-04-03 01:03:06 +02:00
|
|
|
}
|
|
|
|
|
2018-03-15 16:14:26 +01:00
|
|
|
let bindings = self.module.to_string();
|
2017-09-26 07:45:51 -04:00
|
|
|
|
2017-10-28 12:31:36 +02:00
|
|
|
match self.rustfmt_generated_string(&bindings) {
|
2017-09-26 07:45:51 -04:00
|
|
|
Ok(rustfmt_bindings) => {
|
2020-08-08 21:57:41 +08:00
|
|
|
writer.write_all(rustfmt_bindings.as_bytes())?;
|
2019-09-17 09:44:06 +09:00
|
|
|
}
|
2017-10-28 12:31:36 +02:00
|
|
|
Err(err) => {
|
2019-09-17 09:44:06 +09:00
|
|
|
eprintln!(
|
|
|
|
"Failed to run rustfmt: {} (non-fatal, continuing)",
|
|
|
|
err
|
|
|
|
);
|
2020-08-08 21:57:41 +08:00
|
|
|
writer.write_all(bindings.as_bytes())?;
|
2019-09-17 09:44:06 +09:00
|
|
|
}
|
2017-09-26 07:45:51 -04:00
|
|
|
}
|
2017-08-22 18:53:55 -07:00
|
|
|
Ok(())
|
2014-12-23 20:46:13 +01:00
|
|
|
}
|
2017-08-11 17:59:32 +02:00
|
|
|
|
2019-07-26 15:46:23 +02:00
|
|
|
/// Gets the rustfmt path to rustfmt the generated bindings.
|
2021-10-25 22:06:54 +09:00
|
|
|
fn rustfmt_path(&self) -> io::Result<Cow<PathBuf>> {
|
2019-07-26 15:46:23 +02:00
|
|
|
debug_assert!(self.options.rustfmt_bindings);
|
|
|
|
if let Some(ref p) = self.options.rustfmt_path {
|
2019-09-15 18:23:12 -07:00
|
|
|
return Ok(Cow::Borrowed(p));
|
2019-07-26 15:46:23 +02:00
|
|
|
}
|
|
|
|
if let Ok(rustfmt) = env::var("RUSTFMT") {
|
2019-09-15 18:23:12 -07:00
|
|
|
return Ok(Cow::Owned(rustfmt.into()));
|
2019-07-26 15:46:23 +02:00
|
|
|
}
|
2019-09-05 15:41:42 -07:00
|
|
|
#[cfg(feature = "which-rustfmt")]
|
2019-07-26 15:46:23 +02:00
|
|
|
match which::which("rustfmt") {
|
2019-09-15 18:23:12 -07:00
|
|
|
Ok(p) => Ok(Cow::Owned(p)),
|
2019-09-17 09:44:06 +09:00
|
|
|
Err(e) => {
|
|
|
|
Err(io::Error::new(io::ErrorKind::Other, format!("{}", e)))
|
|
|
|
}
|
2019-07-26 15:46:23 +02:00
|
|
|
}
|
2019-09-05 15:41:42 -07:00
|
|
|
#[cfg(not(feature = "which-rustfmt"))]
|
2019-09-27 19:00:21 +02:00
|
|
|
// No rustfmt binary was specified, so assume that the binary is called
|
|
|
|
// "rustfmt" and that it is in the user's PATH.
|
|
|
|
Ok(Cow::Owned("rustfmt".into()))
|
2019-07-26 15:46:23 +02:00
|
|
|
}
|
|
|
|
|
2017-09-26 07:45:51 -04:00
|
|
|
/// Checks if rustfmt_bindings is set and runs rustfmt on the string
|
2017-10-28 12:31:36 +02:00
|
|
|
fn rustfmt_generated_string<'a>(
|
|
|
|
&self,
|
|
|
|
source: &'a str,
|
|
|
|
) -> io::Result<Cow<'a, str>> {
|
2017-09-26 07:45:51 -04:00
|
|
|
let _t = time::Timer::new("rustfmt_generated_string")
|
2017-10-12 12:02:47 -07:00
|
|
|
.with_output(self.options.time_phases);
|
2017-08-31 14:52:51 -07:00
|
|
|
|
2017-10-12 12:02:47 -07:00
|
|
|
if !self.options.rustfmt_bindings {
|
2017-10-28 12:31:36 +02:00
|
|
|
return Ok(Cow::Borrowed(source));
|
2017-08-11 17:59:32 +02:00
|
|
|
}
|
|
|
|
|
2019-09-15 18:23:12 -07:00
|
|
|
let rustfmt = self.rustfmt_path()?;
|
2018-01-26 21:09:42 +01:00
|
|
|
let mut cmd = Command::new(&*rustfmt);
|
2017-08-11 17:59:32 +02:00
|
|
|
|
2019-09-17 09:44:06 +09:00
|
|
|
cmd.stdin(Stdio::piped()).stdout(Stdio::piped());
|
2017-08-11 17:59:32 +02:00
|
|
|
|
2019-09-17 09:44:06 +09:00
|
|
|
if let Some(path) = self
|
|
|
|
.options
|
2017-08-11 22:56:40 +02:00
|
|
|
.rustfmt_configuration_file
|
|
|
|
.as_ref()
|
|
|
|
.and_then(|f| f.to_str())
|
|
|
|
{
|
2022-10-03 13:02:03 -05:00
|
|
|
cmd.args(["--config-path", path]);
|
2017-08-11 17:59:32 +02:00
|
|
|
}
|
|
|
|
|
2017-10-28 12:31:36 +02:00
|
|
|
let mut child = cmd.spawn()?;
|
|
|
|
let mut child_stdin = child.stdin.take().unwrap();
|
|
|
|
let mut child_stdout = child.stdout.take().unwrap();
|
|
|
|
|
|
|
|
let source = source.to_owned();
|
|
|
|
|
|
|
|
// Write to stdin in a new thread, so that we can read from stdout on this
|
|
|
|
// thread. This keeps the child from blocking on writing to its stdout which
|
|
|
|
// might block us from writing to its stdin.
|
|
|
|
let stdin_handle = ::std::thread::spawn(move || {
|
|
|
|
let _ = child_stdin.write_all(source.as_bytes());
|
|
|
|
source
|
|
|
|
});
|
|
|
|
|
|
|
|
let mut output = vec![];
|
|
|
|
io::copy(&mut child_stdout, &mut output)?;
|
|
|
|
|
|
|
|
let status = child.wait()?;
|
2019-09-17 09:44:06 +09:00
|
|
|
let source = stdin_handle.join().expect(
|
|
|
|
"The thread writing to rustfmt's stdin doesn't do \
|
|
|
|
anything that could panic",
|
|
|
|
);
|
2017-10-28 12:31:36 +02:00
|
|
|
|
|
|
|
match String::from_utf8(output) {
|
2019-09-17 09:44:06 +09:00
|
|
|
Ok(bindings) => match status.code() {
|
|
|
|
Some(0) => Ok(Cow::Owned(bindings)),
|
|
|
|
Some(2) => Err(io::Error::new(
|
|
|
|
io::ErrorKind::Other,
|
|
|
|
"Rustfmt parsing errors.".to_string(),
|
|
|
|
)),
|
|
|
|
Some(3) => {
|
|
|
|
warn!("Rustfmt could not format some lines.");
|
|
|
|
Ok(Cow::Owned(bindings))
|
2017-08-11 22:56:40 +02:00
|
|
|
}
|
2019-09-17 09:44:06 +09:00
|
|
|
_ => Err(io::Error::new(
|
|
|
|
io::ErrorKind::Other,
|
|
|
|
"Internal rustfmt error".to_string(),
|
|
|
|
)),
|
2017-10-28 12:31:36 +02:00
|
|
|
},
|
2019-09-17 09:44:06 +09:00
|
|
|
_ => Ok(Cow::Owned(source)),
|
2017-08-11 17:59:32 +02:00
|
|
|
}
|
|
|
|
}
|
2022-08-10 12:51:38 -05:00
|
|
|
|
2022-08-16 11:24:06 -05:00
|
|
|
/// Emit all the warning messages raised while generating the bindings in a build script.
|
|
|
|
///
|
|
|
|
/// If you are using `bindgen` outside of a build script you should use [`Bindings::warnings`]
|
|
|
|
/// and handle the messages accordingly instead.
|
|
|
|
#[inline]
|
|
|
|
pub fn emit_warnings(&self) {
|
|
|
|
for message in &self.warnings {
|
|
|
|
println!("cargo:warning={}", message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return all the warning messages raised while generating the bindings.
|
2022-08-10 12:51:38 -05:00
|
|
|
#[inline]
|
2022-08-16 11:24:06 -05:00
|
|
|
pub fn warnings(&self) -> &[String] {
|
|
|
|
&self.warnings
|
2022-08-10 12:51:38 -05:00
|
|
|
}
|
2014-12-23 20:46:13 +01:00
|
|
|
}
|
|
|
|
|
2021-10-25 22:06:54 +09:00
|
|
|
impl std::fmt::Display for Bindings {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
let mut bytes = vec![];
|
|
|
|
self.write(Box::new(&mut bytes) as Box<dyn Write>)
|
|
|
|
.expect("writing to a vec cannot fail");
|
|
|
|
f.write_str(
|
|
|
|
std::str::from_utf8(&bytes)
|
|
|
|
.expect("we should only write bindings that are valid utf-8"),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
/// Determines whether the given cursor is in any of the files matched by the
|
|
|
|
/// options.
|
|
|
|
fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
|
2017-03-09 01:10:49 +01:00
|
|
|
ctx.options().builtins || !cursor.is_builtin()
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Parse one `Item` from the Clang cursor.
|
2017-10-12 12:01:21 -07:00
|
|
|
fn parse_one(
|
2017-08-04 17:15:41 +02:00
|
|
|
ctx: &mut BindgenContext,
|
|
|
|
cursor: clang::Cursor,
|
|
|
|
parent: Option<ItemId>,
|
|
|
|
) -> clang_sys::CXChildVisitResult {
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
if !filter_builtins(ctx, &cursor) {
|
2016-11-01 12:56:14 +01:00
|
|
|
return CXChildVisit_Continue;
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
|
2016-12-13 16:35:28 +01:00
|
|
|
use clang_sys::CXChildVisit_Continue;
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
match Item::parse(cursor, parent, ctx) {
|
2016-12-21 16:09:09 -08:00
|
|
|
Ok(..) => {}
|
2016-11-01 12:56:14 +01:00
|
|
|
Err(ParseError::Continue) => {}
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
Err(ParseError::Recurse) => {
|
2016-11-22 20:01:29 +01:00
|
|
|
cursor.visit(|child| parse_one(ctx, child, parent));
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CXChildVisit_Continue
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Parse the Clang AST into our `Item` internal representation.
|
2021-12-04 16:46:39 +09:00
|
|
|
fn parse(context: &mut BindgenContext) -> Result<(), BindgenError> {
|
2016-12-13 16:35:28 +01:00
|
|
|
use clang_sys::*;
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
|
2021-12-04 16:46:39 +09:00
|
|
|
let mut error = None;
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
for d in context.translation_unit().diags().iter() {
|
2016-12-13 16:35:28 +01:00
|
|
|
let msg = d.format();
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
let is_err = d.severity() >= CXDiagnostic_Error;
|
2021-12-04 16:46:39 +09:00
|
|
|
if is_err {
|
|
|
|
let error = error.get_or_insert_with(String::new);
|
|
|
|
error.push_str(&msg);
|
|
|
|
error.push('\n');
|
|
|
|
} else {
|
|
|
|
eprintln!("clang diag: {}", msg);
|
|
|
|
}
|
2016-12-10 18:19:25 -10:00
|
|
|
}
|
|
|
|
|
2021-12-04 16:46:39 +09:00
|
|
|
if let Some(message) = error {
|
|
|
|
return Err(BindgenError::ClangDiagnostic(message));
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
let cursor = context.translation_unit().cursor();
|
2017-03-30 12:26:02 +02:00
|
|
|
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
if context.options().emit_ast {
|
2017-03-30 12:26:02 +02:00
|
|
|
fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult {
|
|
|
|
if !cur.is_builtin() {
|
2021-10-25 22:06:54 +09:00
|
|
|
clang::ast_dump(cur, 0)
|
2017-03-30 12:26:02 +02:00
|
|
|
} else {
|
|
|
|
CXChildVisit_Continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cursor.visit(|cur| dump_if_not_builtin(&cur));
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
let root = context.root_module();
|
2016-11-22 20:01:29 +01:00
|
|
|
context.with_module(root, |context| {
|
|
|
|
cursor.visit(|cursor| parse_one(context, cursor, None))
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
});
|
|
|
|
|
2017-08-04 17:15:41 +02:00
|
|
|
assert!(
|
|
|
|
context.current_module() == context.root_module(),
|
|
|
|
"How did this happen?"
|
|
|
|
);
|
2016-12-10 18:19:25 -10:00
|
|
|
Ok(())
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
2016-11-01 17:10:55 -05:00
|
|
|
|
2016-11-01 23:31:42 -05:00
|
|
|
/// Extracted Clang version data
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ClangVersion {
|
2018-06-01 15:52:06 +02:00
|
|
|
/// Major and minor semver, if parsing was successful
|
2016-11-04 16:34:36 +01:00
|
|
|
pub parsed: Option<(u32, u32)>,
|
2016-11-01 23:31:42 -05:00
|
|
|
/// full version string
|
|
|
|
pub full: String,
|
|
|
|
}
|
|
|
|
|
2018-06-01 15:52:06 +02:00
|
|
|
/// Get the major and the minor semver numbers of Clang's version
|
2016-11-03 13:28:33 -05:00
|
|
|
pub fn clang_version() -> ClangVersion {
|
2019-09-15 23:09:22 -07:00
|
|
|
ensure_libclang_is_loaded();
|
2016-12-13 18:18:00 +01:00
|
|
|
|
2021-02-15 13:39:30 +01:00
|
|
|
//Debian clang version 11.0.1-2
|
2016-11-03 13:28:33 -05:00
|
|
|
let raw_v: String = clang::extract_clang_version();
|
2019-09-17 09:44:06 +09:00
|
|
|
let split_v: Option<Vec<&str>> = raw_v
|
|
|
|
.split_whitespace()
|
2021-10-25 22:06:54 +09:00
|
|
|
.find(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit()))
|
2019-09-17 09:44:06 +09:00
|
|
|
.map(|v| v.split('.').collect());
|
2021-10-25 22:06:54 +09:00
|
|
|
if let Some(v) = split_v {
|
|
|
|
if v.len() >= 2 {
|
|
|
|
let maybe_major = v[0].parse::<u32>();
|
|
|
|
let maybe_minor = v[1].parse::<u32>();
|
|
|
|
if let (Ok(major), Ok(minor)) = (maybe_major, maybe_minor) {
|
|
|
|
return ClangVersion {
|
|
|
|
parsed: Some((major, minor)),
|
|
|
|
full: raw_v.clone(),
|
|
|
|
};
|
2016-11-03 13:28:33 -05:00
|
|
|
}
|
2017-08-20 16:26:59 -06:00
|
|
|
}
|
2016-11-01 23:31:42 -05:00
|
|
|
};
|
2016-11-04 16:34:36 +01:00
|
|
|
ClangVersion {
|
|
|
|
parsed: None,
|
|
|
|
full: raw_v.clone(),
|
|
|
|
}
|
2016-11-01 17:10:55 -05:00
|
|
|
}
|
2017-04-13 08:15:11 +05:45
|
|
|
|
2021-04-14 15:17:02 +02:00
|
|
|
/// Looks for the env var `var_${TARGET}`, and falls back to just `var` when it is not found.
|
|
|
|
fn get_target_dependent_env_var(var: &str) -> Option<String> {
|
|
|
|
if let Ok(target) = env::var("TARGET") {
|
2022-11-02 13:32:32 -05:00
|
|
|
if let Ok(v) = env::var(format!("{}_{}", var, target)) {
|
2021-04-14 15:17:02 +02:00
|
|
|
return Some(v);
|
|
|
|
}
|
2022-11-02 13:32:32 -05:00
|
|
|
if let Ok(v) = env::var(format!("{}_{}", var, target.replace('-', "_")))
|
2021-04-14 15:17:02 +02:00
|
|
|
{
|
|
|
|
return Some(v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
env::var(var).ok()
|
|
|
|
}
|
|
|
|
|
2019-10-04 12:57:56 +02:00
|
|
|
/// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed
|
|
|
|
/// line
|
|
|
|
///
|
2021-11-08 09:07:47 +13:00
|
|
|
/// When running inside a `build.rs` script, this can be used to make cargo invalidate the
|
2019-10-04 12:57:56 +02:00
|
|
|
/// generated bindings whenever any of the files included from the header change:
|
|
|
|
/// ```
|
|
|
|
/// use bindgen::builder;
|
|
|
|
/// let bindings = builder()
|
|
|
|
/// .header("path/to/input/header")
|
|
|
|
/// .parse_callbacks(Box::new(bindgen::CargoCallbacks))
|
2021-12-08 09:10:05 +09:00
|
|
|
/// .generate();
|
2019-10-04 12:57:56 +02:00
|
|
|
/// ```
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct CargoCallbacks;
|
|
|
|
|
|
|
|
impl callbacks::ParseCallbacks for CargoCallbacks {
|
|
|
|
fn include_file(&self, filename: &str) {
|
|
|
|
println!("cargo:rerun-if-changed={}", filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-13 08:15:11 +05:45
|
|
|
/// Test command_line_flag function.
|
|
|
|
#[test]
|
|
|
|
fn commandline_flag_unit_test_function() {
|
|
|
|
//Test 1
|
2020-04-27 15:37:47 -04:00
|
|
|
let bindings = crate::builder();
|
2017-04-13 08:15:11 +05:45
|
|
|
let command_line_flags = bindings.command_line_flags();
|
|
|
|
|
2017-08-04 17:15:41 +02:00
|
|
|
let test_cases = vec![
|
2017-12-09 12:05:41 -05:00
|
|
|
"--rust-target",
|
2017-08-04 17:15:41 +02:00
|
|
|
"--no-derive-default",
|
|
|
|
"--generate",
|
2018-11-09 09:50:27 +00:00
|
|
|
"functions,types,vars,methods,constructors,destructors",
|
2019-09-17 09:44:06 +09:00
|
|
|
]
|
|
|
|
.iter()
|
|
|
|
.map(|&x| x.into())
|
|
|
|
.collect::<Vec<String>>();
|
2017-04-13 08:15:11 +05:45
|
|
|
|
2021-12-04 17:25:06 +09:00
|
|
|
assert!(test_cases.iter().all(|x| command_line_flags.contains(x)));
|
2017-04-13 08:15:11 +05:45
|
|
|
|
2017-04-14 14:37:09 -07:00
|
|
|
//Test 2
|
2020-04-27 15:37:47 -04:00
|
|
|
let bindings = crate::builder()
|
2017-08-04 17:15:41 +02:00
|
|
|
.header("input_header")
|
2021-02-11 08:58:46 +01:00
|
|
|
.allowlist_type("Distinct_Type")
|
|
|
|
.allowlist_function("safe_function");
|
2017-04-13 08:15:11 +05:45
|
|
|
|
|
|
|
let command_line_flags = bindings.command_line_flags();
|
2017-08-04 17:15:41 +02:00
|
|
|
let test_cases = vec![
|
2017-12-09 12:05:41 -05:00
|
|
|
"--rust-target",
|
2017-08-04 17:15:41 +02:00
|
|
|
"input_header",
|
|
|
|
"--no-derive-default",
|
|
|
|
"--generate",
|
2018-11-09 09:50:27 +00:00
|
|
|
"functions,types,vars,methods,constructors,destructors",
|
2021-02-11 08:58:46 +01:00
|
|
|
"--allowlist-type",
|
2017-08-04 17:15:41 +02:00
|
|
|
"Distinct_Type",
|
2021-02-11 08:58:46 +01:00
|
|
|
"--allowlist-function",
|
2017-08-04 17:15:41 +02:00
|
|
|
"safe_function",
|
2019-09-17 09:44:06 +09:00
|
|
|
]
|
|
|
|
.iter()
|
|
|
|
.map(|&x| x.into())
|
|
|
|
.collect::<Vec<String>>();
|
2017-04-13 08:15:11 +05:45
|
|
|
println!("{:?}", command_line_flags);
|
|
|
|
|
2021-12-04 17:25:06 +09:00
|
|
|
assert!(test_cases.iter().all(|x| command_line_flags.contains(x)));
|
2017-04-14 12:37:44 +01:00
|
|
|
}
|
2020-08-23 20:37:53 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_rust_to_clang_target() {
|
|
|
|
assert_eq!(rust_to_clang_target("aarch64-apple-ios"), "arm64-apple-ios");
|
|
|
|
}
|
2021-12-12 15:09:30 +11:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_rust_to_clang_target_riscv() {
|
|
|
|
assert_eq!(
|
|
|
|
rust_to_clang_target("riscv64gc-unknown-linux-gnu"),
|
|
|
|
"riscv64-unknown-linux-gnu"
|
|
|
|
)
|
|
|
|
}
|
2023-01-25 14:54:19 -08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_rust_to_clang_target_espidf() {
|
|
|
|
assert_eq!(
|
|
|
|
rust_to_clang_target("riscv32imc-esp-espidf"),
|
|
|
|
"riscv32-esp-elf"
|
|
|
|
);
|
|
|
|
assert_eq!(
|
|
|
|
rust_to_clang_target("xtensa-esp32-espidf"),
|
|
|
|
"xtensa-esp32-elf"
|
|
|
|
);
|
|
|
|
}
|