@@ -138,122 +138,133 @@ impl TargetInfo {
138
138
rustc : & Rustc ,
139
139
kind : CompileKind ,
140
140
) -> CargoResult < TargetInfo > {
141
- let rustflags = env_args (
141
+ let mut rustflags = env_args (
142
142
config,
143
143
requested_kinds,
144
144
& rustc. host ,
145
145
None ,
146
146
kind,
147
147
Flags :: Rust ,
148
148
) ?;
149
- let extra_fingerprint = kind. fingerprint_hash ( ) ;
150
- let mut process = rustc. workspace_process ( ) ;
151
- process
152
- . arg ( "-" )
153
- . arg ( "--crate-name" )
154
- . arg ( "___" )
155
- . arg ( "--print=file-names" )
156
- . args ( & rustflags)
157
- . env_remove ( "RUSTC_LOG" ) ;
158
-
159
- if let CompileKind :: Target ( target) = kind {
160
- process. arg ( "--target" ) . arg ( target. rustc_target ( ) ) ;
161
- }
162
-
163
- let crate_type_process = process. clone ( ) ;
164
- const KNOWN_CRATE_TYPES : & [ CrateType ] = & [
165
- CrateType :: Bin ,
166
- CrateType :: Rlib ,
167
- CrateType :: Dylib ,
168
- CrateType :: Cdylib ,
169
- CrateType :: Staticlib ,
170
- CrateType :: ProcMacro ,
171
- ] ;
172
- for crate_type in KNOWN_CRATE_TYPES . iter ( ) {
173
- process. arg ( "--crate-type" ) . arg ( crate_type. as_str ( ) ) ;
174
- }
175
- let supports_split_debuginfo = rustc
176
- . cached_output (
177
- process. clone ( ) . arg ( "-Csplit-debuginfo=packed" ) ,
178
- extra_fingerprint,
179
- )
180
- . is_ok ( ) ;
181
-
182
- process. arg ( "--print=sysroot" ) ;
183
- process. arg ( "--print=cfg" ) ;
184
-
185
- let ( output, error) = rustc
186
- . cached_output ( & process, extra_fingerprint)
187
- . with_context ( || "failed to run `rustc` to learn about target-specific information" ) ?;
149
+ for _ in 0 ..3 {
150
+ let extra_fingerprint = kind. fingerprint_hash ( ) ;
151
+ let mut process = rustc. workspace_process ( ) ;
152
+ process
153
+ . arg ( "-" )
154
+ . arg ( "--crate-name" )
155
+ . arg ( "___" )
156
+ . arg ( "--print=file-names" )
157
+ . args ( & rustflags)
158
+ . env_remove ( "RUSTC_LOG" ) ;
159
+
160
+ if let CompileKind :: Target ( target) = kind {
161
+ process. arg ( "--target" ) . arg ( target. rustc_target ( ) ) ;
162
+ }
188
163
189
- let mut lines = output. lines ( ) ;
190
- let mut map = HashMap :: new ( ) ;
191
- for crate_type in KNOWN_CRATE_TYPES {
192
- let out = parse_crate_type ( crate_type, & process, & output, & error, & mut lines) ?;
193
- map. insert ( crate_type. clone ( ) , out) ;
194
- }
164
+ let crate_type_process = process. clone ( ) ;
165
+ const KNOWN_CRATE_TYPES : & [ CrateType ] = & [
166
+ CrateType :: Bin ,
167
+ CrateType :: Rlib ,
168
+ CrateType :: Dylib ,
169
+ CrateType :: Cdylib ,
170
+ CrateType :: Staticlib ,
171
+ CrateType :: ProcMacro ,
172
+ ] ;
173
+ for crate_type in KNOWN_CRATE_TYPES . iter ( ) {
174
+ process. arg ( "--crate-type" ) . arg ( crate_type. as_str ( ) ) ;
175
+ }
176
+ let supports_split_debuginfo = rustc
177
+ . cached_output (
178
+ process. clone ( ) . arg ( "-Csplit-debuginfo=packed" ) ,
179
+ extra_fingerprint,
180
+ )
181
+ . is_ok ( ) ;
182
+
183
+ process. arg ( "--print=sysroot" ) ;
184
+ process. arg ( "--print=cfg" ) ;
185
+
186
+ let ( output, error) = rustc
187
+ . cached_output ( & process, extra_fingerprint)
188
+ . with_context ( || {
189
+ "failed to run `rustc` to learn about target-specific information"
190
+ } ) ?;
191
+
192
+ let mut lines = output. lines ( ) ;
193
+ let mut map = HashMap :: new ( ) ;
194
+ for crate_type in KNOWN_CRATE_TYPES {
195
+ let out = parse_crate_type ( crate_type, & process, & output, & error, & mut lines) ?;
196
+ map. insert ( crate_type. clone ( ) , out) ;
197
+ }
195
198
196
- let line = match lines. next ( ) {
197
- Some ( line) => line,
198
- None => anyhow:: bail!(
199
- "output of --print=sysroot missing when learning about \
199
+ let line = match lines. next ( ) {
200
+ Some ( line) => line,
201
+ None => anyhow:: bail!(
202
+ "output of --print=sysroot missing when learning about \
200
203
target-specific information from rustc\n {}",
201
- output_err_info( & process, & output, & error)
202
- ) ,
203
- } ;
204
- let sysroot = PathBuf :: from ( line) ;
205
- let sysroot_host_libdir = if cfg ! ( windows) {
206
- sysroot. join ( "bin" )
207
- } else {
208
- sysroot. join ( "lib" )
209
- } ;
210
- let mut sysroot_target_libdir = sysroot. clone ( ) ;
211
- sysroot_target_libdir. push ( "lib" ) ;
212
- sysroot_target_libdir. push ( "rustlib" ) ;
213
- sysroot_target_libdir. push ( match & kind {
214
- CompileKind :: Host => rustc. host . as_str ( ) ,
215
- CompileKind :: Target ( target) => target. short_name ( ) ,
216
- } ) ;
217
- sysroot_target_libdir. push ( "lib" ) ;
218
-
219
- let cfg = lines
220
- . map ( |line| Ok ( Cfg :: from_str ( line) ?) )
221
- . filter ( TargetInfo :: not_user_specific_cfg)
222
- . collect :: < CargoResult < Vec < _ > > > ( )
223
- . with_context ( || {
224
- format ! (
225
- "failed to parse the cfg from `rustc --print=cfg`, got:\n {}" ,
226
- output
227
- )
228
- } ) ?;
229
-
230
- Ok ( TargetInfo {
231
- crate_type_process,
232
- crate_types : RefCell :: new ( map) ,
233
- sysroot,
234
- sysroot_host_libdir,
235
- sysroot_target_libdir,
204
+ output_err_info( & process, & output, & error)
205
+ ) ,
206
+ } ;
207
+ let sysroot = PathBuf :: from ( line) ;
208
+ let sysroot_host_libdir = if cfg ! ( windows) {
209
+ sysroot. join ( "bin" )
210
+ } else {
211
+ sysroot. join ( "lib" )
212
+ } ;
213
+ let mut sysroot_target_libdir = sysroot. clone ( ) ;
214
+ sysroot_target_libdir. push ( "lib" ) ;
215
+ sysroot_target_libdir. push ( "rustlib" ) ;
216
+ sysroot_target_libdir. push ( match & kind {
217
+ CompileKind :: Host => rustc. host . as_str ( ) ,
218
+ CompileKind :: Target ( target) => target. short_name ( ) ,
219
+ } ) ;
220
+ sysroot_target_libdir. push ( "lib" ) ;
221
+
222
+ let cfg = lines
223
+ . map ( |line| Ok ( Cfg :: from_str ( line) ?) )
224
+ . filter ( TargetInfo :: not_user_specific_cfg)
225
+ . collect :: < CargoResult < Vec < _ > > > ( )
226
+ . with_context ( || {
227
+ format ! (
228
+ "failed to parse the cfg from `rustc --print=cfg`, got:\n {}" ,
229
+ output
230
+ )
231
+ } ) ?;
232
+
236
233
// recalculate `rustflags` from above now that we have `cfg`
237
234
// information
238
- rustflags : env_args (
235
+ let new_flags = env_args (
239
236
config,
240
237
requested_kinds,
241
238
& rustc. host ,
242
239
Some ( & cfg) ,
243
240
kind,
244
241
Flags :: Rust ,
245
- ) ?,
246
- rustdocflags : env_args (
247
- config,
248
- requested_kinds,
249
- & rustc. host ,
250
- Some ( & cfg) ,
251
- kind,
252
- Flags :: Rustdoc ,
253
- ) ?,
254
- cfg,
255
- supports_split_debuginfo,
256
- } )
242
+ ) ?;
243
+ if new_flags != rustflags {
244
+ rustflags = new_flags;
245
+ continue ;
246
+ }
247
+
248
+ return Ok ( TargetInfo {
249
+ crate_type_process,
250
+ crate_types : RefCell :: new ( map) ,
251
+ sysroot,
252
+ sysroot_host_libdir,
253
+ sysroot_target_libdir,
254
+ rustflags,
255
+ rustdocflags : env_args (
256
+ config,
257
+ requested_kinds,
258
+ & rustc. host ,
259
+ Some ( & cfg) ,
260
+ kind,
261
+ Flags :: Rustdoc ,
262
+ ) ?,
263
+ cfg,
264
+ supports_split_debuginfo,
265
+ } ) ;
266
+ }
267
+ anyhow:: bail!( "diverging rustflags" )
257
268
}
258
269
259
270
fn not_user_specific_cfg ( cfg : & CargoResult < Cfg > ) -> bool {
0 commit comments