@@ -29,6 +29,8 @@ use quote::ToTokens;
29
29
use std:: borrow:: Cow ;
30
30
use std:: cell:: { Cell , RefCell } ;
31
31
use std:: collections:: { BTreeSet , HashMap as StdHashMap } ;
32
+ use std:: fs:: OpenOptions ;
33
+ use std:: io:: Write ;
32
34
use std:: mem;
33
35
use std:: path:: Path ;
34
36
@@ -2081,55 +2083,79 @@ If you encounter an error missing from this list, please file an issue or a PR!"
2081
2083
2082
2084
let index = clang:: Index :: new ( false , false ) ;
2083
2085
2084
- let mut c_args = Vec :: new ( ) ;
2085
- let mut pch_paths = Vec :: new ( ) ;
2086
- for input_header in self . options ( ) . input_headers . iter ( ) {
2087
- let path = Path :: new ( input_header. as_ref ( ) ) ;
2088
- let header_name = path
2089
- . file_name ( )
2090
- . and_then ( |hn| hn. to_str ( ) )
2091
- . map ( |s| s. to_owned ( ) ) ;
2092
- let header_path = path
2093
- . parent ( )
2094
- . and_then ( |hp| hp. to_str ( ) )
2095
- . map ( |s| s. to_owned ( ) ) ;
2096
-
2097
- let ( header, pch) = if let ( Some ( ref hp) , Some ( hn) ) =
2098
- ( header_path, header_name)
2099
- {
2100
- let header_path = if hp. is_empty ( ) { "." } else { hp } ;
2101
- let header = format ! ( "{header_path}/{hn}" ) ;
2102
- let pch_path = if let Some ( ref path) =
2103
- self . options ( ) . clang_macro_fallback_build_dir
2104
- {
2105
- path. as_os_str ( ) . to_str ( ) ?
2106
- } else {
2107
- header_path
2108
- } ;
2109
- ( header, format ! ( "{pch_path}/{hn}.pch" ) )
2110
- } else {
2111
- return None ;
2112
- } ;
2113
-
2114
- let mut tu = clang:: TranslationUnit :: parse (
2115
- & index,
2116
- & header,
2117
- & [
2118
- "-x" . to_owned ( ) . into_boxed_str ( ) ,
2119
- "c-header" . to_owned ( ) . into_boxed_str ( ) ,
2120
- ] ,
2121
- & [ ] ,
2122
- clang_sys:: CXTranslationUnit_ForSerialization ,
2086
+ let ( header_names, header_paths, header_contents) =
2087
+ self . options . input_headers . iter ( ) . try_fold (
2088
+ ( Vec :: new ( ) , Vec :: new ( ) , String :: new ( ) ) ,
2089
+ |(
2090
+ mut header_names_to_compile,
2091
+ mut header_paths,
2092
+ mut header_contents,
2093
+ ) ,
2094
+ next| {
2095
+ let path = Path :: new ( next. as_ref ( ) ) ;
2096
+ if let Some ( header_path) = path. parent ( ) {
2097
+ header_paths
2098
+ . push ( header_path. as_os_str ( ) . to_str ( ) ?) ;
2099
+ } else {
2100
+ header_paths. push ( "." ) ;
2101
+ }
2102
+ let header_name = path. file_name ( ) ?. to_str ( ) ?;
2103
+ header_names_to_compile
2104
+ . push ( header_name. split ( ".h" ) . next ( ) ?. to_string ( ) ) ;
2105
+ header_contents +=
2106
+ format ! ( "\n #include <{header_name}>" ) . as_str ( ) ;
2107
+ Some ( (
2108
+ header_names_to_compile,
2109
+ header_paths,
2110
+ header_contents,
2111
+ ) )
2112
+ } ,
2123
2113
) ?;
2124
- tu. save ( & pch) . ok ( ) ?;
2114
+ let header_to_precompile = format ! (
2115
+ "{}/{}" ,
2116
+ match self . options( ) . clang_macro_fallback_build_dir {
2117
+ Some ( ref path) => path. as_os_str( ) . to_str( ) ?,
2118
+ None => "." ,
2119
+ } ,
2120
+ header_names. join( "-" ) + ".h"
2121
+ ) ;
2122
+ let pch = header_to_precompile. clone ( ) + ".pch" ;
2123
+
2124
+ let mut header_to_precompile_file = OpenOptions :: new ( )
2125
+ . create ( true )
2126
+ . truncate ( true )
2127
+ . write ( true )
2128
+ . open ( & header_to_precompile)
2129
+ . ok ( ) ?;
2130
+ header_to_precompile_file
2131
+ . write_all ( header_contents. as_bytes ( ) )
2132
+ . ok ( ) ?;
2125
2133
2126
- c_args. push ( "-include-pch" . to_string ( ) . into_boxed_str ( ) ) ;
2127
- c_args. push ( pch. clone ( ) . into_boxed_str ( ) ) ;
2128
- pch_paths. push ( pch) ;
2134
+ let mut c_args = Vec :: new ( ) ;
2135
+ c_args. push ( "-x" . to_string ( ) . into_boxed_str ( ) ) ;
2136
+ c_args. push ( "c-header" . to_string ( ) . into_boxed_str ( ) ) ;
2137
+ for header_path in header_paths {
2138
+ c_args. push ( "-I" . to_string ( ) . into_boxed_str ( ) ) ;
2139
+ c_args. push ( header_path. to_string ( ) . into_boxed_str ( ) ) ;
2129
2140
}
2130
-
2141
+ let mut tu = clang:: TranslationUnit :: parse (
2142
+ & index,
2143
+ & header_to_precompile,
2144
+ & c_args,
2145
+ & [ ] ,
2146
+ clang_sys:: CXTranslationUnit_ForSerialization ,
2147
+ ) ?;
2148
+ tu. save ( & pch) . ok ( ) ?;
2149
+
2150
+ let c_args = vec ! [
2151
+ "-include-pch" . to_string( ) . into_boxed_str( ) ,
2152
+ pch. clone( ) . into_boxed_str( ) ,
2153
+ ] ;
2131
2154
self . fallback_tu = Some ( clang:: FallbackTranslationUnit :: new (
2132
- file, pch_paths, & c_args,
2155
+ file,
2156
+ header_to_precompile,
2157
+ pch,
2158
+ & c_args,
2133
2159
) ?) ;
2134
2160
}
2135
2161
0 commit comments