@@ -4,7 +4,7 @@ extern crate cc;
4
4
use bindgen:: callbacks:: {
5
5
DeriveInfo , IntKind , MacroParsingBehavior , ParseCallbacks ,
6
6
} ;
7
- use bindgen:: { Builder , EnumVariation } ;
7
+ use bindgen:: { Builder , CargoCallbacks , EnumVariation } ;
8
8
use std:: collections:: HashSet ;
9
9
use std:: env;
10
10
use std:: path:: PathBuf ;
@@ -28,21 +28,14 @@ impl ParseCallbacks for MacroCallback {
28
28
MacroParsingBehavior :: Default
29
29
}
30
30
31
- fn item_name ( & self , original_item_name : & str ) -> Option < String > {
32
- if original_item_name. starts_with ( "my_prefixed_" ) {
33
- Some (
34
- original_item_name
35
- . trim_start_matches ( "my_prefixed_" )
36
- . to_string ( ) ,
37
- )
38
- } else if original_item_name. starts_with ( "MY_PREFIXED_" ) {
39
- Some (
40
- original_item_name
41
- . trim_start_matches ( "MY_PREFIXED_" )
42
- . to_string ( ) ,
43
- )
44
- } else {
45
- None
31
+ fn int_macro ( & self , name : & str , _value : i64 ) -> Option < IntKind > {
32
+ match name {
33
+ "TESTMACRO_CUSTOMINTKIND_PATH" => Some ( IntKind :: Custom {
34
+ name : "crate::MacroInteger" ,
35
+ is_signed : true ,
36
+ } ) ,
37
+
38
+ _ => None ,
46
39
}
47
40
}
48
41
@@ -67,17 +60,6 @@ impl ParseCallbacks for MacroCallback {
67
60
}
68
61
}
69
62
70
- fn int_macro ( & self , name : & str , _value : i64 ) -> Option < IntKind > {
71
- match name {
72
- "TESTMACRO_CUSTOMINTKIND_PATH" => Some ( IntKind :: Custom {
73
- name : "crate::MacroInteger" ,
74
- is_signed : true ,
75
- } ) ,
76
-
77
- _ => None ,
78
- }
79
- }
80
-
81
63
fn func_macro ( & self , name : & str , value : & [ & [ u8 ] ] ) {
82
64
match name {
83
65
"TESTMACRO_NONFUNCTIONAL" => {
@@ -122,6 +104,24 @@ impl ParseCallbacks for MacroCallback {
122
104
}
123
105
}
124
106
107
+ fn item_name ( & self , original_item_name : & str ) -> Option < String > {
108
+ if original_item_name. starts_with ( "my_prefixed_" ) {
109
+ Some (
110
+ original_item_name
111
+ . trim_start_matches ( "my_prefixed_" )
112
+ . to_string ( ) ,
113
+ )
114
+ } else if original_item_name. starts_with ( "MY_PREFIXED_" ) {
115
+ Some (
116
+ original_item_name
117
+ . trim_start_matches ( "MY_PREFIXED_" )
118
+ . to_string ( ) ,
119
+ )
120
+ } else {
121
+ None
122
+ }
123
+ }
124
+
125
125
// Test the "custom derives" capability by adding `PartialEq` to the `Test` struct.
126
126
fn add_derives ( & self , info : & DeriveInfo < ' _ > ) -> Vec < String > {
127
127
if info. name == "Test" {
@@ -149,7 +149,7 @@ impl Drop for MacroCallback {
149
149
}
150
150
}
151
151
152
- fn main ( ) {
152
+ fn setup_macro_test ( ) {
153
153
cc:: Build :: new ( )
154
154
. cpp ( true )
155
155
. file ( "cpp/Test.cc" )
@@ -204,3 +204,65 @@ fn main() {
204
204
"including stub via include dir must produce correct dep path" ,
205
205
) ;
206
206
}
207
+
208
+ fn setup_extern_test ( ) {
209
+ // GH-1090: https://github.com/rust-lang/rust-bindgen/issues/1090
210
+ // set output directory under /target so it is easy to clean generated files
211
+ let out_path = PathBuf :: from ( env:: var ( "OUT_DIR" ) . unwrap ( ) ) ;
212
+ let out_rust_file = out_path. join ( "extern.rs" ) ;
213
+
214
+ let input_header_dir = PathBuf :: from ( "../bindgen-tests/tests/headers/" ) . canonicalize ( )
215
+ . expect ( "Cannot canonicalize libdir path" ) ;
216
+ let input_header_file_path = input_header_dir. join ( "generate-extern-functions.h" ) ;
217
+ let input_header_file_path_str = input_header_file_path. to_str ( )
218
+ . expect ( "Path could not be converted to a str" ) ;
219
+
220
+ // generate external bindings with the external .c and .h files
221
+ let bindings = Builder :: default ( )
222
+ . header ( input_header_file_path_str)
223
+ . parse_callbacks ( Box :: new ( CargoCallbacks ) )
224
+ . generate_extern_functions ( true )
225
+ . extern_functions_directory ( out_path. display ( ) . to_string ( ) )
226
+ . generate ( )
227
+ . expect ( "Unable to generate bindings" ) ;
228
+
229
+ println ! ( "cargo:rustc-link-lib=extern" ) ; // tell cargo to link libextern
230
+ println ! ( "bindings generated: {}" , bindings) ;
231
+
232
+ let obj_path = out_path. join ( "extern.o" ) ;
233
+ let lib_path = out_path. join ( "libextern.a" ) ;
234
+
235
+ // build the external files to check if they work
236
+ if !std:: process:: Command :: new ( "clang" )
237
+ . arg ( "-c" )
238
+ . arg ( "-o" )
239
+ . arg ( & obj_path)
240
+ . arg ( out_path. join ( "extern.c" ) )
241
+ . arg ( "-include" )
242
+ . arg ( input_header_file_path)
243
+ . output ( )
244
+ . expect ( "`clang` command error" )
245
+ . status
246
+ . success ( ) {
247
+ panic ! ( "Could not compile object file" ) ;
248
+ }
249
+
250
+ if !std:: process:: Command :: new ( "ar" )
251
+ . arg ( "rcs" )
252
+ . arg ( lib_path)
253
+ . arg ( obj_path)
254
+ . output ( )
255
+ . expect ( "`ar` command error" )
256
+ . status
257
+ . success ( ) {
258
+ panic ! ( "Could not emit library file" ) ;
259
+ }
260
+
261
+ bindings. write_to_file ( out_rust_file)
262
+ . expect ( "Cound not write bindings to the Rust file" ) ;
263
+ }
264
+
265
+ fn main ( ) {
266
+ setup_macro_test ( ) ;
267
+ setup_extern_test ( ) ;
268
+ }
0 commit comments