• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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