@@ -1559,25 +1559,33 @@ impl Builder {
1559
1559
}
1560
1560
1561
1561
/// Generate the Rust bindings using the options built up thus far.
1562
- pub fn generate ( mut self ) -> Result < Bindings , BindgenError > {
1562
+ pub fn generate ( self ) -> Result < Bindings , BindgenError > {
1563
+ let mut options = self . options . clone ( ) ;
1563
1564
// Add any extra arguments from the environment to the clang command line.
1564
- self . options . clang_args . extend ( get_extra_clang_args ( ) ) ;
1565
+ options. clang_args . extend ( get_extra_clang_args ( ) ) ;
1565
1566
1566
1567
// Transform input headers to arguments on the clang command line.
1567
- self . options . clang_args . extend (
1568
- self . options . input_headers
1569
- [ ..self . options . input_headers . len ( ) . saturating_sub ( 1 ) ]
1568
+ options. clang_args . extend (
1569
+ options. input_headers
1570
+ [ ..options. input_headers . len ( ) . saturating_sub ( 1 ) ]
1570
1571
. iter ( )
1571
1572
. flat_map ( |header| [ "-include" . into ( ) , header. to_string ( ) ] ) ,
1572
1573
) ;
1573
1574
1574
1575
let input_unsaved_files =
1575
- std:: mem:: take ( & mut self . options . input_header_contents )
1576
+ std:: mem:: take ( & mut options. input_header_contents )
1576
1577
. into_iter ( )
1577
1578
. map ( |( name, contents) | clang:: UnsavedFile :: new ( name, contents) )
1578
1579
. collect :: < Vec < _ > > ( ) ;
1579
1580
1580
- Bindings :: generate ( self . options , input_unsaved_files)
1581
+ match Bindings :: generate ( options, input_unsaved_files) {
1582
+ Ok ( bindings) => Ok ( bindings) ,
1583
+ Err ( GenerateError :: ShouldRestart { header } ) => self
1584
+ . header ( header)
1585
+ . generate_inline_functions ( false )
1586
+ . generate ( ) ,
1587
+ Err ( GenerateError :: Bindgen ( err) ) => Err ( err) ,
1588
+ }
1581
1589
}
1582
1590
1583
1591
/// Preprocess and dump the input header files to disk.
@@ -2287,6 +2295,23 @@ fn ensure_libclang_is_loaded() {
2287
2295
#[ cfg( not( feature = "runtime" ) ) ]
2288
2296
fn ensure_libclang_is_loaded ( ) { }
2289
2297
2298
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
2299
+ enum GenerateError {
2300
+ /// Error variant raised when bindgen requires to run again with a newly generated header
2301
+ /// input.
2302
+ #[ allow( dead_code) ]
2303
+ ShouldRestart {
2304
+ header : String ,
2305
+ } ,
2306
+ Bindgen ( BindgenError ) ,
2307
+ }
2308
+
2309
+ impl From < BindgenError > for GenerateError {
2310
+ fn from ( err : BindgenError ) -> Self {
2311
+ Self :: Bindgen ( err)
2312
+ }
2313
+ }
2314
+
2290
2315
/// Error type for rust-bindgen.
2291
2316
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
2292
2317
#[ non_exhaustive]
@@ -2380,7 +2405,7 @@ impl Bindings {
2380
2405
pub ( crate ) fn generate (
2381
2406
mut options : BindgenOptions ,
2382
2407
input_unsaved_files : Vec < clang:: UnsavedFile > ,
2383
- ) -> Result < Bindings , BindgenError > {
2408
+ ) -> Result < Bindings , GenerateError > {
2384
2409
ensure_libclang_is_loaded ( ) ;
2385
2410
2386
2411
#[ cfg( feature = "runtime" ) ]
@@ -2501,17 +2526,20 @@ impl Bindings {
2501
2526
let path = Path :: new ( h) ;
2502
2527
if let Ok ( md) = std:: fs:: metadata ( path) {
2503
2528
if md. is_dir ( ) {
2504
- return Err ( BindgenError :: FolderAsHeader ( path. into ( ) ) ) ;
2529
+ return Err (
2530
+ BindgenError :: FolderAsHeader ( path. into ( ) ) . into ( )
2531
+ ) ;
2505
2532
}
2506
2533
if !can_read ( & md. permissions ( ) ) {
2507
2534
return Err ( BindgenError :: InsufficientPermissions (
2508
2535
path. into ( ) ,
2509
- ) ) ;
2536
+ )
2537
+ . into ( ) ) ;
2510
2538
}
2511
2539
let h = h. clone ( ) ;
2512
2540
options. clang_args . push ( h) ;
2513
2541
} else {
2514
- return Err ( BindgenError :: NotExist ( path. into ( ) ) ) ;
2542
+ return Err ( BindgenError :: NotExist ( path. into ( ) ) . into ( ) ) ;
2515
2543
}
2516
2544
}
2517
2545
0 commit comments