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