2
2
#![ crate_type = "bin" ]
3
3
4
4
extern crate bindgen;
5
+ extern crate docopt;
5
6
extern crate env_logger;
6
7
#[ macro_use]
7
8
extern crate log;
8
9
extern crate clang_sys;
9
10
extern crate rustc_serialize;
10
11
11
- use bindgen:: { BindgenOptions , Bindings , LinkType , ClangVersion , clang_version} ;
12
- use std :: default :: Default ;
12
+ use bindgen:: clang_version;
13
+ use docopt :: Docopt ;
13
14
use std:: env;
14
15
use std:: fs;
15
16
use std:: io;
16
17
use std:: path;
17
- use std:: process;
18
+
19
+ const PKG_NAME : & ' static str = env ! ( "CARGO_PKG_NAME" ) ;
20
+ const PKG_VERSION : & ' static str = env ! ( "CARGO_PKG_VERSION" ) ;
18
21
19
22
const USAGE : & ' static str = "
20
23
Usage:
21
- bindgen [options] \
22
- [--link=<lib>...] \
23
- [--static-link=<lib>...] \
24
- [--framework-link=<framework>...] \
25
- [--raw-line=<raw>...] \
26
- [--opaque-type=<type>...] \
27
- [--blacklist-type=<type>...] \
28
- [--whitelist-type=<type>...] \
29
- [--whitelist-function=<name>...] \
30
- [--whitelist-var=<name>...] \
31
- <input-header> \
32
- [-- <clang-args>...]
33
-
34
- bindgen (-h | --help)
24
+ bindgen [options] <input-header> [-- <clang-args>...]
25
+ bindgen (--help | --version)
35
26
36
27
Options:
37
- -h, --help Display this help message.
28
+ --help, -h Display this help message.
29
+
30
+ --version, -V Display version information.
38
31
39
- -l =<lib>, --link= <lib> Link to a dynamic library, can be provided
32
+ --link =<lib>, -l <lib> ... Link to a dynamic library. Can be provided
40
33
multiple times.
41
34
42
- --static-link=<lib> Link to a static library, can be provided
35
+ --static-link=<lib> ... Link to a static library. Can be provided
43
36
multiple times.
44
37
45
- --framework-link=<framework> Link to a framework.
38
+ --framework-link=<lib> ... Link to a framework. Can be provided
39
+ multiple times.
46
40
47
- -o=<output-rust-file> Write bindings to <output-rust-file>
48
- (defaults to stdout)
41
+ --output=<file>, -o <file> Write Rust bindings to <file>.
49
42
50
43
--builtins Output bindings for builtin definitions (for
51
44
example __builtin_va_list)
@@ -54,172 +47,44 @@ Options:
54
47
methods. This is useful when you only care
55
48
about struct layouts.
56
49
57
- --ignore-methods Avoid generating all kind of methods.
50
+ --ignore-methods Avoid generating all kinds of methods.
58
51
59
52
--enable-cxx-namespaces Enable support for C++ namespaces.
60
53
61
- --emit-clang-ast Output the ast ( for debugging purposes)
54
+ --emit-clang-ast Output the Clang AST for debugging purposes.
62
55
63
- --use-msvc-mangling Handle MSVC C++ ABI mangling; requires that
64
- target be set to (i686|x86_64)-pc-win32
65
-
66
- --raw-line=<raw> Add a raw line at the beginning of the output.
56
+ --raw-line=<raw> ... Add a raw line at the beginning of the output.
67
57
68
- --no-unstable-rust Avoid generating unstable rust .
58
+ --no-unstable-rust Avoid generating unstable Rust code .
69
59
70
- --opaque-type=<type> Mark a type as opaque.
60
+ --opaque-type=<type> ... Mark a type as opaque.
71
61
72
- --blacklist-type=<type> Mark a type as hidden.
62
+ --blacklist-type=<type> ... Mark a type as hidden.
73
63
74
- --whitelist-type=<type> Whitelist the type. If this set or any other
64
+ --whitelist-type=<type> ... Whitelist the type. If this set or any other
75
65
of the whitelisting sets is not empty, then
76
- all the non-whitelisted types (or dependant)
77
- won't be generated.
66
+ all the non-whitelisted types (or anything
67
+ that depends on them) won't be generated.
78
68
79
- --whitelist-function=<regex> Whitelist all the free-standing functions
80
- matching <regex>. Same behavior on emptyness
81
- than the type whitelisting .
69
+ --whitelist-function=<regex> ... Whitelist all the free-standing functions
70
+ matching <regex>. Same behavior on emptyness
71
+ as whitelisted types .
82
72
83
- --whitelist-var=<regex> Whitelist all the free-standing variables
84
- matching <regex>. Same behavior on emptyness
85
- than the type whitelisting .
73
+ --whitelist-var=<regex> ... Whitelist all the free-standing variables
74
+ matching <regex>. Same behavior on emptyness
75
+ as whitelisted types .
86
76
87
77
--dummy-uses=<path> For testing purposes, generate a C/C++ file
88
78
containing dummy uses of all types defined in
89
79
the input header.
90
80
91
- <clang-args> Options other than stated above are passed
92
- directly through to clang.
93
- " ;
81
+ <clang-args> Pass arguments through to clang.
94
82
95
- // FIXME(emilio): Replace this with docopt if/when they fix their exponential
96
- // algorithm for argument parsing.
97
- //
98
- // FIXME(fitzgen): Switch from `BindgenOptions` to the non-deprecated `Builder`.
99
- #[ allow( deprecated) ]
100
- fn parse_args_or_exit ( args : Vec < String > ) -> ( BindgenOptions , Box < io:: Write > ) {
101
- let mut options = BindgenOptions :: default ( ) ;
102
- let mut dest_file = None ;
103
- let mut source_file = None ;
104
-
105
- let mut iter = args. into_iter ( ) . skip ( 1 ) ;
106
- loop {
107
- let next = match iter. next ( ) {
108
- Some ( arg) => arg,
109
- _ => break ,
110
- } ;
111
-
112
- match & * next {
113
- "-h" | "--help" => {
114
- println ! ( "{}" , USAGE ) ;
115
- process:: exit ( 0 ) ;
116
- }
117
- "-l" | "--link" => {
118
- let lib = iter. next ( ) . expect ( "--link needs an argument" ) ;
119
- options. links . push ( ( lib, LinkType :: Default ) ) ;
120
- }
121
- "--static-link" => {
122
- let lib = iter. next ( ) . expect ( "--static-link needs an argument" ) ;
123
- options. links . push ( ( lib, LinkType :: Static ) ) ;
124
- }
125
- "--framework-link" => {
126
- let lib = iter. next ( )
127
- . expect ( "--framework-link needs an argument" ) ;
128
- options. links . push ( ( lib, LinkType :: Framework ) ) ;
129
- }
130
- "--raw-line" => {
131
- let line = iter. next ( ) . expect ( "--raw-line needs an argument" ) ;
132
- options. raw_lines . push ( line) ;
133
- }
134
- "--opaque-type" => {
135
- let ty_canonical_name = iter. next ( )
136
- . expect ( "--opaque-type expects a type" ) ;
137
- options. opaque_types . insert ( ty_canonical_name) ;
138
- }
139
- "--blacklist-type" => {
140
- let ty_canonical_name = iter. next ( )
141
- . expect ( "--blacklist-type expects a type" ) ;
142
- options. hidden_types . insert ( ty_canonical_name) ;
143
- }
144
- "--whitelist-type" => {
145
- let ty_pat = iter. next ( )
146
- . expect ( "--whitelist-type expects a type pattern" ) ;
147
- options. whitelisted_types . insert ( & ty_pat) ;
148
- }
149
- "--whitelist-function" => {
150
- let function_pat = iter. next ( )
151
- . expect ( "--whitelist-function expects a pattern" ) ;
152
- options. whitelisted_functions . insert ( & function_pat) ;
153
- }
154
- "--whitelist-var" => {
155
- let var_pat = iter. next ( )
156
- . expect ( "--whitelist-var expects a pattern" ) ;
157
- options. whitelisted_vars . insert ( & var_pat) ;
158
- }
159
- "--" => {
160
- while let Some ( clang_arg) = iter. next ( ) {
161
- options. clang_args . push ( clang_arg) ;
162
- }
163
- }
164
- "--output" | "-o" => {
165
- let out_name = iter. next ( ) . expect ( "-o expects a file name" ) ;
166
- dest_file = Some ( out_name) ;
167
- }
168
- "--builtins" => {
169
- options. builtins = true ;
170
- }
171
- "--ignore-functions" => {
172
- options. ignore_functions = true ;
173
- }
174
- "--ignore-methods" => {
175
- options. ignore_methods = true ;
176
- }
177
- "--enable-cxx-namespaces" => {
178
- options. enable_cxx_namespaces = true ;
179
- }
180
- "--no-unstable-rust" => {
181
- options. unstable_rust = false ;
182
- }
183
- "--emit-clang-ast" => {
184
- options. emit_ast = true ;
185
- }
186
- "--use-msvc-mangling" => {
187
- options. msvc_mangling = true ;
188
- }
189
- "--dummy-uses" => {
190
- let dummy_path = iter. next ( )
191
- . expect ( "--dummy-uses expects a file path" ) ;
192
- options. dummy_uses = Some ( dummy_path) ;
193
- }
194
- other if source_file. is_none ( ) => {
195
- source_file = Some ( other. into ( ) ) ;
196
- }
197
- other => {
198
- panic ! ( "Unknown option: \" {}\" " , other) ;
199
- }
200
- }
201
- }
83
+ Deprecated:
202
84
203
- if let Some ( source_file) = source_file. take ( ) {
204
- options. clang_args . push ( source_file) ;
205
- options. input_header = options. clang_args . last ( ) . cloned ( ) ;
206
- } else {
207
- options. input_header = options. clang_args
208
- . iter ( )
209
- . find ( |arg| arg. ends_with ( ".h" ) || arg. ends_with ( ".hpp" ) )
210
- . cloned ( ) ;
211
- }
212
-
213
- let out = if let Some ( ref path_name) = dest_file {
214
- let path = path:: Path :: new ( path_name) ;
215
- let file = fs:: File :: create ( path) . expect ( "Opening out file failed" ) ;
216
- Box :: new ( io:: BufWriter :: new ( file) ) as Box < io:: Write >
217
- } else {
218
- Box :: new ( io:: BufWriter :: new ( io:: stdout ( ) ) ) as Box < io:: Write >
219
- } ;
220
-
221
- ( options, out)
222
- }
85
+ --use-msvc-mangling Handle MSVC C++ ABI mangling; requires that
86
+ target be set to (i686|x86_64)-pc-win32.
87
+ " ;
223
88
224
89
pub fn main ( ) {
225
90
log:: set_logger ( |max_log_level| {
@@ -270,9 +135,115 @@ pub fn main() {
270
135
}
271
136
}
272
137
273
- let ( options, out) = parse_args_or_exit ( bind_args) ;
138
+ let args = Docopt :: new ( USAGE )
139
+ . and_then ( |dopt| dopt. parse ( ) )
140
+ . unwrap_or_else ( |e| e. exit ( ) ) ;
141
+
142
+ if args. get_bool ( "--version" ) {
143
+ println ! ( "{} v{}" , PKG_NAME , PKG_VERSION ) ;
144
+ std:: process:: exit ( 0 ) ;
145
+ }
146
+
147
+ let mut builder = bindgen:: builder ( ) ;
148
+
149
+ // Input header
150
+ let header = args. get_str ( "<input-header>" ) ;
151
+ if header != "" {
152
+ builder = builder. header ( header) ;
153
+ }
154
+
155
+ // Output file or stdout
156
+ let output = args. get_str ( "--output" ) ;
157
+ let out = if output != "" {
158
+ let path = path:: Path :: new ( output) ;
159
+ let file = fs:: File :: create ( path) . expect ( "Opening output file failed." ) ;
160
+ Box :: new ( io:: BufWriter :: new ( file) ) as Box < io:: Write >
161
+ } else {
162
+ Box :: new ( io:: BufWriter :: new ( io:: stdout ( ) ) ) as Box < io:: Write >
163
+ } ;
164
+
165
+ // Emit C/C++ type uses file for testing
166
+ let dummy_uses = args. get_str ( "--dummy-uses" ) ;
167
+ if dummy_uses != "" {
168
+ builder = builder. dummy_uses ( dummy_uses) ;
169
+ }
170
+
171
+ if args. get_bool ( "--builtins" ) {
172
+ builder = builder. emit_builtins ( ) ;
173
+ }
174
+
175
+ if args. get_bool ( "--emit-clang-ast" ) {
176
+ builder = builder. emit_clang_ast ( ) ;
177
+ }
178
+
179
+ if args. get_bool ( "--enable-cxx-namespaces" ) {
180
+ builder = builder. enable_cxx_namespaces ( ) ;
181
+ }
182
+
183
+ if args. get_bool ( "--ignore-functions" ) {
184
+ builder = builder. ignore_functions ( ) ;
185
+ }
186
+
187
+ if args. get_bool ( "--ignore-methods" ) {
188
+ builder = builder. ignore_methods ( ) ;
189
+ }
190
+
191
+ // Do not generate unstable Rust code
192
+ if args. get_bool ( "--no-unstable-rust" ) {
193
+ builder = builder. no_unstable_rust ( ) ;
194
+ }
195
+
196
+ // Shared library links
197
+ for link in args. get_vec ( "--link" ) {
198
+ builder = builder. link ( link) ;
199
+ }
200
+
201
+ // Static library links
202
+ for link in args. get_vec ( "--static-link" ) {
203
+ builder = builder. link_static ( link) ;
204
+ }
205
+
206
+ // Framework links
207
+ for link in args. get_vec ( "--framework-link" ) {
208
+ builder = builder. link_framework ( link) ;
209
+ }
210
+
211
+ // Raw lines to add at top of output
212
+ for line in args. get_vec ( "--raw-line" ) {
213
+ builder = builder. raw_line ( line) ;
214
+ }
215
+
216
+ // Hidden types
217
+ for arg in args. get_vec ( "--blacklist-type" ) {
218
+ builder = builder. hide_type ( arg) ;
219
+ }
220
+
221
+ // Opaque types
222
+ for arg in args. get_vec ( "--opaque-type" ) {
223
+ builder = builder. opaque_type ( arg) ;
224
+ }
225
+
226
+ // Whitelisted types
227
+ for regex in args. get_vec ( "--whitelist-type" ) {
228
+ builder = builder. whitelisted_type ( regex) ;
229
+ }
230
+
231
+ // Whitelisted functions
232
+ for regex in args. get_vec ( "--whitelist-function" ) {
233
+ builder = builder. whitelisted_function ( regex) ;
234
+ }
235
+
236
+ // Whitelisted variables
237
+ for regex in args. get_vec ( "--whitelist-var" ) {
238
+ builder = builder. whitelisted_var ( regex) ;
239
+ }
240
+
241
+ // Clang parameters
242
+ for arg in args. get_vec ( "<clang-args>" ) {
243
+ builder = builder. clang_arg ( arg) ;
244
+ }
274
245
275
- let mut bindings = Bindings :: generate ( options , None )
246
+ let mut bindings = builder . generate ( )
276
247
. expect ( "Unable to generate bindings" ) ;
277
248
278
249
bindings. write_dummy_uses ( )
0 commit comments