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