-
Notifications
You must be signed in to change notification settings - Fork 739
/
Copy pathmod.rs
2257 lines (2208 loc) · 90.5 KB
/
mod.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//! Declarations and setter methods for `bindgen` options.
//!
//! The main entry point of this module is the `options` macro.
#[macro_use]
mod helpers;
mod as_args;
#[cfg(feature = "__cli")]
pub(crate) mod cli;
use crate::callbacks::ParseCallbacks;
use crate::codegen::{
AliasVariation, EnumVariation, MacroTypeVariation, NonCopyUnionStyle,
};
use crate::deps::DepfileSpec;
use crate::features::{RustEdition, RustFeatures, RustTarget};
use crate::regex_set::RegexSet;
use crate::Abi;
use crate::Builder;
use crate::CodegenConfig;
use crate::FieldVisibilityKind;
use crate::Formatter;
use crate::HashMap;
use crate::DEFAULT_ANON_FIELDS_PREFIX;
use std::env;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use as_args::AsArgs;
use helpers::ignore;
/// Macro used to generate the [`BindgenOptions`] type and the [`Builder`] setter methods for each
/// one of the fields of `BindgenOptions`.
///
/// The input format of this macro resembles a `struct` pattern. Each field of the `BindgenOptions`
/// type is declared by adding the name of the field and its type using the `name: type` syntax and
/// a block of code with the following items:
///
/// - `default`: The default value for the field. If this item is omitted, `Default::default()` is
/// used instead, meaning that the type of the field must implement `Default`.
/// - `methods`: A block of code containing methods for the `Builder` type. These methods should be
/// related to the field being declared.
/// - `as_args`: This item declares how the field should be converted into a valid CLI argument for
/// `bindgen` and is used in the [`Builder::command_line_flags`] method which is used to do a
/// roundtrip test of the CLI args in the `bindgen-test` crate. This item can take one of the
/// following:
/// - A string literal with the flag if the type of the field implements the [`AsArgs`] trait.
/// - A closure with the signature `|field, args: &mut Vec<String>| -> ()` that pushes arguments
/// into the `args` buffer based on the value of the field. This is used if the field does not
/// implement `AsArgs` or if the implementation of the trait is not logically correct for the
/// option and a custom behavior must be taken into account.
/// - The `ignore` literal, which does not emit any CLI arguments for this field. This is useful
/// if the field cannot be used from the `bindgen` CLI.
///
/// As an example, this would be the declaration of a `bool` field called `be_fun` whose default
/// value is `false` (the `Default` value for `bool`):
/// ```rust,ignore
/// be_fun: bool {
/// methods: {
/// /// Ask `bindgen` to be fun. This option is disabled by default.
/// fn be_fun(mut self) -> Self {
/// self.options.be_fun = true;
/// self
/// }
/// },
/// as_args: "--be-fun",
/// }
/// ```
///
/// However, we could also set the `be_fun` field to `true` by default and use a `--not-fun` flag
/// instead. This means that we have to add the `default` item and use a closure in the `as_args`
/// item:
/// ```rust,ignore
/// be_fun: bool {
/// default: true,
/// methods: {
/// /// Ask `bindgen` to not be fun. `bindgen` is fun by default.
/// fn not_fun(mut self) -> Self {
/// self.options.be_fun = false;
/// self
/// }
/// },
/// as_args: |be_fun, args| (!be_fun).as_args(args, "--not-fun"),
/// }
/// ```
/// More complex examples can be found in the sole invocation of this macro.
macro_rules! options {
($(
$(#[doc = $docs:literal])+
$field:ident: $ty:ty {
$(default: $default:expr,)?
methods: {$($methods_tokens:tt)*}$(,)?
as_args: $as_args:expr$(,)?
}$(,)?
)*) => {
#[derive(Debug, Clone)]
pub(crate) struct BindgenOptions {
$($(#[doc = $docs])* pub(crate) $field: $ty,)*
}
impl Default for BindgenOptions {
fn default() -> Self {
Self {
$($field: default!($($default)*),)*
}
}
}
impl Builder {
/// Generates the command line flags used to create this [`Builder`].
pub fn command_line_flags(&self) -> Vec<String> {
let mut args = vec![];
let headers = match self.options.input_headers.split_last() {
Some((header, headers)) => {
// The last input header is passed as an argument in the first position.
args.push(header.clone().into());
headers
},
None => &[]
};
$({
let func: fn(&$ty, &mut Vec<String>) = as_args!($as_args);
func(&self.options.$field, &mut args);
})*
// Add the `--experimental` flag if `bindgen` is built with the `experimental`
// feature.
if cfg!(feature = "experimental") {
args.push("--experimental".to_owned());
}
// Add all the clang arguments.
args.push("--".to_owned());
if !self.options.clang_args.is_empty() {
args.extend(self.options.clang_args.iter().map(|s| s.clone().into()));
}
// We need to pass all but the last header via the `-include` clang argument.
for header in headers {
args.push("-include".to_owned());
args.push(header.clone().into());
}
args
}
$($($methods_tokens)*)*
}
};
}
options! {
/// Whether to specify the type of a virtual function receiver
use_specific_virtual_function_receiver: bool {
methods: {
/// Normally, virtual functions have void* as their 'this' type.
/// If this flag is enabled, override that behavior to indicate a
/// pointer of the specific type.
/// Disabled by default.
pub fn use_specific_virtual_function_receiver(mut self, doit: bool) -> Builder {
self.options.use_specific_virtual_function_receiver = doit;
self
}
},
as_args: "--use-specific-virtual-function-receiver",
},
/// Use a newtype wrapper to clearly denote "opaque" types; that is,
/// types where bindgen has generated a type matching the size and
/// alignment of the C++ type but without any knowledge of what's
/// inside it. The newtype wrapper will be a fake type called
/// `bindgen_marker_Opaque`. It's assumed that you will replace this with some
/// real sensible newtype wrapper of your own, either by post-processing
/// the output of bindgen, or by using a `use` statemet injected using
/// `--module-raw-lines` or similar.
use_opaque_newtype_wrapper: bool {
methods: {
/// If this is true, wrap opaque types in a fake newtype
/// wrapper which post-processors can replace with something
/// more sensible.
pub fn use_opaque_newtype_wrapper(mut self, doit: bool) -> Builder {
self.options.use_opaque_newtype_wrapper = doit;
self
}
},
as_args: "--use-opaque-newtype-wrapper",
},
/// Use a newtype wrapper to clearly denote C++ reference types.
/// These are always generated as raw Rust pointers, and so otherwise
/// there's no way to distinguish references from pointers.
/// The newtype wrapper will be a fake type either called
/// `bindgen_marker_Reference` or `bindgen_marker_RVAlueReference`.
/// It's assumed that you will replace this with some
/// real sensible newtype wrapper of your own, either by post-processing
/// the output of bindgen, or by using a `use` statemet injected using
/// `--module-raw-lines` or similar.
use_reference_newtype_wrapper: bool {
methods: {
/// If this is true, wrap C++ references in a fake newtype
/// wrapper which post-processors can replace with something
/// more sensible.
pub fn use_reference_newtype_wrapper(mut self, doit: bool) -> Builder {
self.options.use_reference_newtype_wrapper = doit;
self
}
},
as_args: "--use-reference-newtype-wrapper",
},
/// Whether we should distinguish between C++'s 'char16_t' and 'u16'.
/// The C++ type `char16_t` is its own special type; it's not a typedef
/// of some other integer (this differs from C).
/// As standard, bindgen represents C++ `char16_t` as `u16`.
/// Rust does not have a `std::os::raw::c_char16_t` type, and thus
/// we can't use a built-in Rust type in the generated bindings (and
/// nor would it be appropriate as it's a C++-specific type.)
/// But for some uses of bindgen, especially when downstream
/// post-processing occurs, it's important to distinguish `char16_t`
/// from normal `uint16_t`. When this option is enabled, bindgen
/// generates a fake type called `bindgen_cchar16_t`. Downstream
/// code post-processors should arrange to replace this with a
/// real type.
use_distinct_char16_t: bool {
methods: {
/// If this is true, denote 'char16_t' as a separate type from 'u16'
/// Disabled by default.
pub fn use_distinct_char16_t(mut self, doit: bool) -> Builder {
self.options.use_distinct_char16_t = doit;
self
}
},
as_args: "--use-distinct-char16-t",
},
/// Types that have been blocklisted and should not appear anywhere in the generated code.
blocklisted_types: RegexSet {
methods: {
regex_option! {
/// Do not generate any bindings for the given type.
///
/// This option is not recursive, meaning that it will only block types whose names
/// explicitly match the argument of this method.
pub fn blocklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.blocklisted_types.insert(arg);
self
}
}
},
as_args: "--blocklist-type",
},
/// Functions that have been blocklisted and should not appear in the generated code.
blocklisted_functions: RegexSet {
methods: {
regex_option! {
/// Do not generate any bindings for the given function.
///
/// This option is not recursive, meaning that it will only block functions whose
/// names explicitly match the argument of this method.
pub fn blocklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.blocklisted_functions.insert(arg);
self
}
}
},
as_args: "--blocklist-function",
},
/// Items that have been blocklisted and should not appear in the generated code.
blocklisted_items: RegexSet {
methods: {
regex_option! {
/// Do not generate any bindings for the given item, regardless of whether it is a
/// type, function, module, etc.
///
/// This option is not recursive, meaning that it will only block items whose names
/// explicitly match the argument of this method.
pub fn blocklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.blocklisted_items.insert(arg);
self
}
}
},
as_args: "--blocklist-item",
},
/// Files whose contents should be blocklisted and should not appear in the generated code.
blocklisted_files: RegexSet {
methods: {
regex_option! {
/// Do not generate any bindings for the contents of the given file, regardless of
/// whether the contents of the file are types, functions, modules, etc.
///
/// This option is not recursive, meaning that it will only block files whose names
/// explicitly match the argument of this method.
///
/// This method will use the argument to match the complete path of the file
/// instead of a section of it.
pub fn blocklist_file<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.blocklisted_files.insert(arg);
self
}
}
},
as_args: "--blocklist-file",
},
/// Variables that have been blocklisted and should not appear in the generated code.
blocklisted_vars: RegexSet {
methods: {
regex_option! {
/// Do not generate any bindings for the given variable.
///
/// This option is not recursive, meaning that it will only block variables whose
/// names explicitly match the argument of this method.
pub fn blocklist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.blocklisted_vars.insert(arg);
self
}
}
},
as_args: "--blocklist-var",
},
/// Types that should be treated as opaque structures in the generated code.
opaque_types: RegexSet {
methods: {
regex_option! {
/// Treat the given type as opaque in the generated bindings.
///
/// Opaque in this context means that none of the generated bindings will contain
/// information about the inner representation of the type and the type itself will
/// be represented as a chunk of bytes with the alignment and size of the type.
pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.opaque_types.insert(arg);
self
}
}
},
as_args: "--opaque-type",
},
/// The explicit `rustfmt` path.
rustfmt_path: Option<PathBuf> {
methods: {
/// Set an explicit path to the `rustfmt` binary.
///
/// This option only comes into effect if `rustfmt` is set to be the formatter used by
/// `bindgen`. Check the documentation of the [`Builder::formatter`] method for more
/// information.
pub fn with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self {
self.options.rustfmt_path = Some(path.into());
self
}
},
// This option cannot be set from the CLI.
as_args: ignore,
},
/// The path to which we should write a Makefile-syntax depfile (if any).
depfile: Option<DepfileSpec> {
methods: {
/// Add a depfile output which will be written alongside the generated bindings.
pub fn depfile<H: Into<String>, D: Into<PathBuf>>(
mut self,
output_module: H,
depfile: D,
) -> Builder {
self.options.depfile = Some(DepfileSpec {
output_module: output_module.into(),
depfile_path: depfile.into(),
});
self
}
},
as_args: |depfile, args| {
if let Some(depfile) = depfile {
args.push("--depfile".into());
args.push(depfile.depfile_path.display().to_string());
}
},
},
/// Types that have been allowlisted and should appear in the generated code.
allowlisted_types: RegexSet {
methods: {
regex_option! {
/// Generate bindings for the given type.
///
/// This option is transitive by default. Check the documentation of the
/// [`Builder::allowlist_recursively`] method for further information.
pub fn allowlist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.allowlisted_types.insert(arg);
self
}
}
},
as_args: "--allowlist-type",
},
/// Functions that have been allowlisted and should appear in the generated code.
allowlisted_functions: RegexSet {
methods: {
regex_option! {
/// Generate bindings for the given function.
///
/// This option is transitive by default. Check the documentation of the
/// [`Builder::allowlist_recursively`] method for further information.
pub fn allowlist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.allowlisted_functions.insert(arg);
self
}
}
},
as_args: "--allowlist-function",
},
/// Variables that have been allowlisted and should appear in the generated code.
allowlisted_vars: RegexSet {
methods: {
regex_option! {
/// Generate bindings for the given variable.
///
/// This option is transitive by default. Check the documentation of the
/// [`Builder::allowlist_recursively`] method for further information.
pub fn allowlist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.allowlisted_vars.insert(arg);
self
}
}
},
as_args: "--allowlist-var",
},
/// Files whose contents have been allowlisted and should appear in the generated code.
allowlisted_files: RegexSet {
methods: {
regex_option! {
/// Generate bindings for the content of the given file.
///
/// This option is transitive by default. Check the documentation of the
/// [`Builder::allowlist_recursively`] method for further information.
///
/// This method will use the argument to match the complete path of the file
/// instead of a section of it.
pub fn allowlist_file<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.allowlisted_files.insert(arg);
self
}
}
},
as_args: "--allowlist-file",
},
/// Items that have been allowlisted and should appear in the generated code.
allowlisted_items: RegexSet {
methods: {
regex_option! {
/// Generate bindings for the given item, regardless of whether it is a type,
/// function, module, etc.
///
/// This option is transitive by default. Check the documentation of the
/// [`Builder::allowlist_recursively`] method for further information.
pub fn allowlist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.allowlisted_items.insert(arg);
self
}
}
},
as_args: "--allowlist-item",
},
/// The default style of for generated `enum`s.
default_enum_style: EnumVariation {
methods: {
/// Set the default style for generated `enum`s.
///
/// If this method is not called, the [`EnumVariation::Consts`] style will be used by
/// default.
///
/// To set the style for individual `enum`s, use [`Builder::bitfield_enum`],
/// [`Builder::newtype_enum`], [`Builder::newtype_global_enum`],
/// [`Builder::rustified_enum`], [`Builder::rustified_non_exhaustive_enum`],
/// [`Builder::constified_enum_module`] or [`Builder::constified_enum`].
pub fn default_enum_style(
mut self,
arg: EnumVariation,
) -> Builder {
self.options.default_enum_style = arg;
self
}
},
as_args: |variation, args| {
if *variation != Default::default() {
args.push("--default-enum-style".to_owned());
args.push(variation.to_string());
}
},
},
/// `enum`s marked as bitfield-like. This is, newtypes with bitwise operations.
bitfield_enums: RegexSet {
methods: {
regex_option! {
/// Mark the given `enum` as being bitfield-like.
///
/// This is similar to the [`Builder::newtype_enum`] style, but with the bitwise
/// operators implemented.
pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.bitfield_enums.insert(arg);
self
}
}
},
as_args: "--bitfield-enum",
},
/// `enum`s marked as newtypes.
newtype_enums: RegexSet {
methods: {
regex_option! {
/// Mark the given `enum` as a newtype.
///
/// This means that an integer newtype will be declared to represent the `enum`
/// type and its variants will be represented as constants inside of this type's
/// `impl` block.
pub fn newtype_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.newtype_enums.insert(arg);
self
}
}
},
as_args: "--newtype-enum",
},
/// `enum`s marked as global newtypes .
newtype_global_enums: RegexSet {
methods: {
regex_option! {
/// Mark the given `enum` as a global newtype.
///
/// This is similar to the [`Builder::newtype_enum`] style, but the constants for
/// each variant are free constants instead of being declared inside an `impl`
/// block for the newtype.
pub fn newtype_global_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.newtype_global_enums.insert(arg);
self
}
}
},
as_args: "--newtype-global-enum",
},
/// `enum`s marked as Rust `enum`s.
rustified_enums: RegexSet {
methods: {
regex_option! {
/// Mark the given `enum` as a Rust `enum`.
///
/// This means that each variant of the `enum` will be represented as a Rust `enum`
/// variant.
///
/// **Use this with caution**, creating an instance of a Rust `enum` with an
/// invalid value will cause undefined behaviour. To avoid this, use the
/// [`Builder::newtype_enum`] style instead.
pub fn rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.rustified_enums.insert(arg);
self
}
}
},
as_args: "--rustified-enum",
},
/// `enum`s marked as non-exhaustive Rust `enum`s.
rustified_non_exhaustive_enums: RegexSet {
methods: {
regex_option! {
/// Mark the given `enum` as a non-exhaustive Rust `enum`.
///
/// This is similar to the [`Builder::rustified_enum`] style, but the `enum` is
/// tagged with the `#[non_exhaustive]` attribute.
pub fn rustified_non_exhaustive_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.rustified_non_exhaustive_enums.insert(arg);
self
}
}
},
as_args: "--rustified-non-exhaustive-enums",
},
/// `enum`s marked as modules of constants.
constified_enum_modules: RegexSet {
methods: {
regex_option! {
/// Mark the given `enum` as a module with a set of integer constants.
pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.constified_enum_modules.insert(arg);
self
}
}
},
as_args: "--constified-enum-module",
},
/// `enum`s marked as a set of constants.
constified_enums: RegexSet {
methods: {
regex_option! {
/// Mark the given `enum` as a set of integer constants.
///
/// This is similar to the [`Builder::constified_enum_module`] style, but the
/// constants are generated in the current module instead of in a new module.
pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.constified_enums.insert(arg);
self
}
}
},
as_args: "--constified-enum",
},
/// The default type signedness for C macro constants.
default_macro_constant_type: MacroTypeVariation {
methods: {
/// Set the default type signedness to be used for macro constants.
///
/// If this method is not called, [`MacroTypeVariation::Unsigned`] is used by default.
///
/// To set the type for individual macro constants, use the
/// [`ParseCallbacks::int_macro`] method.
pub fn default_macro_constant_type(mut self, arg: MacroTypeVariation) -> Builder {
self.options.default_macro_constant_type = arg;
self
}
},
as_args: |variation, args| {
if *variation != Default::default() {
args.push("--default-macro-constant-type".to_owned());
args.push(variation.to_string());
}
},
},
/// The default style of code generation for `typedef`s.
default_alias_style: AliasVariation {
methods: {
/// Set the default style of code generation for `typedef`s.
///
/// If this method is not called, the [`AliasVariation::TypeAlias`] style is used by
/// default.
///
/// To set the style for individual `typedefs`s, use [`Builder::type_alias`],
/// [`Builder::new_type_alias`] or [`Builder::new_type_alias_deref`].
pub fn default_alias_style(
mut self,
arg: AliasVariation,
) -> Builder {
self.options.default_alias_style = arg;
self
}
},
as_args: |variation, args| {
if *variation != Default::default() {
args.push("--default-alias-style".to_owned());
args.push(variation.to_string());
}
},
},
/// `typedef` patterns that will use regular type aliasing.
type_alias: RegexSet {
methods: {
regex_option! {
/// Mark the given `typedef` as a regular Rust `type` alias.
///
/// This is the default behavior, meaning that this method only comes into effect
/// if a style different from [`AliasVariation::TypeAlias`] was passed to the
/// [`Builder::default_alias_style`] method.
pub fn type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.type_alias.insert(arg);
self
}
}
},
as_args: "--type-alias",
},
/// `typedef` patterns that will be aliased by creating a newtype.
new_type_alias: RegexSet {
methods: {
regex_option! {
/// Mark the given `typedef` as a Rust newtype by having the aliased
/// type be wrapped in a `struct` with `#[repr(transparent)]`.
///
/// This method can be used to enforce stricter type checking.
pub fn new_type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.new_type_alias.insert(arg);
self
}
}
},
as_args: "--new-type-alias",
},
/// `typedef` patterns that will be wrapped in a newtype implementing `Deref` and `DerefMut`.
new_type_alias_deref: RegexSet {
methods: {
regex_option! {
/// Mark the given `typedef` to be generated as a newtype that can be dereferenced.
///
/// This is similar to the [`Builder::new_type_alias`] style, but the newtype
/// implements `Deref` and `DerefMut` with the aliased type as a target.
pub fn new_type_alias_deref<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.new_type_alias_deref.insert(arg);
self
}
}
},
as_args: "--new-type-alias-deref",
},
/// The default style of code to generate for `union`s containing non-`Copy` members.
default_non_copy_union_style: NonCopyUnionStyle {
methods: {
/// Set the default style of code to generate for `union`s with non-`Copy` members.
///
/// If this method is not called, the [`NonCopyUnionStyle::BindgenWrapper`] style is
/// used by default.
///
/// To set the style for individual `union`s, use [`Builder::bindgen_wrapper_union`] or
/// [`Builder::manually_drop_union`].
pub fn default_non_copy_union_style(mut self, arg: NonCopyUnionStyle) -> Self {
self.options.default_non_copy_union_style = arg;
self
}
},
as_args: |style, args| {
if *style != Default::default() {
args.push("--default-non-copy-union-style".to_owned());
args.push(style.to_string());
}
},
},
/// The patterns marking non-`Copy` `union`s as using the `bindgen` generated wrapper.
bindgen_wrapper_union: RegexSet {
methods: {
regex_option! {
/// Mark the given `union` to use a `bindgen`-generated wrapper for its members if at
/// least one them is not `Copy`.
///
/// This is the default behavior, meaning that this method only comes into effect
/// if a style different from [`NonCopyUnionStyle::BindgenWrapper`] was passed to
/// the [`Builder::default_non_copy_union_style`] method.
pub fn bindgen_wrapper_union<T: AsRef<str>>(mut self, arg: T) -> Self {
self.options.bindgen_wrapper_union.insert(arg);
self
}
}
},
as_args: "--bindgen-wrapper-union",
},
/// The patterns marking non-`Copy` `union`s as using the `ManuallyDrop` wrapper.
manually_drop_union: RegexSet {
methods: {
regex_option! {
/// Mark the given `union` to use [`::core::mem::ManuallyDrop`] for its members if
/// at least one of them is not `Copy`.
///
/// The `ManuallyDrop` type was stabilized in Rust 1.20.0, do not use this option
/// if your target version is lower than this.
pub fn manually_drop_union<T: AsRef<str>>(mut self, arg: T) -> Self {
self.options.manually_drop_union.insert(arg);
self
}
}
},
as_args: "--manually-drop-union",
},
/// Whether we should generate built-in definitions.
builtins: bool {
methods: {
/// Generate Rust bindings for built-in definitions (for example `__builtin_va_list`).
///
/// Bindings for built-in definitions are not emitted by default.
pub fn emit_builtins(mut self) -> Builder {
self.options.builtins = true;
self
}
},
as_args: "--builtins",
},
/// Whether we should dump the Clang AST for debugging purposes.
emit_ast: bool {
methods: {
/// Emit the Clang AST to `stdout` for debugging purposes.
///
/// The Clang AST is not emitted by default.
pub fn emit_clang_ast(mut self) -> Builder {
self.options.emit_ast = true;
self
}
},
as_args: "--emit-clang-ast",
},
/// Whether we should dump our IR for debugging purposes.
emit_ir: bool {
methods: {
/// Emit the `bindgen` internal representation to `stdout` for debugging purposes.
///
/// This internal representation is not emitted by default.
pub fn emit_ir(mut self) -> Builder {
self.options.emit_ir = true;
self
}
},
as_args: "--emit-ir",
},
/// Output path for the `graphviz` DOT file.
emit_ir_graphviz: Option<String> {
methods: {
/// Set the path for the file where the`bindgen` internal representation will be
/// emitted as a graph using the `graphviz` DOT language.
///
/// This graph representation is not emitted by default.
pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
let path = path.into();
self.options.emit_ir_graphviz = Some(path);
self
}
},
as_args: "--emit-ir-graphviz",
},
/// Whether we should emulate C++ namespaces with Rust modules.
enable_cxx_namespaces: bool {
methods: {
/// Emulate C++ namespaces using Rust modules in the generated bindings.
///
/// C++ namespaces are not emulated by default.
pub fn enable_cxx_namespaces(mut self) -> Builder {
self.options.enable_cxx_namespaces = true;
self
}
},
as_args: "--enable-cxx-namespaces",
},
/// Whether we should try to find unexposed attributes in functions.
enable_function_attribute_detection: bool {
methods: {
/// Enable detecting function attributes on C functions.
///
/// This enables the following features:
/// - Add `#[must_use]` attributes to Rust items whose C counterparts are marked as so.
/// This feature also requires that the Rust target version supports the attribute.
/// - Set `!` as the return type for Rust functions whose C counterparts are marked as
/// diverging.
///
/// This option can be quite slow in some cases (check [#1465]), so it is disabled by
/// default.
///
/// [#1465]: https://github.com/rust-lang/rust-bindgen/issues/1465
pub fn enable_function_attribute_detection(mut self) -> Self {
self.options.enable_function_attribute_detection = true;
self
}
},
as_args: "--enable-function-attribute-detection",
},
/// Whether we should avoid mangling names with namespaces.
disable_name_namespacing: bool {
methods: {
/// Disable name auto-namespacing.
///
/// By default, `bindgen` mangles names like `foo::bar::Baz` to look like `foo_bar_Baz`
/// instead of just `Baz`. This method disables that behavior.
///
/// Note that this does not change the names used for allowlisting and blocklisting,
/// which should still be mangled with the namespaces. Additionally, this option may
/// cause `bindgen` to generate duplicate names.
pub fn disable_name_namespacing(mut self) -> Builder {
self.options.disable_name_namespacing = true;
self
}
},
as_args: "--disable-name-namespacing",
},
/// Whether we should avoid generating nested `struct` names.
disable_nested_struct_naming: bool {
methods: {
/// Disable nested `struct` naming.
///
/// The following `struct`s have different names for C and C++. In C, they are visible
/// as `foo` and `bar`. In C++, they are visible as `foo` and `foo::bar`.
///
/// ```c
/// struct foo {
/// struct bar {
/// } b;
/// };
/// ```
///
/// `bindgen` tries to avoid duplicate names by default, so it follows the C++ naming
/// convention and it generates `foo` and `foo_bar` instead of just `foo` and `bar`.
///
/// This method disables this behavior and it is indented to be used only for headers
/// that were written in C.
pub fn disable_nested_struct_naming(mut self) -> Builder {
self.options.disable_nested_struct_naming = true;
self
}
},
as_args: "--disable-nested-struct-naming",
},
/// Whether we should avoid embedding version identifiers into source code.
disable_header_comment: bool {
methods: {
/// Do not insert the `bindgen` version identifier into the generated bindings.
///
/// This identifier is inserted by default.
pub fn disable_header_comment(mut self) -> Self {
self.options.disable_header_comment = true;
self
}
},
as_args: "--disable-header-comment",
},
/// Whether we should generate layout tests for generated `struct`s.
layout_tests: bool {
default: true,
methods: {
/// Set whether layout tests should be generated.
///
/// Layout tests are generated by default.
pub fn layout_tests(mut self, doit: bool) -> Self {
self.options.layout_tests = doit;
self
}
},
as_args: |value, args| (!value).as_args(args, "--no-layout-tests"),
},
/// Whether we should implement `Debug` for types that cannot derive it.
impl_debug: bool {
methods: {
/// Set whether `Debug` should be implemented for types that cannot derive it.
///
/// This option is disabled by default.
pub fn impl_debug(mut self, doit: bool) -> Self {
self.options.impl_debug = doit;
self
}
},
as_args: "--impl-debug",
},
/// Whether we should implement `PartialEq` types that cannot derive it.
impl_partialeq: bool {
methods: {
/// Set whether `PartialEq` should be implemented for types that cannot derive it.
///
/// This option is disabled by default.
pub fn impl_partialeq(mut self, doit: bool) -> Self {
self.options.impl_partialeq = doit;
self
}
},
as_args: "--impl-partialeq",
},
/// Whether we should derive `Copy` when possible.
derive_copy: bool {
default: true,
methods: {
/// Set whether the `Copy` trait should be derived when possible.
///
/// `Copy` is derived by default.
pub fn derive_copy(mut self, doit: bool) -> Self {
self.options.derive_copy = doit;
self
}
},
as_args: |value, args| (!value).as_args(args, "--no-derive-copy"),
},
/// Whether we should derive `Debug` when possible.
derive_debug: bool {
default: true,
methods: {
/// Set whether the `Debug` trait should be derived when possible.
///
/// The [`Builder::impl_debug`] method can be used to implement `Debug` for types that
/// cannot derive it.
///
/// `Debug` is derived by default.
pub fn derive_debug(mut self, doit: bool) -> Self {
self.options.derive_debug = doit;
self
}
},
as_args: |value, args| (!value).as_args(args, "--no-derive-debug"),
},
/// Whether we should derive `Default` when possible.
derive_default: bool {
methods: {
/// Set whether the `Default` trait should be derived when possible.
///
/// `Default` is not derived by default.
pub fn derive_default(mut self, doit: bool) -> Self {
self.options.derive_default = doit;
self
}
},
as_args: |&value, args| {
let arg = if value {
"--with-derive-default"
} else {