1 //! Generate Rust bindings for C and C++ libraries.
2 //!
3 //! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
4 //! functions and use types defined in the header.
5 //!
6 //! See the [`Builder`](./struct.Builder.html) struct for usage.
7 //!
8 //! See the [Users Guide](https://rust-lang.github.io/rust-bindgen/) for
9 //! additional documentation.
10 #![deny(missing_docs)]
11 #![deny(unused_extern_crates)]
12 // To avoid rather annoying warnings when matching with CXCursor_xxx as a
13 // constant.
14 #![allow(non_upper_case_globals)]
15 // `quote!` nests quite deeply.
16 #![recursion_limit = "128"]
17
18 #[macro_use]
19 extern crate bitflags;
20 #[macro_use]
21 extern crate lazy_static;
22 #[macro_use]
23 extern crate quote;
24
25 #[cfg(feature = "logging")]
26 #[macro_use]
27 extern crate log;
28
29 #[cfg(not(feature = "logging"))]
30 #[macro_use]
31 mod log_stubs;
32
33 #[macro_use]
34 mod extra_assertions;
35
36 // A macro to declare an internal module for which we *must* provide
37 // documentation for. If we are building with the "testing_only_docs" feature,
38 // then the module is declared public, and our `#![deny(missing_docs)]` pragma
39 // applies to it. This feature is used in CI, so we won't let anything slip by
40 // undocumented. Normal builds, however, will leave the module private, so that
41 // we don't expose internals to library consumers.
42 macro_rules! doc_mod {
43 ($m:ident, $doc_mod_name:ident) => {
44 #[cfg(feature = "testing_only_docs")]
45 pub mod $doc_mod_name {
46 //! Autogenerated documentation module.
47 pub use super::$m::*;
48 }
49 };
50 }
51
52 mod clang;
53 mod codegen;
54 mod features;
55 mod ir;
56 mod parse;
57 mod regex_set;
58 mod time;
59
60 pub mod callbacks;
61
62 doc_mod!(clang, clang_docs);
63 doc_mod!(features, features_docs);
64 doc_mod!(ir, ir_docs);
65 doc_mod!(parse, parse_docs);
66 doc_mod!(regex_set, regex_set_docs);
67
68 pub use crate::codegen::{AliasVariation, EnumVariation, MacroTypeVariation};
69 use crate::features::RustFeatures;
70 pub use crate::features::{
71 RustTarget, LATEST_STABLE_RUST, RUST_TARGET_STRINGS,
72 };
73 use crate::ir::context::{BindgenContext, ItemId};
74 use crate::ir::item::Item;
75 use crate::parse::{ClangItemParser, ParseError};
76 use crate::regex_set::RegexSet;
77
78 use std::borrow::Cow;
79 use std::fs::{File, OpenOptions};
80 use std::io::{self, Write};
81 use std::path::{Path, PathBuf};
82 use std::process::{Command, Stdio};
83 use std::{env, iter};
84
85 // Some convenient typedefs for a fast hash map and hash set.
86 type HashMap<K, V> = ::rustc_hash::FxHashMap<K, V>;
87 type HashSet<K> = ::rustc_hash::FxHashSet<K>;
88 pub(crate) use std::collections::hash_map::Entry;
89
90 /// Default prefix for the anon fields.
91 pub const DEFAULT_ANON_FIELDS_PREFIX: &'static str = "__bindgen_anon_";
92
file_is_cpp(name_file: &str) -> bool93 fn file_is_cpp(name_file: &str) -> bool {
94 name_file.ends_with(".hpp") ||
95 name_file.ends_with(".hxx") ||
96 name_file.ends_with(".hh") ||
97 name_file.ends_with(".h++")
98 }
99
args_are_cpp(clang_args: &[String]) -> bool100 fn args_are_cpp(clang_args: &[String]) -> bool {
101 for w in clang_args.windows(2) {
102 if w[0] == "-xc++" || w[1] == "-xc++" {
103 return true;
104 }
105 if w[0] == "-x" && w[1] == "c++" {
106 return true;
107 }
108 if w[0] == "-include" && file_is_cpp(&w[1]) {
109 return true;
110 }
111 }
112 false
113 }
114
115 bitflags! {
116 /// A type used to indicate which kind of items we have to generate.
117 pub struct CodegenConfig: u32 {
118 /// Whether to generate functions.
119 const FUNCTIONS = 1 << 0;
120 /// Whether to generate types.
121 const TYPES = 1 << 1;
122 /// Whether to generate constants.
123 const VARS = 1 << 2;
124 /// Whether to generate methods.
125 const METHODS = 1 << 3;
126 /// Whether to generate constructors
127 const CONSTRUCTORS = 1 << 4;
128 /// Whether to generate destructors.
129 const DESTRUCTORS = 1 << 5;
130 }
131 }
132
133 impl CodegenConfig {
134 /// Returns true if functions should be generated.
functions(self) -> bool135 pub fn functions(self) -> bool {
136 self.contains(CodegenConfig::FUNCTIONS)
137 }
138
139 /// Returns true if types should be generated.
types(self) -> bool140 pub fn types(self) -> bool {
141 self.contains(CodegenConfig::TYPES)
142 }
143
144 /// Returns true if constants should be generated.
vars(self) -> bool145 pub fn vars(self) -> bool {
146 self.contains(CodegenConfig::VARS)
147 }
148
149 /// Returns true if methds should be generated.
methods(self) -> bool150 pub fn methods(self) -> bool {
151 self.contains(CodegenConfig::METHODS)
152 }
153
154 /// Returns true if constructors should be generated.
constructors(self) -> bool155 pub fn constructors(self) -> bool {
156 self.contains(CodegenConfig::CONSTRUCTORS)
157 }
158
159 /// Returns true if destructors should be generated.
destructors(self) -> bool160 pub fn destructors(self) -> bool {
161 self.contains(CodegenConfig::DESTRUCTORS)
162 }
163 }
164
165 impl Default for CodegenConfig {
default() -> Self166 fn default() -> Self {
167 CodegenConfig::all()
168 }
169 }
170
171 /// Configure and generate Rust bindings for a C/C++ header.
172 ///
173 /// This is the main entry point to the library.
174 ///
175 /// ```ignore
176 /// use bindgen::builder;
177 ///
178 /// // Configure and generate bindings.
179 /// let bindings = builder().header("path/to/input/header")
180 /// .allowlist_type("SomeCoolClass")
181 /// .allowlist_function("do_some_cool_thing")
182 /// .generate()?;
183 ///
184 /// // Write the generated bindings to an output file.
185 /// bindings.write_to_file("path/to/output.rs")?;
186 /// ```
187 ///
188 /// # Enums
189 ///
190 /// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on
191 /// the pattern passed to several methods:
192 ///
193 /// 1. [`constified_enum_module()`](#method.constified_enum_module)
194 /// 2. [`bitfield_enum()`](#method.bitfield_enum)
195 /// 3. [`newtype_enum()`](#method.newtype_enum)
196 /// 4. [`rustified_enum()`](#method.rustified_enum)
197 ///
198 /// For each C enum, bindgen tries to match the pattern in the following order:
199 ///
200 /// 1. Constified enum module
201 /// 2. Bitfield enum
202 /// 3. Newtype enum
203 /// 4. Rustified enum
204 ///
205 /// If none of the above patterns match, then bindgen will generate a set of Rust constants.
206 ///
207 /// # Clang arguments
208 ///
209 /// Extra arguments can be passed to with clang:
210 /// 1. [`clang_arg()`](#method.clang_arg): takes a single argument
211 /// 2. [`clang_args()`](#method.clang_args): takes an iterator of arguments
212 /// 3. `BINDGEN_EXTRA_CLANG_ARGS` environment variable: whitespace separate
213 /// environment variable of arguments
214 ///
215 /// Clang arguments specific to your crate should be added via the
216 /// `clang_arg()`/`clang_args()` methods.
217 ///
218 /// End-users of the crate may need to set the `BINDGEN_EXTRA_CLANG_ARGS` environment variable to
219 /// add additional arguments. For example, to build against a different sysroot a user could set
220 /// `BINDGEN_EXTRA_CLANG_ARGS` to `--sysroot=/path/to/sysroot`.
221 #[derive(Debug, Default)]
222 pub struct Builder {
223 options: BindgenOptions,
224 input_headers: Vec<String>,
225 // Tuples of unsaved file contents of the form (name, contents).
226 input_header_contents: Vec<(String, String)>,
227 }
228
229 /// Construct a new [`Builder`](./struct.Builder.html).
builder() -> Builder230 pub fn builder() -> Builder {
231 Default::default()
232 }
233
234 impl Builder {
235 /// Generates the command line flags use for creating `Builder`.
command_line_flags(&self) -> Vec<String>236 pub fn command_line_flags(&self) -> Vec<String> {
237 let mut output_vector: Vec<String> = Vec::new();
238
239 if let Some(header) = self.input_headers.last().cloned() {
240 // Positional argument 'header'
241 output_vector.push(header);
242 }
243
244 output_vector.push("--rust-target".into());
245 output_vector.push(self.options.rust_target.into());
246
247 // FIXME(emilio): This is a bit hacky, maybe we should stop re-using the
248 // RustFeatures to store the "disable_untagged_union" call, and make it
249 // a different flag that we check elsewhere / in generate().
250 if !self.options.rust_features.untagged_union &&
251 RustFeatures::from(self.options.rust_target).untagged_union
252 {
253 output_vector.push("--disable-untagged-union".into());
254 }
255
256 if self.options.default_enum_style != Default::default() {
257 output_vector.push("--default-enum-style".into());
258 output_vector.push(
259 match self.options.default_enum_style {
260 codegen::EnumVariation::Rust {
261 non_exhaustive: false,
262 } => "rust",
263 codegen::EnumVariation::Rust {
264 non_exhaustive: true,
265 } => "rust_non_exhaustive",
266 codegen::EnumVariation::NewType { is_bitfield: true } => {
267 "bitfield"
268 }
269 codegen::EnumVariation::NewType { is_bitfield: false } => {
270 "newtype"
271 }
272 codegen::EnumVariation::Consts => "consts",
273 codegen::EnumVariation::ModuleConsts => "moduleconsts",
274 }
275 .into(),
276 )
277 }
278
279 if self.options.default_macro_constant_type != Default::default() {
280 output_vector.push("--default-macro-constant-type".into());
281 output_vector
282 .push(self.options.default_macro_constant_type.as_str().into());
283 }
284
285 if self.options.default_alias_style != Default::default() {
286 output_vector.push("--default-alias-style".into());
287 output_vector
288 .push(self.options.default_alias_style.as_str().into());
289 }
290
291 let regex_sets = &[
292 (&self.options.bitfield_enums, "--bitfield-enum"),
293 (&self.options.newtype_enums, "--newtype-enum"),
294 (&self.options.rustified_enums, "--rustified-enum"),
295 (
296 &self.options.rustified_non_exhaustive_enums,
297 "--rustified-enum-non-exhaustive",
298 ),
299 (
300 &self.options.constified_enum_modules,
301 "--constified-enum-module",
302 ),
303 (&self.options.constified_enums, "--constified-enum"),
304 (&self.options.type_alias, "--type-alias"),
305 (&self.options.new_type_alias, "--new-type-alias"),
306 (&self.options.new_type_alias_deref, "--new-type-alias-deref"),
307 (&self.options.blocklisted_types, "--blocklist-type"),
308 (&self.options.blocklisted_functions, "--blocklist-function"),
309 (&self.options.blocklisted_items, "--blocklist-item"),
310 (&self.options.opaque_types, "--opaque-type"),
311 (&self.options.allowlisted_functions, "--allowlist-function"),
312 (&self.options.allowlisted_types, "--allowlist-type"),
313 (&self.options.allowlisted_vars, "--allowlist-var"),
314 (&self.options.no_partialeq_types, "--no-partialeq"),
315 (&self.options.no_copy_types, "--no-copy"),
316 (&self.options.no_debug_types, "--no-debug"),
317 (&self.options.no_default_types, "--no-default"),
318 (&self.options.no_hash_types, "--no-hash"),
319 ];
320
321 for (set, flag) in regex_sets {
322 for item in set.get_items() {
323 output_vector.push((*flag).to_owned());
324 output_vector.push(item.to_owned());
325 }
326 }
327
328 if !self.options.layout_tests {
329 output_vector.push("--no-layout-tests".into());
330 }
331
332 if self.options.impl_debug {
333 output_vector.push("--impl-debug".into());
334 }
335
336 if self.options.impl_partialeq {
337 output_vector.push("--impl-partialeq".into());
338 }
339
340 if !self.options.derive_copy {
341 output_vector.push("--no-derive-copy".into());
342 }
343
344 if !self.options.derive_debug {
345 output_vector.push("--no-derive-debug".into());
346 }
347
348 if !self.options.derive_default {
349 output_vector.push("--no-derive-default".into());
350 } else {
351 output_vector.push("--with-derive-default".into());
352 }
353
354 if self.options.derive_hash {
355 output_vector.push("--with-derive-hash".into());
356 }
357
358 if self.options.derive_partialord {
359 output_vector.push("--with-derive-partialord".into());
360 }
361
362 if self.options.derive_ord {
363 output_vector.push("--with-derive-ord".into());
364 }
365
366 if self.options.derive_partialeq {
367 output_vector.push("--with-derive-partialeq".into());
368 }
369
370 if self.options.derive_eq {
371 output_vector.push("--with-derive-eq".into());
372 }
373
374 if self.options.time_phases {
375 output_vector.push("--time-phases".into());
376 }
377
378 if !self.options.generate_comments {
379 output_vector.push("--no-doc-comments".into());
380 }
381
382 if !self.options.allowlist_recursively {
383 output_vector.push("--no-recursive-allowlist".into());
384 }
385
386 if self.options.objc_extern_crate {
387 output_vector.push("--objc-extern-crate".into());
388 }
389
390 if self.options.generate_block {
391 output_vector.push("--generate-block".into());
392 }
393
394 if self.options.block_extern_crate {
395 output_vector.push("--block-extern-crate".into());
396 }
397
398 if self.options.builtins {
399 output_vector.push("--builtins".into());
400 }
401
402 if let Some(ref prefix) = self.options.ctypes_prefix {
403 output_vector.push("--ctypes-prefix".into());
404 output_vector.push(prefix.clone());
405 }
406
407 if self.options.anon_fields_prefix != DEFAULT_ANON_FIELDS_PREFIX {
408 output_vector.push("--anon-fields-prefix".into());
409 output_vector.push(self.options.anon_fields_prefix.clone());
410 }
411
412 if self.options.emit_ast {
413 output_vector.push("--emit-clang-ast".into());
414 }
415
416 if self.options.emit_ir {
417 output_vector.push("--emit-ir".into());
418 }
419 if let Some(ref graph) = self.options.emit_ir_graphviz {
420 output_vector.push("--emit-ir-graphviz".into());
421 output_vector.push(graph.clone())
422 }
423 if self.options.enable_cxx_namespaces {
424 output_vector.push("--enable-cxx-namespaces".into());
425 }
426 if self.options.enable_function_attribute_detection {
427 output_vector.push("--enable-function-attribute-detection".into());
428 }
429 if self.options.disable_name_namespacing {
430 output_vector.push("--disable-name-namespacing".into());
431 }
432 if self.options.disable_nested_struct_naming {
433 output_vector.push("--disable-nested-struct-naming".into());
434 }
435
436 if self.options.disable_header_comment {
437 output_vector.push("--disable-header-comment".into());
438 }
439
440 if !self.options.codegen_config.functions() {
441 output_vector.push("--ignore-functions".into());
442 }
443
444 output_vector.push("--generate".into());
445
446 //Temporary placeholder for below 4 options
447 let mut options: Vec<String> = Vec::new();
448 if self.options.codegen_config.functions() {
449 options.push("functions".into());
450 }
451 if self.options.codegen_config.types() {
452 options.push("types".into());
453 }
454 if self.options.codegen_config.vars() {
455 options.push("vars".into());
456 }
457 if self.options.codegen_config.methods() {
458 options.push("methods".into());
459 }
460 if self.options.codegen_config.constructors() {
461 options.push("constructors".into());
462 }
463 if self.options.codegen_config.destructors() {
464 options.push("destructors".into());
465 }
466
467 output_vector.push(options.join(","));
468
469 if !self.options.codegen_config.methods() {
470 output_vector.push("--ignore-methods".into());
471 }
472
473 if !self.options.convert_floats {
474 output_vector.push("--no-convert-floats".into());
475 }
476
477 if !self.options.prepend_enum_name {
478 output_vector.push("--no-prepend-enum-name".into());
479 }
480
481 if self.options.fit_macro_constants {
482 output_vector.push("--fit-macro-constant-types".into());
483 }
484
485 if self.options.array_pointers_in_arguments {
486 output_vector.push("--use-array-pointers-in-arguments".into());
487 }
488
489 if let Some(ref wasm_import_module_name) =
490 self.options.wasm_import_module_name
491 {
492 output_vector.push("--wasm-import-module-name".into());
493 output_vector.push(wasm_import_module_name.clone());
494 }
495
496 for line in &self.options.raw_lines {
497 output_vector.push("--raw-line".into());
498 output_vector.push(line.clone());
499 }
500
501 for (module, lines) in &self.options.module_lines {
502 for line in lines.iter() {
503 output_vector.push("--module-raw-line".into());
504 output_vector.push(module.clone());
505 output_vector.push(line.clone());
506 }
507 }
508
509 if self.options.use_core {
510 output_vector.push("--use-core".into());
511 }
512
513 if self.options.conservative_inline_namespaces {
514 output_vector.push("--conservative-inline-namespaces".into());
515 }
516
517 if self.options.generate_inline_functions {
518 output_vector.push("--generate-inline-functions".into());
519 }
520
521 if !self.options.record_matches {
522 output_vector.push("--no-record-matches".into());
523 }
524
525 if self.options.size_t_is_usize {
526 output_vector.push("--size_t-is-usize".into());
527 }
528
529 if !self.options.rustfmt_bindings {
530 output_vector.push("--no-rustfmt-bindings".into());
531 }
532
533 if let Some(path) = self
534 .options
535 .rustfmt_configuration_file
536 .as_ref()
537 .and_then(|f| f.to_str())
538 {
539 output_vector.push("--rustfmt-configuration-file".into());
540 output_vector.push(path.into());
541 }
542
543 if let Some(ref name) = self.options.dynamic_library_name {
544 output_vector.push("--dynamic-loading".into());
545 output_vector.push(name.clone());
546 }
547
548 if self.options.dynamic_link_require_all {
549 output_vector.push("--dynamic-link-require-all".into());
550 }
551
552 if self.options.respect_cxx_access_specs {
553 output_vector.push("--respect-cxx-access-specs".into());
554 }
555
556 if self.options.translate_enum_integer_types {
557 output_vector.push("--translate-enum-integer-types".into());
558 }
559
560 // Add clang arguments
561
562 output_vector.push("--".into());
563
564 if !self.options.clang_args.is_empty() {
565 output_vector.extend(self.options.clang_args.iter().cloned());
566 }
567
568 if self.input_headers.len() > 1 {
569 // To pass more than one header, we need to pass all but the last
570 // header via the `-include` clang arg
571 for header in &self.input_headers[..self.input_headers.len() - 1] {
572 output_vector.push("-include".to_string());
573 output_vector.push(header.clone());
574 }
575 }
576
577 output_vector
578 }
579
580 /// Add an input C/C++ header to generate bindings for.
581 ///
582 /// This can be used to generate bindings to a single header:
583 ///
584 /// ```ignore
585 /// let bindings = bindgen::Builder::default()
586 /// .header("input.h")
587 /// .generate()
588 /// .unwrap();
589 /// ```
590 ///
591 /// Or you can invoke it multiple times to generate bindings to multiple
592 /// headers:
593 ///
594 /// ```ignore
595 /// let bindings = bindgen::Builder::default()
596 /// .header("first.h")
597 /// .header("second.h")
598 /// .header("third.h")
599 /// .generate()
600 /// .unwrap();
601 /// ```
header<T: Into<String>>(mut self, header: T) -> Builder602 pub fn header<T: Into<String>>(mut self, header: T) -> Builder {
603 self.input_headers.push(header.into());
604 self
605 }
606
607 /// Add `contents` as an input C/C++ header named `name`.
608 ///
609 /// The file `name` will be added to the clang arguments.
header_contents(mut self, name: &str, contents: &str) -> Builder610 pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
611 // Apparently clang relies on having virtual FS correspondent to
612 // the real one, so we need absolute paths here
613 let absolute_path = env::current_dir()
614 .expect("Cannot retrieve current directory")
615 .join(name)
616 .to_str()
617 .expect("Cannot convert current directory name to string")
618 .to_owned();
619 self.input_header_contents
620 .push((absolute_path, contents.into()));
621 self
622 }
623
624 /// Specify the rust target
625 ///
626 /// The default is the latest stable Rust version
rust_target(mut self, rust_target: RustTarget) -> Self627 pub fn rust_target(mut self, rust_target: RustTarget) -> Self {
628 self.options.set_rust_target(rust_target);
629 self
630 }
631
632 /// Disable support for native Rust unions, if supported.
disable_untagged_union(mut self) -> Self633 pub fn disable_untagged_union(mut self) -> Self {
634 self.options.rust_features.untagged_union = false;
635 self
636 }
637
638 /// Disable insertion of bindgen's version identifier into generated
639 /// bindings.
disable_header_comment(mut self) -> Self640 pub fn disable_header_comment(mut self) -> Self {
641 self.options.disable_header_comment = true;
642 self
643 }
644
645 /// Set the output graphviz file.
emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder646 pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
647 let path = path.into();
648 self.options.emit_ir_graphviz = Some(path);
649 self
650 }
651
652 /// Whether the generated bindings should contain documentation comments
653 /// (docstrings) or not. This is set to true by default.
654 ///
655 /// Note that clang by default excludes comments from system headers, pass
656 /// `-fretain-comments-from-system-headers` as
657 /// [`clang_arg`][Builder::clang_arg] to include them. It can also be told
658 /// to process all comments (not just documentation ones) using the
659 /// `-fparse-all-comments` flag. See [slides on clang comment parsing](
660 /// https://llvm.org/devmtg/2012-11/Gribenko_CommentParsing.pdf) for
661 /// background and examples.
generate_comments(mut self, doit: bool) -> Self662 pub fn generate_comments(mut self, doit: bool) -> Self {
663 self.options.generate_comments = doit;
664 self
665 }
666
667 /// Whether to allowlist recursively or not. Defaults to true.
668 ///
669 /// Given that we have explicitly allowlisted the "initiate_dance_party"
670 /// function in this C header:
671 ///
672 /// ```c
673 /// typedef struct MoonBoots {
674 /// int bouncy_level;
675 /// } MoonBoots;
676 ///
677 /// void initiate_dance_party(MoonBoots* boots);
678 /// ```
679 ///
680 /// We would normally generate bindings to both the `initiate_dance_party`
681 /// function and the `MoonBoots` struct that it transitively references. By
682 /// configuring with `allowlist_recursively(false)`, `bindgen` will not emit
683 /// bindings for anything except the explicitly allowlisted items, and there
684 /// would be no emitted struct definition for `MoonBoots`. However, the
685 /// `initiate_dance_party` function would still reference `MoonBoots`!
686 ///
687 /// **Disabling this feature will almost certainly cause `bindgen` to emit
688 /// bindings that will not compile!** If you disable this feature, then it
689 /// is *your* responsibility to provide definitions for every type that is
690 /// referenced from an explicitly allowlisted item. One way to provide the
691 /// definitions is by using the [`Builder::raw_line`](#method.raw_line)
692 /// method, another would be to define them in Rust and then `include!(...)`
693 /// the bindings immediately afterwards.
allowlist_recursively(mut self, doit: bool) -> Self694 pub fn allowlist_recursively(mut self, doit: bool) -> Self {
695 self.options.allowlist_recursively = doit;
696 self
697 }
698
699 /// Deprecated alias for allowlist_recursively.
700 #[deprecated(note = "Use allowlist_recursively instead")]
whitelist_recursively(self, doit: bool) -> Self701 pub fn whitelist_recursively(self, doit: bool) -> Self {
702 self.allowlist_recursively(doit)
703 }
704
705 /// Generate `#[macro_use] extern crate objc;` instead of `use objc;`
706 /// in the prologue of the files generated from objective-c files
objc_extern_crate(mut self, doit: bool) -> Self707 pub fn objc_extern_crate(mut self, doit: bool) -> Self {
708 self.options.objc_extern_crate = doit;
709 self
710 }
711
712 /// Generate proper block signatures instead of void pointers.
generate_block(mut self, doit: bool) -> Self713 pub fn generate_block(mut self, doit: bool) -> Self {
714 self.options.generate_block = doit;
715 self
716 }
717
718 /// Generate `#[macro_use] extern crate block;` instead of `use block;`
719 /// in the prologue of the files generated from apple block files
block_extern_crate(mut self, doit: bool) -> Self720 pub fn block_extern_crate(mut self, doit: bool) -> Self {
721 self.options.block_extern_crate = doit;
722 self
723 }
724
725 /// Whether to use the clang-provided name mangling. This is true by default
726 /// and probably needed for C++ features.
727 ///
728 /// However, some old libclang versions seem to return incorrect results in
729 /// some cases for non-mangled functions, see [1], so we allow disabling it.
730 ///
731 /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
trust_clang_mangling(mut self, doit: bool) -> Self732 pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
733 self.options.enable_mangling = doit;
734 self
735 }
736
737 /// Hide the given type from the generated bindings. Regular expressions are
738 /// supported.
739 #[deprecated(note = "Use blocklist_type instead")]
hide_type<T: AsRef<str>>(self, arg: T) -> Builder740 pub fn hide_type<T: AsRef<str>>(self, arg: T) -> Builder {
741 self.blocklist_type(arg)
742 }
743
744 /// Hide the given type from the generated bindings. Regular expressions are
745 /// supported.
746 #[deprecated(note = "Use blocklist_type instead")]
blacklist_type<T: AsRef<str>>(self, arg: T) -> Builder747 pub fn blacklist_type<T: AsRef<str>>(self, arg: T) -> Builder {
748 self.blocklist_type(arg)
749 }
750
751 /// Hide the given type from the generated bindings. Regular expressions are
752 /// supported.
753 ///
754 /// To blocklist types prefixed with "mylib" use `"mylib_.*"`.
755 /// For more complicated expressions check
756 /// [regex](https://docs.rs/regex/*/regex/) docs
blocklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder757 pub fn blocklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
758 self.options.blocklisted_types.insert(arg);
759 self
760 }
761
762 /// Hide the given function from the generated bindings. Regular expressions
763 /// are supported.
764 #[deprecated(note = "Use blocklist_function instead")]
blacklist_function<T: AsRef<str>>(self, arg: T) -> Builder765 pub fn blacklist_function<T: AsRef<str>>(self, arg: T) -> Builder {
766 self.blocklist_function(arg)
767 }
768
769 /// Hide the given function from the generated bindings. Regular expressions
770 /// are supported.
771 ///
772 /// To blocklist functions prefixed with "mylib" use `"mylib_.*"`.
773 /// For more complicated expressions check
774 /// [regex](https://docs.rs/regex/*/regex/) docs
blocklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder775 pub fn blocklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
776 self.options.blocklisted_functions.insert(arg);
777 self
778 }
779
780 /// Hide the given item from the generated bindings, regardless of
781 /// whether it's a type, function, module, etc. Regular
782 /// expressions are supported.
783 #[deprecated(note = "Use blocklist_item instead")]
blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder784 pub fn blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
785 self.options.blocklisted_items.insert(arg);
786 self
787 }
788
789 /// Hide the given item from the generated bindings, regardless of
790 /// whether it's a type, function, module, etc. Regular
791 /// expressions are supported.
792 ///
793 /// To blocklist items prefixed with "mylib" use `"mylib_.*"`.
794 /// For more complicated expressions check
795 /// [regex](https://docs.rs/regex/*/regex/) docs
blocklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder796 pub fn blocklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
797 self.options.blocklisted_items.insert(arg);
798 self
799 }
800
801 /// Treat the given type as opaque in the generated bindings. Regular
802 /// expressions are supported.
803 ///
804 /// To change types prefixed with "mylib" into opaque, use `"mylib_.*"`.
805 /// For more complicated expressions check
806 /// [regex](https://docs.rs/regex/*/regex/) docs
opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder807 pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
808 self.options.opaque_types.insert(arg);
809 self
810 }
811
812 /// Allowlist the given type so that it (and all types that it transitively
813 /// refers to) appears in the generated bindings. Regular expressions are
814 /// supported.
815 #[deprecated(note = "use allowlist_type instead")]
whitelisted_type<T: AsRef<str>>(self, arg: T) -> Builder816 pub fn whitelisted_type<T: AsRef<str>>(self, arg: T) -> Builder {
817 self.allowlist_type(arg)
818 }
819
820 /// Allowlist the given type so that it (and all types that it transitively
821 /// refers to) appears in the generated bindings. Regular expressions are
822 /// supported.
823 #[deprecated(note = "use allowlist_type instead")]
whitelist_type<T: AsRef<str>>(self, arg: T) -> Builder824 pub fn whitelist_type<T: AsRef<str>>(self, arg: T) -> Builder {
825 self.allowlist_type(arg)
826 }
827
828 /// Allowlist the given type so that it (and all types that it transitively
829 /// refers to) appears in the generated bindings. Regular expressions are
830 /// supported.
831 ///
832 /// To allowlist types prefixed with "mylib" use `"mylib_.*"`.
833 /// For more complicated expressions check
834 /// [regex](https://docs.rs/regex/*/regex/) docs
allowlist_type<T: AsRef<str>>(mut self, arg: T) -> Builder835 pub fn allowlist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
836 self.options.allowlisted_types.insert(arg);
837 self
838 }
839
840 /// Allowlist the given function so that it (and all types that it
841 /// transitively refers to) appears in the generated bindings. Regular
842 /// expressions are supported.
843 ///
844 /// To allowlist functions prefixed with "mylib" use `"mylib_.*"`.
845 /// For more complicated expressions check
846 /// [regex](https://docs.rs/regex/*/regex/) docs
allowlist_function<T: AsRef<str>>(mut self, arg: T) -> Builder847 pub fn allowlist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
848 self.options.allowlisted_functions.insert(arg);
849 self
850 }
851
852 /// Allowlist the given function.
853 ///
854 /// Deprecated: use allowlist_function instead.
855 #[deprecated(note = "use allowlist_function instead")]
whitelist_function<T: AsRef<str>>(self, arg: T) -> Builder856 pub fn whitelist_function<T: AsRef<str>>(self, arg: T) -> Builder {
857 self.allowlist_function(arg)
858 }
859
860 /// Allowlist the given function.
861 ///
862 /// Deprecated: use allowlist_function instead.
863 #[deprecated(note = "use allowlist_function instead")]
whitelisted_function<T: AsRef<str>>(self, arg: T) -> Builder864 pub fn whitelisted_function<T: AsRef<str>>(self, arg: T) -> Builder {
865 self.allowlist_function(arg)
866 }
867
868 /// Allowlist the given variable so that it (and all types that it
869 /// transitively refers to) appears in the generated bindings. Regular
870 /// expressions are supported.
871 ///
872 /// To allowlist variables prefixed with "mylib" use `"mylib_.*"`.
873 /// For more complicated expressions check
874 /// [regex](https://docs.rs/regex/*/regex/) docs
allowlist_var<T: AsRef<str>>(mut self, arg: T) -> Builder875 pub fn allowlist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
876 self.options.allowlisted_vars.insert(arg);
877 self
878 }
879
880 /// Deprecated: use allowlist_var instead.
881 #[deprecated(note = "use allowlist_var instead")]
whitelist_var<T: AsRef<str>>(self, arg: T) -> Builder882 pub fn whitelist_var<T: AsRef<str>>(self, arg: T) -> Builder {
883 self.allowlist_var(arg)
884 }
885
886 /// Allowlist the given variable.
887 ///
888 /// Deprecated: use allowlist_var instead.
889 #[deprecated(note = "use allowlist_var instead")]
whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder890 pub fn whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder {
891 self.allowlist_var(arg)
892 }
893
894 /// Set the default style of code to generate for enums
default_enum_style( mut self, arg: codegen::EnumVariation, ) -> Builder895 pub fn default_enum_style(
896 mut self,
897 arg: codegen::EnumVariation,
898 ) -> Builder {
899 self.options.default_enum_style = arg;
900 self
901 }
902
903 /// Mark the given enum (or set of enums, if using a pattern) as being
904 /// bitfield-like. Regular expressions are supported.
905 ///
906 /// This makes bindgen generate a type that isn't a rust `enum`. Regular
907 /// expressions are supported.
908 ///
909 /// This is similar to the newtype enum style, but with the bitwise
910 /// operators implemented.
bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder911 pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
912 self.options.bitfield_enums.insert(arg);
913 self
914 }
915
916 /// Mark the given enum (or set of enums, if using a pattern) as a newtype.
917 /// Regular expressions are supported.
918 ///
919 /// This makes bindgen generate a type that isn't a Rust `enum`. Regular
920 /// expressions are supported.
newtype_enum<T: AsRef<str>>(mut self, arg: T) -> Builder921 pub fn newtype_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
922 self.options.newtype_enums.insert(arg);
923 self
924 }
925
926 /// Mark the given enum (or set of enums, if using a pattern) as a Rust
927 /// enum.
928 ///
929 /// This makes bindgen generate enums instead of constants. Regular
930 /// expressions are supported.
931 ///
932 /// **Use this with caution**, creating this in unsafe code
933 /// (including FFI) with an invalid value will invoke undefined behaviour.
934 /// You may want to use the newtype enum style instead.
rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder935 pub fn rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
936 self.options.rustified_enums.insert(arg);
937 self
938 }
939
940 /// Mark the given enum (or set of enums, if using a pattern) as a Rust
941 /// enum with the `#[non_exhaustive]` attribute.
942 ///
943 /// This makes bindgen generate enums instead of constants. Regular
944 /// expressions are supported.
945 ///
946 /// **Use this with caution**, creating this in unsafe code
947 /// (including FFI) with an invalid value will invoke undefined behaviour.
948 /// You may want to use the newtype enum style instead.
rustified_non_exhaustive_enum<T: AsRef<str>>( mut self, arg: T, ) -> Builder949 pub fn rustified_non_exhaustive_enum<T: AsRef<str>>(
950 mut self,
951 arg: T,
952 ) -> Builder {
953 self.options.rustified_non_exhaustive_enums.insert(arg);
954 self
955 }
956
957 /// Mark the given enum (or set of enums, if using a pattern) as a set of
958 /// constants that are not to be put into a module.
constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder959 pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
960 self.options.constified_enums.insert(arg);
961 self
962 }
963
964 /// Mark the given enum (or set of enums, if using a pattern) as a set of
965 /// constants that should be put into a module.
966 ///
967 /// This makes bindgen generate modules containing constants instead of
968 /// just constants. Regular expressions are supported.
constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder969 pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
970 self.options.constified_enum_modules.insert(arg);
971 self
972 }
973
974 /// Set the default type for macro constants
default_macro_constant_type( mut self, arg: codegen::MacroTypeVariation, ) -> Builder975 pub fn default_macro_constant_type(
976 mut self,
977 arg: codegen::MacroTypeVariation,
978 ) -> Builder {
979 self.options.default_macro_constant_type = arg;
980 self
981 }
982
983 /// Set the default style of code to generate for typedefs
default_alias_style( mut self, arg: codegen::AliasVariation, ) -> Builder984 pub fn default_alias_style(
985 mut self,
986 arg: codegen::AliasVariation,
987 ) -> Builder {
988 self.options.default_alias_style = arg;
989 self
990 }
991
992 /// Mark the given typedef alias (or set of aliases, if using a pattern) to
993 /// use regular Rust type aliasing.
994 ///
995 /// This is the default behavior and should be used if `default_alias_style`
996 /// was set to NewType or NewTypeDeref and you want to override it for a
997 /// set of typedefs.
type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder998 pub fn type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
999 self.options.type_alias.insert(arg);
1000 self
1001 }
1002
1003 /// Mark the given typedef alias (or set of aliases, if using a pattern) to
1004 /// be generated as a new type by having the aliased type be wrapped in a
1005 /// #[repr(transparent)] struct.
1006 ///
1007 /// Used to enforce stricter type checking.
new_type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder1008 pub fn new_type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
1009 self.options.new_type_alias.insert(arg);
1010 self
1011 }
1012
1013 /// Mark the given typedef alias (or set of aliases, if using a pattern) to
1014 /// be generated as a new type by having the aliased type be wrapped in a
1015 /// #[repr(transparent)] struct and also have an automatically generated
1016 /// impl's of `Deref` and `DerefMut` to their aliased type.
new_type_alias_deref<T: AsRef<str>>(mut self, arg: T) -> Builder1017 pub fn new_type_alias_deref<T: AsRef<str>>(mut self, arg: T) -> Builder {
1018 self.options.new_type_alias_deref.insert(arg);
1019 self
1020 }
1021
1022 /// Add a string to prepend to the generated bindings. The string is passed
1023 /// through without any modification.
raw_line<T: Into<String>>(mut self, arg: T) -> Self1024 pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Self {
1025 self.options.raw_lines.push(arg.into());
1026 self
1027 }
1028
1029 /// Add a given line to the beginning of module `mod`.
module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self where T: Into<String>, U: Into<String>,1030 pub fn module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self
1031 where
1032 T: Into<String>,
1033 U: Into<String>,
1034 {
1035 self.options
1036 .module_lines
1037 .entry(mod_.into())
1038 .or_insert_with(Vec::new)
1039 .push(line.into());
1040 self
1041 }
1042
1043 /// Add a given set of lines to the beginning of module `mod`.
module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self where T: Into<String>, I: IntoIterator, I::Item: Into<String>,1044 pub fn module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self
1045 where
1046 T: Into<String>,
1047 I: IntoIterator,
1048 I::Item: Into<String>,
1049 {
1050 self.options
1051 .module_lines
1052 .entry(mod_.into())
1053 .or_insert_with(Vec::new)
1054 .extend(lines.into_iter().map(Into::into));
1055 self
1056 }
1057
1058 /// Add an argument to be passed straight through to clang.
clang_arg<T: Into<String>>(mut self, arg: T) -> Builder1059 pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
1060 self.options.clang_args.push(arg.into());
1061 self
1062 }
1063
1064 /// Add arguments to be passed straight through to clang.
clang_args<I>(mut self, iter: I) -> Builder where I: IntoIterator, I::Item: AsRef<str>,1065 pub fn clang_args<I>(mut self, iter: I) -> Builder
1066 where
1067 I: IntoIterator,
1068 I::Item: AsRef<str>,
1069 {
1070 for arg in iter {
1071 self = self.clang_arg(arg.as_ref())
1072 }
1073 self
1074 }
1075
1076 /// Emit bindings for builtin definitions (for example `__builtin_va_list`)
1077 /// in the generated Rust.
emit_builtins(mut self) -> Builder1078 pub fn emit_builtins(mut self) -> Builder {
1079 self.options.builtins = true;
1080 self
1081 }
1082
1083 /// Avoid converting floats to `f32`/`f64` by default.
no_convert_floats(mut self) -> Self1084 pub fn no_convert_floats(mut self) -> Self {
1085 self.options.convert_floats = false;
1086 self
1087 }
1088
1089 /// Set whether layout tests should be generated.
layout_tests(mut self, doit: bool) -> Self1090 pub fn layout_tests(mut self, doit: bool) -> Self {
1091 self.options.layout_tests = doit;
1092 self
1093 }
1094
1095 /// Set whether `Debug` should be implemented, if it can not be derived automatically.
impl_debug(mut self, doit: bool) -> Self1096 pub fn impl_debug(mut self, doit: bool) -> Self {
1097 self.options.impl_debug = doit;
1098 self
1099 }
1100
1101 /// Set whether `PartialEq` should be implemented, if it can not be derived automatically.
impl_partialeq(mut self, doit: bool) -> Self1102 pub fn impl_partialeq(mut self, doit: bool) -> Self {
1103 self.options.impl_partialeq = doit;
1104 self
1105 }
1106
1107 /// Set whether `Copy` should be derived by default.
derive_copy(mut self, doit: bool) -> Self1108 pub fn derive_copy(mut self, doit: bool) -> Self {
1109 self.options.derive_copy = doit;
1110 self
1111 }
1112
1113 /// Set whether `Debug` should be derived by default.
derive_debug(mut self, doit: bool) -> Self1114 pub fn derive_debug(mut self, doit: bool) -> Self {
1115 self.options.derive_debug = doit;
1116 self
1117 }
1118
1119 /// Set whether `Default` should be derived by default.
derive_default(mut self, doit: bool) -> Self1120 pub fn derive_default(mut self, doit: bool) -> Self {
1121 self.options.derive_default = doit;
1122 self
1123 }
1124
1125 /// Set whether `Hash` should be derived by default.
derive_hash(mut self, doit: bool) -> Self1126 pub fn derive_hash(mut self, doit: bool) -> Self {
1127 self.options.derive_hash = doit;
1128 self
1129 }
1130
1131 /// Set whether `PartialOrd` should be derived by default.
1132 /// If we don't compute partialord, we also cannot compute
1133 /// ord. Set the derive_ord to `false` when doit is `false`.
derive_partialord(mut self, doit: bool) -> Self1134 pub fn derive_partialord(mut self, doit: bool) -> Self {
1135 self.options.derive_partialord = doit;
1136 if !doit {
1137 self.options.derive_ord = false;
1138 }
1139 self
1140 }
1141
1142 /// Set whether `Ord` should be derived by default.
1143 /// We can't compute `Ord` without computing `PartialOrd`,
1144 /// so we set the same option to derive_partialord.
derive_ord(mut self, doit: bool) -> Self1145 pub fn derive_ord(mut self, doit: bool) -> Self {
1146 self.options.derive_ord = doit;
1147 self.options.derive_partialord = doit;
1148 self
1149 }
1150
1151 /// Set whether `PartialEq` should be derived by default.
1152 ///
1153 /// If we don't derive `PartialEq`, we also cannot derive `Eq`, so deriving
1154 /// `Eq` is also disabled when `doit` is `false`.
derive_partialeq(mut self, doit: bool) -> Self1155 pub fn derive_partialeq(mut self, doit: bool) -> Self {
1156 self.options.derive_partialeq = doit;
1157 if !doit {
1158 self.options.derive_eq = false;
1159 }
1160 self
1161 }
1162
1163 /// Set whether `Eq` should be derived by default.
1164 ///
1165 /// We can't derive `Eq` without also deriving `PartialEq`, so we also
1166 /// enable deriving `PartialEq` when `doit` is `true`.
derive_eq(mut self, doit: bool) -> Self1167 pub fn derive_eq(mut self, doit: bool) -> Self {
1168 self.options.derive_eq = doit;
1169 if doit {
1170 self.options.derive_partialeq = doit;
1171 }
1172 self
1173 }
1174
1175 /// Set whether or not to time bindgen phases, and print information to
1176 /// stderr.
time_phases(mut self, doit: bool) -> Self1177 pub fn time_phases(mut self, doit: bool) -> Self {
1178 self.options.time_phases = doit;
1179 self
1180 }
1181
1182 /// Emit Clang AST.
emit_clang_ast(mut self) -> Builder1183 pub fn emit_clang_ast(mut self) -> Builder {
1184 self.options.emit_ast = true;
1185 self
1186 }
1187
1188 /// Emit IR.
emit_ir(mut self) -> Builder1189 pub fn emit_ir(mut self) -> Builder {
1190 self.options.emit_ir = true;
1191 self
1192 }
1193
1194 /// Enable C++ namespaces.
enable_cxx_namespaces(mut self) -> Builder1195 pub fn enable_cxx_namespaces(mut self) -> Builder {
1196 self.options.enable_cxx_namespaces = true;
1197 self
1198 }
1199
1200 /// Enable detecting must_use attributes on C functions.
1201 ///
1202 /// This is quite slow in some cases (see #1465), so it's disabled by
1203 /// default.
1204 ///
1205 /// Note that for this to do something meaningful for now at least, the rust
1206 /// target version has to have support for `#[must_use]`.
enable_function_attribute_detection(mut self) -> Self1207 pub fn enable_function_attribute_detection(mut self) -> Self {
1208 self.options.enable_function_attribute_detection = true;
1209 self
1210 }
1211
1212 /// Disable name auto-namespacing.
1213 ///
1214 /// By default, bindgen mangles names like `foo::bar::Baz` to look like
1215 /// `foo_bar_Baz` instead of just `Baz`.
1216 ///
1217 /// This method disables that behavior.
1218 ///
1219 /// Note that this intentionally does not change the names used for
1220 /// allowlisting and blocklisting, which should still be mangled with the
1221 /// namespaces.
1222 ///
1223 /// Note, also, that this option may cause bindgen to generate duplicate
1224 /// names.
disable_name_namespacing(mut self) -> Builder1225 pub fn disable_name_namespacing(mut self) -> Builder {
1226 self.options.disable_name_namespacing = true;
1227 self
1228 }
1229
1230 /// Disable nested struct naming.
1231 ///
1232 /// The following structs have different names for C and C++. In case of C
1233 /// they are visible as `foo` and `bar`. In case of C++ they are visible as
1234 /// `foo` and `foo::bar`.
1235 ///
1236 /// ```c
1237 /// struct foo {
1238 /// struct bar {
1239 /// } b;
1240 /// };
1241 /// ```
1242 ///
1243 /// Bindgen wants to avoid duplicate names by default so it follows C++ naming
1244 /// and it generates `foo`/`foo_bar` instead of just `foo`/`bar`.
1245 ///
1246 /// This method disables this behavior and it is indented to be used only
1247 /// for headers that were written for C.
disable_nested_struct_naming(mut self) -> Builder1248 pub fn disable_nested_struct_naming(mut self) -> Builder {
1249 self.options.disable_nested_struct_naming = true;
1250 self
1251 }
1252
1253 /// Treat inline namespaces conservatively.
1254 ///
1255 /// This is tricky, because in C++ is technically legal to override an item
1256 /// defined in an inline namespace:
1257 ///
1258 /// ```cpp
1259 /// inline namespace foo {
1260 /// using Bar = int;
1261 /// }
1262 /// using Bar = long;
1263 /// ```
1264 ///
1265 /// Even though referencing `Bar` is a compiler error.
1266 ///
1267 /// We want to support this (arguably esoteric) use case, but we don't want
1268 /// to make the rest of bindgen users pay an usability penalty for that.
1269 ///
1270 /// To support this, we need to keep all the inline namespaces around, but
1271 /// then bindgen usage is a bit more difficult, because you cannot
1272 /// reference, e.g., `std::string` (you'd need to use the proper inline
1273 /// namespace).
1274 ///
1275 /// We could complicate a lot of the logic to detect name collisions, and if
1276 /// not detected generate a `pub use inline_ns::*` or something like that.
1277 ///
1278 /// That's probably something we can do if we see this option is needed in a
1279 /// lot of cases, to improve it's usability, but my guess is that this is
1280 /// not going to be too useful.
conservative_inline_namespaces(mut self) -> Builder1281 pub fn conservative_inline_namespaces(mut self) -> Builder {
1282 self.options.conservative_inline_namespaces = true;
1283 self
1284 }
1285
1286 /// Whether inline functions should be generated or not.
1287 ///
1288 /// Note that they will usually not work. However you can use
1289 /// `-fkeep-inline-functions` or `-fno-inline-functions` if you are
1290 /// responsible of compiling the library to make them callable.
generate_inline_functions(mut self, doit: bool) -> Self1291 pub fn generate_inline_functions(mut self, doit: bool) -> Self {
1292 self.options.generate_inline_functions = doit;
1293 self
1294 }
1295
1296 /// Ignore functions.
ignore_functions(mut self) -> Builder1297 pub fn ignore_functions(mut self) -> Builder {
1298 self.options.codegen_config.remove(CodegenConfig::FUNCTIONS);
1299 self
1300 }
1301
1302 /// Ignore methods.
ignore_methods(mut self) -> Builder1303 pub fn ignore_methods(mut self) -> Builder {
1304 self.options.codegen_config.remove(CodegenConfig::METHODS);
1305 self
1306 }
1307
1308 /// Avoid generating any unstable Rust, such as Rust unions, in the generated bindings.
1309 #[deprecated(note = "please use `rust_target` instead")]
unstable_rust(self, doit: bool) -> Self1310 pub fn unstable_rust(self, doit: bool) -> Self {
1311 let rust_target = if doit {
1312 RustTarget::Nightly
1313 } else {
1314 LATEST_STABLE_RUST
1315 };
1316 self.rust_target(rust_target)
1317 }
1318
1319 /// Use core instead of libstd in the generated bindings.
use_core(mut self) -> Builder1320 pub fn use_core(mut self) -> Builder {
1321 self.options.use_core = true;
1322 self
1323 }
1324
1325 /// Use the given prefix for the raw types instead of `::std::os::raw`.
ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder1326 pub fn ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
1327 self.options.ctypes_prefix = Some(prefix.into());
1328 self
1329 }
1330
1331 /// Use the given prefix for the anon fields.
anon_fields_prefix<T: Into<String>>(mut self, prefix: T) -> Builder1332 pub fn anon_fields_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
1333 self.options.anon_fields_prefix = prefix.into();
1334 self
1335 }
1336
1337 /// Allows configuring types in different situations, see the
1338 /// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation.
parse_callbacks( mut self, cb: Box<dyn callbacks::ParseCallbacks>, ) -> Self1339 pub fn parse_callbacks(
1340 mut self,
1341 cb: Box<dyn callbacks::ParseCallbacks>,
1342 ) -> Self {
1343 self.options.parse_callbacks = Some(cb);
1344 self
1345 }
1346
1347 /// Choose what to generate using a
1348 /// [`CodegenConfig`](./struct.CodegenConfig.html).
with_codegen_config(mut self, config: CodegenConfig) -> Self1349 pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self {
1350 self.options.codegen_config = config;
1351 self
1352 }
1353
1354 /// Whether to detect include paths using clang_sys.
detect_include_paths(mut self, doit: bool) -> Self1355 pub fn detect_include_paths(mut self, doit: bool) -> Self {
1356 self.options.detect_include_paths = doit;
1357 self
1358 }
1359
1360 /// Whether to try to fit macro constants to types smaller than u32/i32
fit_macro_constants(mut self, doit: bool) -> Self1361 pub fn fit_macro_constants(mut self, doit: bool) -> Self {
1362 self.options.fit_macro_constants = doit;
1363 self
1364 }
1365
1366 /// Prepend the enum name to constant or newtype variants.
prepend_enum_name(mut self, doit: bool) -> Self1367 pub fn prepend_enum_name(mut self, doit: bool) -> Self {
1368 self.options.prepend_enum_name = doit;
1369 self
1370 }
1371
1372 /// Set whether `size_t` should be translated to `usize` automatically.
size_t_is_usize(mut self, is: bool) -> Self1373 pub fn size_t_is_usize(mut self, is: bool) -> Self {
1374 self.options.size_t_is_usize = is;
1375 self
1376 }
1377
1378 /// Set whether rustfmt should format the generated bindings.
rustfmt_bindings(mut self, doit: bool) -> Self1379 pub fn rustfmt_bindings(mut self, doit: bool) -> Self {
1380 self.options.rustfmt_bindings = doit;
1381 self
1382 }
1383
1384 /// Set whether we should record matched items in our regex sets.
record_matches(mut self, doit: bool) -> Self1385 pub fn record_matches(mut self, doit: bool) -> Self {
1386 self.options.record_matches = doit;
1387 self
1388 }
1389
1390 /// Set the absolute path to the rustfmt configuration file, if None, the standard rustfmt
1391 /// options are used.
rustfmt_configuration_file(mut self, path: Option<PathBuf>) -> Self1392 pub fn rustfmt_configuration_file(mut self, path: Option<PathBuf>) -> Self {
1393 self = self.rustfmt_bindings(true);
1394 self.options.rustfmt_configuration_file = path;
1395 self
1396 }
1397
1398 /// Sets an explicit path to rustfmt, to be used when rustfmt is enabled.
with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self1399 pub fn with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self {
1400 self.options.rustfmt_path = Some(path.into());
1401 self
1402 }
1403
1404 /// Generate the Rust bindings using the options built up thus far.
generate(mut self) -> Result<Bindings, ()>1405 pub fn generate(mut self) -> Result<Bindings, ()> {
1406 // Add any extra arguments from the environment to the clang command line.
1407 if let Some(extra_clang_args) =
1408 env::var("BINDGEN_EXTRA_CLANG_ARGS").ok()
1409 {
1410 // Try to parse it with shell quoting. If we fail, make it one single big argument.
1411 if let Some(strings) = shlex::split(&extra_clang_args) {
1412 self.options.clang_args.extend(strings);
1413 } else {
1414 self.options.clang_args.push(extra_clang_args);
1415 };
1416 }
1417
1418 // Transform input headers to arguments on the clang command line.
1419 self.options.input_header = self.input_headers.pop();
1420 self.options
1421 .clang_args
1422 .extend(self.input_headers.drain(..).flat_map(|header| {
1423 iter::once("-include".into()).chain(iter::once(header))
1424 }));
1425
1426 self.options.input_unsaved_files.extend(
1427 self.input_header_contents
1428 .drain(..)
1429 .map(|(name, contents)| {
1430 clang::UnsavedFile::new(&name, &contents)
1431 }),
1432 );
1433
1434 Bindings::generate(self.options)
1435 }
1436
1437 /// Preprocess and dump the input header files to disk.
1438 ///
1439 /// This is useful when debugging bindgen, using C-Reduce, or when filing
1440 /// issues. The resulting file will be named something like `__bindgen.i` or
1441 /// `__bindgen.ii`
dump_preprocessed_input(&self) -> io::Result<()>1442 pub fn dump_preprocessed_input(&self) -> io::Result<()> {
1443 let clang =
1444 clang_sys::support::Clang::find(None, &[]).ok_or_else(|| {
1445 io::Error::new(
1446 io::ErrorKind::Other,
1447 "Cannot find clang executable",
1448 )
1449 })?;
1450
1451 // The contents of a wrapper file that includes all the input header
1452 // files.
1453 let mut wrapper_contents = String::new();
1454
1455 // Whether we are working with C or C++ inputs.
1456 let mut is_cpp = args_are_cpp(&self.options.clang_args);
1457
1458 // For each input header, add `#include "$header"`.
1459 for header in &self.input_headers {
1460 is_cpp |= file_is_cpp(header);
1461
1462 wrapper_contents.push_str("#include \"");
1463 wrapper_contents.push_str(header);
1464 wrapper_contents.push_str("\"\n");
1465 }
1466
1467 // For each input header content, add a prefix line of `#line 0 "$name"`
1468 // followed by the contents.
1469 for &(ref name, ref contents) in &self.input_header_contents {
1470 is_cpp |= file_is_cpp(name);
1471
1472 wrapper_contents.push_str("#line 0 \"");
1473 wrapper_contents.push_str(name);
1474 wrapper_contents.push_str("\"\n");
1475 wrapper_contents.push_str(contents);
1476 }
1477
1478 let wrapper_path = PathBuf::from(if is_cpp {
1479 "__bindgen.cpp"
1480 } else {
1481 "__bindgen.c"
1482 });
1483
1484 {
1485 let mut wrapper_file = File::create(&wrapper_path)?;
1486 wrapper_file.write_all(wrapper_contents.as_bytes())?;
1487 }
1488
1489 let mut cmd = Command::new(&clang.path);
1490 cmd.arg("-save-temps")
1491 .arg("-E")
1492 .arg("-C")
1493 .arg("-c")
1494 .arg(&wrapper_path)
1495 .stdout(Stdio::piped());
1496
1497 for a in &self.options.clang_args {
1498 cmd.arg(a);
1499 }
1500
1501 let mut child = cmd.spawn()?;
1502
1503 let mut preprocessed = child.stdout.take().unwrap();
1504 let mut file = File::create(if is_cpp {
1505 "__bindgen.ii"
1506 } else {
1507 "__bindgen.i"
1508 })?;
1509 io::copy(&mut preprocessed, &mut file)?;
1510
1511 if child.wait()?.success() {
1512 Ok(())
1513 } else {
1514 Err(io::Error::new(
1515 io::ErrorKind::Other,
1516 "clang exited with non-zero status",
1517 ))
1518 }
1519 }
1520
1521 /// Don't derive `PartialEq` for a given type. Regular
1522 /// expressions are supported.
no_partialeq<T: Into<String>>(mut self, arg: T) -> Builder1523 pub fn no_partialeq<T: Into<String>>(mut self, arg: T) -> Builder {
1524 self.options.no_partialeq_types.insert(arg.into());
1525 self
1526 }
1527
1528 /// Don't derive `Copy` for a given type. Regular
1529 /// expressions are supported.
no_copy<T: Into<String>>(mut self, arg: T) -> Self1530 pub fn no_copy<T: Into<String>>(mut self, arg: T) -> Self {
1531 self.options.no_copy_types.insert(arg.into());
1532 self
1533 }
1534
1535 /// Don't derive `Debug` for a given type. Regular
1536 /// expressions are supported.
no_debug<T: Into<String>>(mut self, arg: T) -> Self1537 pub fn no_debug<T: Into<String>>(mut self, arg: T) -> Self {
1538 self.options.no_debug_types.insert(arg.into());
1539 self
1540 }
1541
1542 /// Don't derive/impl `Default` for a given type. Regular
1543 /// expressions are supported.
no_default<T: Into<String>>(mut self, arg: T) -> Self1544 pub fn no_default<T: Into<String>>(mut self, arg: T) -> Self {
1545 self.options.no_default_types.insert(arg.into());
1546 self
1547 }
1548
1549 /// Don't derive `Hash` for a given type. Regular
1550 /// expressions are supported.
no_hash<T: Into<String>>(mut self, arg: T) -> Builder1551 pub fn no_hash<T: Into<String>>(mut self, arg: T) -> Builder {
1552 self.options.no_hash_types.insert(arg.into());
1553 self
1554 }
1555
1556 /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut)
array_pointers_in_arguments(mut self, doit: bool) -> Self1557 pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self {
1558 self.options.array_pointers_in_arguments = doit;
1559 self
1560 }
1561
1562 /// Set the wasm import module name
wasm_import_module_name<T: Into<String>>( mut self, import_name: T, ) -> Self1563 pub fn wasm_import_module_name<T: Into<String>>(
1564 mut self,
1565 import_name: T,
1566 ) -> Self {
1567 self.options.wasm_import_module_name = Some(import_name.into());
1568 self
1569 }
1570
1571 /// Specify the dynamic library name if we are generating bindings for a shared library.
dynamic_library_name<T: Into<String>>( mut self, dynamic_library_name: T, ) -> Self1572 pub fn dynamic_library_name<T: Into<String>>(
1573 mut self,
1574 dynamic_library_name: T,
1575 ) -> Self {
1576 self.options.dynamic_library_name = Some(dynamic_library_name.into());
1577 self
1578 }
1579
1580 /// Require successful linkage for all routines in a shared library.
1581 /// This allows us to optimize function calls by being able to safely assume function pointers
1582 /// are valid.
dynamic_link_require_all(mut self, req: bool) -> Self1583 pub fn dynamic_link_require_all(mut self, req: bool) -> Self {
1584 self.options.dynamic_link_require_all = req;
1585 self
1586 }
1587
1588 /// Generate bindings as `pub` only if the bound item is publically accessible by C++.
respect_cxx_access_specs(mut self, doit: bool) -> Self1589 pub fn respect_cxx_access_specs(mut self, doit: bool) -> Self {
1590 self.options.respect_cxx_access_specs = doit;
1591 self
1592 }
1593
1594 /// Always translate enum integer types to native Rust integer types.
1595 ///
1596 /// This will result in enums having types such as `u32` and `i16` instead
1597 /// of `c_uint` and `c_short`. Types for Rustified enums are always
1598 /// translated.
translate_enum_integer_types(mut self, doit: bool) -> Self1599 pub fn translate_enum_integer_types(mut self, doit: bool) -> Self {
1600 self.options.translate_enum_integer_types = doit;
1601 self
1602 }
1603 }
1604
1605 /// Configuration options for generated bindings.
1606 #[derive(Debug)]
1607 struct BindgenOptions {
1608 /// The set of types that have been blocklisted and should not appear
1609 /// anywhere in the generated code.
1610 blocklisted_types: RegexSet,
1611
1612 /// The set of functions that have been blocklisted and should not appear
1613 /// in the generated code.
1614 blocklisted_functions: RegexSet,
1615
1616 /// The set of items, regardless of item-type, that have been
1617 /// blocklisted and should not appear in the generated code.
1618 blocklisted_items: RegexSet,
1619
1620 /// The set of types that should be treated as opaque structures in the
1621 /// generated code.
1622 opaque_types: RegexSet,
1623
1624 /// The explicit rustfmt path.
1625 rustfmt_path: Option<PathBuf>,
1626
1627 /// The set of types that we should have bindings for in the generated
1628 /// code.
1629 ///
1630 /// This includes all types transitively reachable from any type in this
1631 /// set. One might think of allowlisted types/vars/functions as GC roots,
1632 /// and the generated Rust code as including everything that gets marked.
1633 allowlisted_types: RegexSet,
1634
1635 /// Allowlisted functions. See docs for `allowlisted_types` for more.
1636 allowlisted_functions: RegexSet,
1637
1638 /// Allowlisted variables. See docs for `allowlisted_types` for more.
1639 allowlisted_vars: RegexSet,
1640
1641 /// The default style of code to generate for enums
1642 default_enum_style: codegen::EnumVariation,
1643
1644 /// The enum patterns to mark an enum as a bitfield
1645 /// (newtype with bitwise operations).
1646 bitfield_enums: RegexSet,
1647
1648 /// The enum patterns to mark an enum as a newtype.
1649 newtype_enums: RegexSet,
1650
1651 /// The enum patterns to mark an enum as a Rust enum.
1652 rustified_enums: RegexSet,
1653
1654 /// The enum patterns to mark an enum as a non-exhaustive Rust enum.
1655 rustified_non_exhaustive_enums: RegexSet,
1656
1657 /// The enum patterns to mark an enum as a module of constants.
1658 constified_enum_modules: RegexSet,
1659
1660 /// The enum patterns to mark an enum as a set of constants.
1661 constified_enums: RegexSet,
1662
1663 /// The default type for C macro constants.
1664 default_macro_constant_type: codegen::MacroTypeVariation,
1665
1666 /// The default style of code to generate for typedefs.
1667 default_alias_style: codegen::AliasVariation,
1668
1669 /// Typedef patterns that will use regular type aliasing.
1670 type_alias: RegexSet,
1671
1672 /// Typedef patterns that will be aliased by creating a new struct.
1673 new_type_alias: RegexSet,
1674
1675 /// Typedef patterns that will be wrapped in a new struct and have
1676 /// Deref and Deref to their aliased type.
1677 new_type_alias_deref: RegexSet,
1678
1679 /// Whether we should generate builtins or not.
1680 builtins: bool,
1681
1682 /// True if we should dump the Clang AST for debugging purposes.
1683 emit_ast: bool,
1684
1685 /// True if we should dump our internal IR for debugging purposes.
1686 emit_ir: bool,
1687
1688 /// Output graphviz dot file.
1689 emit_ir_graphviz: Option<String>,
1690
1691 /// True if we should emulate C++ namespaces with Rust modules in the
1692 /// generated bindings.
1693 enable_cxx_namespaces: bool,
1694
1695 /// True if we should try to find unexposed attributes in functions, in
1696 /// order to be able to generate #[must_use] attributes in Rust.
1697 enable_function_attribute_detection: bool,
1698
1699 /// True if we should avoid mangling names with namespaces.
1700 disable_name_namespacing: bool,
1701
1702 /// True if we should avoid generating nested struct names.
1703 disable_nested_struct_naming: bool,
1704
1705 /// True if we should avoid embedding version identifiers into source code.
1706 disable_header_comment: bool,
1707
1708 /// True if we should generate layout tests for generated structures.
1709 layout_tests: bool,
1710
1711 /// True if we should implement the Debug trait for C/C++ structures and types
1712 /// that do not support automatically deriving Debug.
1713 impl_debug: bool,
1714
1715 /// True if we should implement the PartialEq trait for C/C++ structures and types
1716 /// that do not support automatically deriving PartialEq.
1717 impl_partialeq: bool,
1718
1719 /// True if we should derive Copy trait implementations for C/C++ structures
1720 /// and types.
1721 derive_copy: bool,
1722
1723 /// True if we should derive Debug trait implementations for C/C++ structures
1724 /// and types.
1725 derive_debug: bool,
1726
1727 /// True if we should derive Default trait implementations for C/C++ structures
1728 /// and types.
1729 derive_default: bool,
1730
1731 /// True if we should derive Hash trait implementations for C/C++ structures
1732 /// and types.
1733 derive_hash: bool,
1734
1735 /// True if we should derive PartialOrd trait implementations for C/C++ structures
1736 /// and types.
1737 derive_partialord: bool,
1738
1739 /// True if we should derive Ord trait implementations for C/C++ structures
1740 /// and types.
1741 derive_ord: bool,
1742
1743 /// True if we should derive PartialEq trait implementations for C/C++ structures
1744 /// and types.
1745 derive_partialeq: bool,
1746
1747 /// True if we should derive Eq trait implementations for C/C++ structures
1748 /// and types.
1749 derive_eq: bool,
1750
1751 /// True if we should avoid using libstd to use libcore instead.
1752 use_core: bool,
1753
1754 /// An optional prefix for the "raw" types, like `c_int`, `c_void`...
1755 ctypes_prefix: Option<String>,
1756
1757 /// The prefix for the anon fields.
1758 anon_fields_prefix: String,
1759
1760 /// Whether to time the bindgen phases.
1761 time_phases: bool,
1762
1763 /// True if we should generate constant names that are **directly** under
1764 /// namespaces.
1765 namespaced_constants: bool,
1766
1767 /// True if we should use MSVC name mangling rules.
1768 msvc_mangling: bool,
1769
1770 /// Whether we should convert float types to f32/f64 types.
1771 convert_floats: bool,
1772
1773 /// The set of raw lines to prepend to the top-level module of generated
1774 /// Rust code.
1775 raw_lines: Vec<String>,
1776
1777 /// The set of raw lines to prepend to each of the modules.
1778 ///
1779 /// This only makes sense if the `enable_cxx_namespaces` option is set.
1780 module_lines: HashMap<String, Vec<String>>,
1781
1782 /// The set of arguments to pass straight through to Clang.
1783 clang_args: Vec<String>,
1784
1785 /// The input header file.
1786 input_header: Option<String>,
1787
1788 /// Unsaved files for input.
1789 input_unsaved_files: Vec<clang::UnsavedFile>,
1790
1791 /// A user-provided visitor to allow customizing different kinds of
1792 /// situations.
1793 parse_callbacks: Option<Box<dyn callbacks::ParseCallbacks>>,
1794
1795 /// Which kind of items should we generate? By default, we'll generate all
1796 /// of them.
1797 codegen_config: CodegenConfig,
1798
1799 /// Whether to treat inline namespaces conservatively.
1800 ///
1801 /// See the builder method description for more details.
1802 conservative_inline_namespaces: bool,
1803
1804 /// Whether to keep documentation comments in the generated output. See the
1805 /// documentation for more details. Defaults to true.
1806 generate_comments: bool,
1807
1808 /// Whether to generate inline functions. Defaults to false.
1809 generate_inline_functions: bool,
1810
1811 /// Whether to allowlist types recursively. Defaults to true.
1812 allowlist_recursively: bool,
1813
1814 /// Instead of emitting 'use objc;' to files generated from objective c files,
1815 /// generate '#[macro_use] extern crate objc;'
1816 objc_extern_crate: bool,
1817
1818 /// Instead of emitting 'use block;' to files generated from objective c files,
1819 /// generate '#[macro_use] extern crate block;'
1820 generate_block: bool,
1821
1822 /// Instead of emitting 'use block;' to files generated from objective c files,
1823 /// generate '#[macro_use] extern crate block;'
1824 block_extern_crate: bool,
1825
1826 /// Whether to use the clang-provided name mangling. This is true and
1827 /// probably needed for C++ features.
1828 ///
1829 /// However, some old libclang versions seem to return incorrect results in
1830 /// some cases for non-mangled functions, see [1], so we allow disabling it.
1831 ///
1832 /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
1833 enable_mangling: bool,
1834
1835 /// Whether to detect include paths using clang_sys.
1836 detect_include_paths: bool,
1837
1838 /// Whether to try to fit macro constants into types smaller than u32/i32
1839 fit_macro_constants: bool,
1840
1841 /// Whether to prepend the enum name to constant or newtype variants.
1842 prepend_enum_name: bool,
1843
1844 /// Version of the Rust compiler to target
1845 rust_target: RustTarget,
1846
1847 /// Features to enable, derived from `rust_target`
1848 rust_features: RustFeatures,
1849
1850 /// Whether we should record which items in the regex sets ever matched.
1851 ///
1852 /// This may be a bit slower, but will enable reporting of unused allowlist
1853 /// items via the `error!` log.
1854 record_matches: bool,
1855
1856 /// Whether `size_t` should be translated to `usize` automatically.
1857 size_t_is_usize: bool,
1858
1859 /// Whether rustfmt should format the generated bindings.
1860 rustfmt_bindings: bool,
1861
1862 /// The absolute path to the rustfmt configuration file, if None, the standard rustfmt
1863 /// options are used.
1864 rustfmt_configuration_file: Option<PathBuf>,
1865
1866 /// The set of types that we should not derive `PartialEq` for.
1867 no_partialeq_types: RegexSet,
1868
1869 /// The set of types that we should not derive `Copy` for.
1870 no_copy_types: RegexSet,
1871
1872 /// The set of types that we should not derive `Debug` for.
1873 no_debug_types: RegexSet,
1874
1875 /// The set of types that we should not derive/impl `Default` for.
1876 no_default_types: RegexSet,
1877
1878 /// The set of types that we should not derive `Hash` for.
1879 no_hash_types: RegexSet,
1880
1881 /// Decide if C arrays should be regular pointers in rust or array pointers
1882 array_pointers_in_arguments: bool,
1883
1884 /// Wasm import module name.
1885 wasm_import_module_name: Option<String>,
1886
1887 /// The name of the dynamic library (if we are generating bindings for a shared library). If
1888 /// this is None, no dynamic bindings are created.
1889 dynamic_library_name: Option<String>,
1890
1891 /// Require successful linkage for all routines in a shared library.
1892 /// This allows us to optimize function calls by being able to safely assume function pointers
1893 /// are valid. No effect if `dynamic_library_name` is None.
1894 dynamic_link_require_all: bool,
1895
1896 /// Only make generated bindings `pub` if the items would be publically accessible
1897 /// by C++.
1898 respect_cxx_access_specs: bool,
1899
1900 /// Always translate enum integer types to native Rust integer types.
1901 translate_enum_integer_types: bool,
1902 }
1903
1904 /// TODO(emilio): This is sort of a lie (see the error message that results from
1905 /// removing this), but since we don't share references across panic boundaries
1906 /// it's ok.
1907 impl ::std::panic::UnwindSafe for BindgenOptions {}
1908
1909 impl BindgenOptions {
build(&mut self)1910 fn build(&mut self) {
1911 let mut regex_sets = [
1912 &mut self.allowlisted_vars,
1913 &mut self.allowlisted_types,
1914 &mut self.allowlisted_functions,
1915 &mut self.blocklisted_types,
1916 &mut self.blocklisted_functions,
1917 &mut self.blocklisted_items,
1918 &mut self.opaque_types,
1919 &mut self.bitfield_enums,
1920 &mut self.constified_enums,
1921 &mut self.constified_enum_modules,
1922 &mut self.newtype_enums,
1923 &mut self.rustified_enums,
1924 &mut self.rustified_non_exhaustive_enums,
1925 &mut self.type_alias,
1926 &mut self.new_type_alias,
1927 &mut self.new_type_alias_deref,
1928 &mut self.no_partialeq_types,
1929 &mut self.no_copy_types,
1930 &mut self.no_debug_types,
1931 &mut self.no_default_types,
1932 &mut self.no_hash_types,
1933 ];
1934 let record_matches = self.record_matches;
1935 for regex_set in &mut regex_sets {
1936 regex_set.build(record_matches);
1937 }
1938 }
1939
1940 /// Update rust target version
set_rust_target(&mut self, rust_target: RustTarget)1941 pub fn set_rust_target(&mut self, rust_target: RustTarget) {
1942 self.rust_target = rust_target;
1943
1944 // Keep rust_features synced with rust_target
1945 self.rust_features = rust_target.into();
1946 }
1947
1948 /// Get features supported by target Rust version
rust_features(&self) -> RustFeatures1949 pub fn rust_features(&self) -> RustFeatures {
1950 self.rust_features
1951 }
1952 }
1953
1954 impl Default for BindgenOptions {
default() -> BindgenOptions1955 fn default() -> BindgenOptions {
1956 let rust_target = RustTarget::default();
1957
1958 BindgenOptions {
1959 rust_target,
1960 rust_features: rust_target.into(),
1961 blocklisted_types: Default::default(),
1962 blocklisted_functions: Default::default(),
1963 blocklisted_items: Default::default(),
1964 opaque_types: Default::default(),
1965 rustfmt_path: Default::default(),
1966 allowlisted_types: Default::default(),
1967 allowlisted_functions: Default::default(),
1968 allowlisted_vars: Default::default(),
1969 default_enum_style: Default::default(),
1970 bitfield_enums: Default::default(),
1971 newtype_enums: Default::default(),
1972 rustified_enums: Default::default(),
1973 rustified_non_exhaustive_enums: Default::default(),
1974 constified_enums: Default::default(),
1975 constified_enum_modules: Default::default(),
1976 default_macro_constant_type: Default::default(),
1977 default_alias_style: Default::default(),
1978 type_alias: Default::default(),
1979 new_type_alias: Default::default(),
1980 new_type_alias_deref: Default::default(),
1981 builtins: false,
1982 emit_ast: false,
1983 emit_ir: false,
1984 emit_ir_graphviz: None,
1985 layout_tests: true,
1986 impl_debug: false,
1987 impl_partialeq: false,
1988 derive_copy: true,
1989 derive_debug: true,
1990 derive_default: false,
1991 derive_hash: false,
1992 derive_partialord: false,
1993 derive_ord: false,
1994 derive_partialeq: false,
1995 derive_eq: false,
1996 enable_cxx_namespaces: false,
1997 enable_function_attribute_detection: false,
1998 disable_name_namespacing: false,
1999 disable_nested_struct_naming: false,
2000 disable_header_comment: false,
2001 use_core: false,
2002 ctypes_prefix: None,
2003 anon_fields_prefix: DEFAULT_ANON_FIELDS_PREFIX.into(),
2004 namespaced_constants: true,
2005 msvc_mangling: false,
2006 convert_floats: true,
2007 raw_lines: vec![],
2008 module_lines: HashMap::default(),
2009 clang_args: vec![],
2010 input_header: None,
2011 input_unsaved_files: vec![],
2012 parse_callbacks: None,
2013 codegen_config: CodegenConfig::all(),
2014 conservative_inline_namespaces: false,
2015 generate_comments: true,
2016 generate_inline_functions: false,
2017 allowlist_recursively: true,
2018 generate_block: false,
2019 objc_extern_crate: false,
2020 block_extern_crate: false,
2021 enable_mangling: true,
2022 detect_include_paths: true,
2023 fit_macro_constants: false,
2024 prepend_enum_name: true,
2025 time_phases: false,
2026 record_matches: true,
2027 rustfmt_bindings: true,
2028 size_t_is_usize: false,
2029 rustfmt_configuration_file: None,
2030 no_partialeq_types: Default::default(),
2031 no_copy_types: Default::default(),
2032 no_debug_types: Default::default(),
2033 no_default_types: Default::default(),
2034 no_hash_types: Default::default(),
2035 array_pointers_in_arguments: false,
2036 wasm_import_module_name: None,
2037 dynamic_library_name: None,
2038 dynamic_link_require_all: false,
2039 respect_cxx_access_specs: false,
2040 translate_enum_integer_types: false,
2041 }
2042 }
2043 }
2044
2045 #[cfg(feature = "runtime")]
ensure_libclang_is_loaded()2046 fn ensure_libclang_is_loaded() {
2047 if clang_sys::is_loaded() {
2048 return;
2049 }
2050
2051 // XXX (issue #350): Ensure that our dynamically loaded `libclang`
2052 // doesn't get dropped prematurely, nor is loaded multiple times
2053 // across different threads.
2054
2055 lazy_static! {
2056 static ref LIBCLANG: std::sync::Arc<clang_sys::SharedLibrary> = {
2057 clang_sys::load().expect("Unable to find libclang");
2058 clang_sys::get_library().expect(
2059 "We just loaded libclang and it had better still be \
2060 here!",
2061 )
2062 };
2063 }
2064
2065 clang_sys::set_library(Some(LIBCLANG.clone()));
2066 }
2067
2068 #[cfg(not(feature = "runtime"))]
ensure_libclang_is_loaded()2069 fn ensure_libclang_is_loaded() {}
2070
2071 /// Generated Rust bindings.
2072 #[derive(Debug)]
2073 pub struct Bindings {
2074 options: BindgenOptions,
2075 module: proc_macro2::TokenStream,
2076 }
2077
2078 pub(crate) const HOST_TARGET: &'static str =
2079 include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
2080
2081 // Some architecture triplets are different between rust and libclang, see #1211
2082 // and duplicates.
rust_to_clang_target(rust_target: &str) -> String2083 fn rust_to_clang_target(rust_target: &str) -> String {
2084 if rust_target.starts_with("aarch64-apple-") {
2085 let mut clang_target = "arm64-apple-".to_owned();
2086 clang_target.push_str(&rust_target["aarch64-apple-".len()..]);
2087 return clang_target;
2088 }
2089 rust_target.to_owned()
2090 }
2091
2092 /// Returns the effective target, and whether it was explicitly specified on the
2093 /// clang flags.
find_effective_target(clang_args: &[String]) -> (String, bool)2094 fn find_effective_target(clang_args: &[String]) -> (String, bool) {
2095 let mut args = clang_args.iter();
2096 while let Some(opt) = args.next() {
2097 if opt.starts_with("--target=") {
2098 let mut split = opt.split('=');
2099 split.next();
2100 return (split.next().unwrap().to_owned(), true);
2101 }
2102
2103 if opt == "-target" {
2104 if let Some(target) = args.next() {
2105 return (target.clone(), true);
2106 }
2107 }
2108 }
2109
2110 // If we're running from a build script, try to find the cargo target.
2111 if let Ok(t) = env::var("TARGET") {
2112 return (rust_to_clang_target(&t), false);
2113 }
2114
2115 (rust_to_clang_target(HOST_TARGET), false)
2116 }
2117
2118 impl Bindings {
2119 /// Generate bindings for the given options.
generate( mut options: BindgenOptions, ) -> Result<Bindings, ()>2120 pub(crate) fn generate(
2121 mut options: BindgenOptions,
2122 ) -> Result<Bindings, ()> {
2123 ensure_libclang_is_loaded();
2124
2125 #[cfg(feature = "runtime")]
2126 debug!(
2127 "Generating bindings, libclang at {}",
2128 clang_sys::get_library().unwrap().path().display()
2129 );
2130 #[cfg(not(feature = "runtime"))]
2131 debug!("Generating bindings, libclang linked");
2132
2133 options.build();
2134
2135 let (effective_target, explicit_target) =
2136 find_effective_target(&options.clang_args);
2137
2138 let is_host_build =
2139 rust_to_clang_target(HOST_TARGET) == effective_target;
2140
2141 // NOTE: The is_host_build check wouldn't be sound normally in some
2142 // cases if we were to call a binary (if you have a 32-bit clang and are
2143 // building on a 64-bit system for example). But since we rely on
2144 // opening libclang.so, it has to be the same architecture and thus the
2145 // check is fine.
2146 if !explicit_target && !is_host_build {
2147 options
2148 .clang_args
2149 .insert(0, format!("--target={}", effective_target));
2150 };
2151
2152 fn detect_include_paths(options: &mut BindgenOptions) {
2153 if !options.detect_include_paths {
2154 return;
2155 }
2156
2157 // Filter out include paths and similar stuff, so we don't incorrectly
2158 // promote them to `-isystem`.
2159 let clang_args_for_clang_sys = {
2160 let mut last_was_include_prefix = false;
2161 options
2162 .clang_args
2163 .iter()
2164 .filter(|arg| {
2165 if last_was_include_prefix {
2166 last_was_include_prefix = false;
2167 return false;
2168 }
2169
2170 let arg = &**arg;
2171
2172 // https://clang.llvm.org/docs/ClangCommandLineReference.html
2173 // -isystem and -isystem-after are harmless.
2174 if arg == "-I" || arg == "--include-directory" {
2175 last_was_include_prefix = true;
2176 return false;
2177 }
2178
2179 if arg.starts_with("-I") ||
2180 arg.starts_with("--include-directory=")
2181 {
2182 return false;
2183 }
2184
2185 true
2186 })
2187 .cloned()
2188 .collect::<Vec<_>>()
2189 };
2190
2191 debug!(
2192 "Trying to find clang with flags: {:?}",
2193 clang_args_for_clang_sys
2194 );
2195
2196 let clang = match clang_sys::support::Clang::find(
2197 None,
2198 &clang_args_for_clang_sys,
2199 ) {
2200 None => return,
2201 Some(clang) => clang,
2202 };
2203
2204 debug!("Found clang: {:?}", clang);
2205
2206 // Whether we are working with C or C++ inputs.
2207 let is_cpp = args_are_cpp(&options.clang_args) ||
2208 options
2209 .input_header
2210 .as_ref()
2211 .map_or(false, |i| file_is_cpp(&i));
2212
2213 let search_paths = if is_cpp {
2214 clang.cpp_search_paths
2215 } else {
2216 clang.c_search_paths
2217 };
2218
2219 if let Some(search_paths) = search_paths {
2220 for path in search_paths.into_iter() {
2221 if let Ok(path) = path.into_os_string().into_string() {
2222 options.clang_args.push("-isystem".to_owned());
2223 options.clang_args.push(path);
2224 }
2225 }
2226 }
2227 }
2228
2229 detect_include_paths(&mut options);
2230
2231 #[cfg(unix)]
2232 fn can_read(perms: &std::fs::Permissions) -> bool {
2233 use std::os::unix::fs::PermissionsExt;
2234 perms.mode() & 0o444 > 0
2235 }
2236
2237 #[cfg(not(unix))]
2238 fn can_read(_: &std::fs::Permissions) -> bool {
2239 true
2240 }
2241
2242 if let Some(h) = options.input_header.as_ref() {
2243 if let Ok(md) = std::fs::metadata(h) {
2244 if md.is_dir() {
2245 eprintln!("error: '{}' is a folder", h);
2246 return Err(());
2247 }
2248 if !can_read(&md.permissions()) {
2249 eprintln!(
2250 "error: insufficient permissions to read '{}'",
2251 h
2252 );
2253 return Err(());
2254 }
2255 options.clang_args.push(h.clone())
2256 } else {
2257 eprintln!("error: header '{}' does not exist.", h);
2258 return Err(());
2259 }
2260 }
2261
2262 for (idx, f) in options.input_unsaved_files.iter().enumerate() {
2263 if idx != 0 || options.input_header.is_some() {
2264 options.clang_args.push("-include".to_owned());
2265 }
2266 options.clang_args.push(f.name.to_str().unwrap().to_owned())
2267 }
2268
2269 debug!("Fixed-up options: {:?}", options);
2270
2271 let time_phases = options.time_phases;
2272 let mut context = BindgenContext::new(options);
2273
2274 if is_host_build {
2275 debug_assert_eq!(
2276 context.target_pointer_size(),
2277 std::mem::size_of::<*mut ()>(),
2278 "{:?} {:?}",
2279 effective_target,
2280 HOST_TARGET
2281 );
2282 }
2283
2284 {
2285 let _t = time::Timer::new("parse").with_output(time_phases);
2286 parse(&mut context)?;
2287 }
2288
2289 let (items, options) = codegen::codegen(context);
2290
2291 Ok(Bindings {
2292 options,
2293 module: quote! {
2294 #( #items )*
2295 },
2296 })
2297 }
2298
2299 /// Convert these bindings into source text (with raw lines prepended).
to_string(&self) -> String2300 pub fn to_string(&self) -> String {
2301 let mut bytes = vec![];
2302 self.write(Box::new(&mut bytes) as Box<dyn Write>)
2303 .expect("writing to a vec cannot fail");
2304 String::from_utf8(bytes)
2305 .expect("we should only write bindings that are valid utf-8")
2306 }
2307
2308 /// Write these bindings as source text to a file.
write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()>2309 pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
2310 let file = OpenOptions::new()
2311 .write(true)
2312 .truncate(true)
2313 .create(true)
2314 .open(path.as_ref())?;
2315 self.write(Box::new(file))?;
2316 Ok(())
2317 }
2318
2319 /// Write these bindings as source text to the given `Write`able.
write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()>2320 pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()> {
2321 if !self.options.disable_header_comment {
2322 let version = Some("0.58.1");
2323 let header = format!(
2324 "/* automatically generated by rust-bindgen {} */\n\n",
2325 version.unwrap_or("(unknown version)")
2326 );
2327 writer.write_all(header.as_bytes())?;
2328 }
2329
2330 for line in self.options.raw_lines.iter() {
2331 writer.write_all(line.as_bytes())?;
2332 writer.write_all("\n".as_bytes())?;
2333 }
2334
2335 if !self.options.raw_lines.is_empty() {
2336 writer.write_all("\n".as_bytes())?;
2337 }
2338
2339 let bindings = self.module.to_string();
2340
2341 match self.rustfmt_generated_string(&bindings) {
2342 Ok(rustfmt_bindings) => {
2343 writer.write_all(rustfmt_bindings.as_bytes())?;
2344 }
2345 Err(err) => {
2346 eprintln!(
2347 "Failed to run rustfmt: {} (non-fatal, continuing)",
2348 err
2349 );
2350 writer.write_all(bindings.as_bytes())?;
2351 }
2352 }
2353 Ok(())
2354 }
2355
2356 /// Gets the rustfmt path to rustfmt the generated bindings.
rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>>2357 fn rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>> {
2358 debug_assert!(self.options.rustfmt_bindings);
2359 if let Some(ref p) = self.options.rustfmt_path {
2360 return Ok(Cow::Borrowed(p));
2361 }
2362 if let Ok(rustfmt) = env::var("RUSTFMT") {
2363 return Ok(Cow::Owned(rustfmt.into()));
2364 }
2365 #[cfg(feature = "which-rustfmt")]
2366 match which::which("rustfmt") {
2367 Ok(p) => Ok(Cow::Owned(p)),
2368 Err(e) => {
2369 Err(io::Error::new(io::ErrorKind::Other, format!("{}", e)))
2370 }
2371 }
2372 #[cfg(not(feature = "which-rustfmt"))]
2373 // No rustfmt binary was specified, so assume that the binary is called
2374 // "rustfmt" and that it is in the user's PATH.
2375 Ok(Cow::Owned("rustfmt".into()))
2376 }
2377
2378 /// Checks if rustfmt_bindings is set and runs rustfmt on the string
rustfmt_generated_string<'a>( &self, source: &'a str, ) -> io::Result<Cow<'a, str>>2379 fn rustfmt_generated_string<'a>(
2380 &self,
2381 source: &'a str,
2382 ) -> io::Result<Cow<'a, str>> {
2383 let _t = time::Timer::new("rustfmt_generated_string")
2384 .with_output(self.options.time_phases);
2385
2386 if !self.options.rustfmt_bindings {
2387 return Ok(Cow::Borrowed(source));
2388 }
2389
2390 let rustfmt = self.rustfmt_path()?;
2391 let mut cmd = Command::new(&*rustfmt);
2392
2393 cmd.stdin(Stdio::piped()).stdout(Stdio::piped());
2394
2395 if let Some(path) = self
2396 .options
2397 .rustfmt_configuration_file
2398 .as_ref()
2399 .and_then(|f| f.to_str())
2400 {
2401 cmd.args(&["--config-path", path]);
2402 }
2403
2404 let mut child = cmd.spawn()?;
2405 let mut child_stdin = child.stdin.take().unwrap();
2406 let mut child_stdout = child.stdout.take().unwrap();
2407
2408 let source = source.to_owned();
2409
2410 // Write to stdin in a new thread, so that we can read from stdout on this
2411 // thread. This keeps the child from blocking on writing to its stdout which
2412 // might block us from writing to its stdin.
2413 let stdin_handle = ::std::thread::spawn(move || {
2414 let _ = child_stdin.write_all(source.as_bytes());
2415 source
2416 });
2417
2418 let mut output = vec![];
2419 io::copy(&mut child_stdout, &mut output)?;
2420
2421 let status = child.wait()?;
2422 let source = stdin_handle.join().expect(
2423 "The thread writing to rustfmt's stdin doesn't do \
2424 anything that could panic",
2425 );
2426
2427 match String::from_utf8(output) {
2428 Ok(bindings) => match status.code() {
2429 Some(0) => Ok(Cow::Owned(bindings)),
2430 Some(2) => Err(io::Error::new(
2431 io::ErrorKind::Other,
2432 "Rustfmt parsing errors.".to_string(),
2433 )),
2434 Some(3) => {
2435 warn!("Rustfmt could not format some lines.");
2436 Ok(Cow::Owned(bindings))
2437 }
2438 _ => Err(io::Error::new(
2439 io::ErrorKind::Other,
2440 "Internal rustfmt error".to_string(),
2441 )),
2442 },
2443 _ => Ok(Cow::Owned(source)),
2444 }
2445 }
2446 }
2447
2448 /// Determines whether the given cursor is in any of the files matched by the
2449 /// options.
filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool2450 fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
2451 ctx.options().builtins || !cursor.is_builtin()
2452 }
2453
2454 /// Parse one `Item` from the Clang cursor.
parse_one( ctx: &mut BindgenContext, cursor: clang::Cursor, parent: Option<ItemId>, ) -> clang_sys::CXChildVisitResult2455 fn parse_one(
2456 ctx: &mut BindgenContext,
2457 cursor: clang::Cursor,
2458 parent: Option<ItemId>,
2459 ) -> clang_sys::CXChildVisitResult {
2460 if !filter_builtins(ctx, &cursor) {
2461 return CXChildVisit_Continue;
2462 }
2463
2464 use clang_sys::CXChildVisit_Continue;
2465 match Item::parse(cursor, parent, ctx) {
2466 Ok(..) => {}
2467 Err(ParseError::Continue) => {}
2468 Err(ParseError::Recurse) => {
2469 cursor.visit(|child| parse_one(ctx, child, parent));
2470 }
2471 }
2472 CXChildVisit_Continue
2473 }
2474
2475 /// Parse the Clang AST into our `Item` internal representation.
parse(context: &mut BindgenContext) -> Result<(), ()>2476 fn parse(context: &mut BindgenContext) -> Result<(), ()> {
2477 use clang_sys::*;
2478
2479 let mut any_error = false;
2480 for d in context.translation_unit().diags().iter() {
2481 let msg = d.format();
2482 let is_err = d.severity() >= CXDiagnostic_Error;
2483 eprintln!("{}, err: {}", msg, is_err);
2484 any_error |= is_err;
2485 }
2486
2487 if any_error {
2488 return Err(());
2489 }
2490
2491 let cursor = context.translation_unit().cursor();
2492
2493 if context.options().emit_ast {
2494 fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult {
2495 if !cur.is_builtin() {
2496 clang::ast_dump(&cur, 0)
2497 } else {
2498 CXChildVisit_Continue
2499 }
2500 }
2501 cursor.visit(|cur| dump_if_not_builtin(&cur));
2502 }
2503
2504 let root = context.root_module();
2505 context.with_module(root, |context| {
2506 cursor.visit(|cursor| parse_one(context, cursor, None))
2507 });
2508
2509 assert!(
2510 context.current_module() == context.root_module(),
2511 "How did this happen?"
2512 );
2513 Ok(())
2514 }
2515
2516 /// Extracted Clang version data
2517 #[derive(Debug)]
2518 pub struct ClangVersion {
2519 /// Major and minor semver, if parsing was successful
2520 pub parsed: Option<(u32, u32)>,
2521 /// full version string
2522 pub full: String,
2523 }
2524
2525 /// Get the major and the minor semver numbers of Clang's version
clang_version() -> ClangVersion2526 pub fn clang_version() -> ClangVersion {
2527 ensure_libclang_is_loaded();
2528
2529 //Debian clang version 11.0.1-2
2530 let raw_v: String = clang::extract_clang_version();
2531 let split_v: Option<Vec<&str>> = raw_v
2532 .split_whitespace()
2533 .filter(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit()))
2534 .next()
2535 .map(|v| v.split('.').collect());
2536 match split_v {
2537 Some(v) => {
2538 if v.len() >= 2 {
2539 let maybe_major = v[0].parse::<u32>();
2540 let maybe_minor = v[1].parse::<u32>();
2541 match (maybe_major, maybe_minor) {
2542 (Ok(major), Ok(minor)) => {
2543 return ClangVersion {
2544 parsed: Some((major, minor)),
2545 full: raw_v.clone(),
2546 }
2547 }
2548 _ => {}
2549 }
2550 }
2551 }
2552 None => {}
2553 };
2554 ClangVersion {
2555 parsed: None,
2556 full: raw_v.clone(),
2557 }
2558 }
2559
2560 /// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed
2561 /// line
2562 ///
2563 /// When running in side a `build.rs` script, this can be used to make cargo invalidate the
2564 /// generated bindings whenever any of the files included from the header change:
2565 /// ```
2566 /// use bindgen::builder;
2567 /// let bindings = builder()
2568 /// .header("path/to/input/header")
2569 /// .parse_callbacks(Box::new(bindgen::CargoCallbacks))
2570 /// .generate();
2571 /// ```
2572 #[derive(Debug)]
2573 pub struct CargoCallbacks;
2574
2575 impl callbacks::ParseCallbacks for CargoCallbacks {
include_file(&self, filename: &str)2576 fn include_file(&self, filename: &str) {
2577 println!("cargo:rerun-if-changed={}", filename);
2578 }
2579 }
2580
2581 /// Test command_line_flag function.
2582 #[test]
commandline_flag_unit_test_function()2583 fn commandline_flag_unit_test_function() {
2584 //Test 1
2585 let bindings = crate::builder();
2586 let command_line_flags = bindings.command_line_flags();
2587
2588 let test_cases = vec![
2589 "--rust-target",
2590 "--no-derive-default",
2591 "--generate",
2592 "functions,types,vars,methods,constructors,destructors",
2593 ]
2594 .iter()
2595 .map(|&x| x.into())
2596 .collect::<Vec<String>>();
2597
2598 assert!(test_cases
2599 .iter()
2600 .all(|ref x| command_line_flags.contains(x),));
2601
2602 //Test 2
2603 let bindings = crate::builder()
2604 .header("input_header")
2605 .allowlist_type("Distinct_Type")
2606 .allowlist_function("safe_function");
2607
2608 let command_line_flags = bindings.command_line_flags();
2609 let test_cases = vec![
2610 "--rust-target",
2611 "input_header",
2612 "--no-derive-default",
2613 "--generate",
2614 "functions,types,vars,methods,constructors,destructors",
2615 "--allowlist-type",
2616 "Distinct_Type",
2617 "--allowlist-function",
2618 "safe_function",
2619 ]
2620 .iter()
2621 .map(|&x| x.into())
2622 .collect::<Vec<String>>();
2623 println!("{:?}", command_line_flags);
2624
2625 assert!(test_cases
2626 .iter()
2627 .all(|ref x| command_line_flags.contains(x),));
2628 }
2629
2630 #[test]
test_rust_to_clang_target()2631 fn test_rust_to_clang_target() {
2632 assert_eq!(rust_to_clang_target("aarch64-apple-ios"), "arm64-apple-ios");
2633 }
2634