1
+ use bstr:: ByteSlice ;
1
2
use cargo_metadata:: { camino:: Utf8PathBuf , DependencyKind } ;
2
3
use cargo_platform:: Cfg ;
3
4
use color_eyre:: eyre:: { bail, eyre, Result } ;
4
5
use std:: {
5
6
collections:: { hash_map:: Entry , HashMap , HashSet } ,
6
7
ffi:: OsString ,
7
- path:: PathBuf ,
8
+ path:: { Path , PathBuf } ,
8
9
process:: Command ,
9
10
str:: FromStr ,
10
11
sync:: { Arc , OnceLock , RwLock } ,
11
12
} ;
12
13
13
14
use crate :: {
14
- build_aux, status_emitter:: StatusEmitter , Config , Errored , Mode , OutputConflictHandling ,
15
+ crate_type, default_per_file_config,
16
+ per_test_config:: { Comments , TestConfig } ,
17
+ rustc_stderr,
18
+ status_emitter:: StatusEmitter ,
19
+ test_result:: Errored ,
20
+ Config , CrateType , Error , Mode , OutputConflictHandling ,
15
21
} ;
16
22
17
23
#[ derive( Default , Debug ) ]
@@ -290,7 +296,7 @@ impl<'a> BuildManager<'a> {
290
296
Err ( ( ) )
291
297
}
292
298
} ,
293
- Build :: Aux { aux_file } => match build_aux ( aux_file, config, self ) {
299
+ Build :: Aux { aux_file } => match self . build_aux ( aux_file, config) {
294
300
Ok ( args) => Ok ( args. iter ( ) . map ( Into :: into) . collect ( ) ) ,
295
301
Err ( e) => {
296
302
err = Some ( e) ;
@@ -300,7 +306,7 @@ impl<'a> BuildManager<'a> {
300
306
} ;
301
307
build. done (
302
308
& res. as_ref ( )
303
- . map ( |_| crate :: TestOk :: Ok )
309
+ . map ( |_| crate :: test_result :: TestOk :: Ok )
304
310
. map_err ( |( ) | Errored {
305
311
command : Command :: new ( what. description ( ) ) ,
306
312
errors : vec ! [ ] ,
@@ -320,4 +326,104 @@ impl<'a> BuildManager<'a> {
320
326
} )
321
327
} )
322
328
}
329
+
330
+ fn build_aux (
331
+ & self ,
332
+ aux_file : & Path ,
333
+ config : & Config ,
334
+ ) -> std:: result:: Result < Vec < OsString > , Errored > {
335
+ let file_contents = std:: fs:: read ( aux_file) . map_err ( |err| Errored {
336
+ command : Command :: new ( format ! ( "reading aux file `{}`" , aux_file. display( ) ) ) ,
337
+ errors : vec ! [ ] ,
338
+ stderr : err. to_string ( ) . into_bytes ( ) ,
339
+ stdout : vec ! [ ] ,
340
+ } ) ?;
341
+ let comments = Comments :: parse ( & file_contents, config. comment_defaults . clone ( ) , aux_file)
342
+ . map_err ( |errors| Errored :: new ( errors, "parse aux comments" ) ) ?;
343
+ assert_eq ! (
344
+ comments. revisions, None ,
345
+ "aux builds cannot specify revisions"
346
+ ) ;
347
+
348
+ let mut config = config. clone ( ) ;
349
+
350
+ // Strip any `crate-type` flags from the args, as we need to set our own,
351
+ // and they may conflict (e.g. `lib` vs `proc-macro`);
352
+ let mut prev_was_crate_type = false ;
353
+ config. program . args . retain ( |arg| {
354
+ if prev_was_crate_type {
355
+ prev_was_crate_type = false ;
356
+ return false ;
357
+ }
358
+ if arg == "--test" {
359
+ false
360
+ } else if arg == "--crate-type" {
361
+ prev_was_crate_type = true ;
362
+ false
363
+ } else if let Some ( arg) = arg. to_str ( ) {
364
+ !arg. starts_with ( "--crate-type=" )
365
+ } else {
366
+ true
367
+ }
368
+ } ) ;
369
+
370
+ default_per_file_config ( & mut config, aux_file, & file_contents) ;
371
+
372
+ match crate_type ( & file_contents) {
373
+ // Proc macros must be run on the host
374
+ CrateType :: ProcMacro => config. target = config. host . clone ( ) ,
375
+ CrateType :: Test | CrateType :: Bin | CrateType :: Lib => { }
376
+ }
377
+
378
+ let mut config = TestConfig {
379
+ config,
380
+ revision : "" ,
381
+ comments : & comments,
382
+ path : aux_file,
383
+ } ;
384
+
385
+ config. patch_out_dir ( ) ;
386
+
387
+ let mut aux_cmd = config. build_command ( ) ?;
388
+
389
+ let mut extra_args = config. build_aux_files ( aux_file. parent ( ) . unwrap ( ) , self ) ?;
390
+ // Make sure we see our dependencies
391
+ aux_cmd. args ( extra_args. iter ( ) ) ;
392
+
393
+ aux_cmd. arg ( "--emit=link" ) ;
394
+ let filename = aux_file. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
395
+ let output = aux_cmd. output ( ) . unwrap ( ) ;
396
+ if !output. status . success ( ) {
397
+ let error = Error :: Command {
398
+ kind : "compilation of aux build failed" . to_string ( ) ,
399
+ status : output. status ,
400
+ } ;
401
+ return Err ( Errored {
402
+ command : aux_cmd,
403
+ errors : vec ! [ error] ,
404
+ stderr : rustc_stderr:: process ( aux_file, & output. stderr ) . rendered ,
405
+ stdout : output. stdout ,
406
+ } ) ;
407
+ }
408
+
409
+ // Now run the command again to fetch the output filenames
410
+ aux_cmd. arg ( "--print" ) . arg ( "file-names" ) ;
411
+ let output = aux_cmd. output ( ) . unwrap ( ) ;
412
+ assert ! ( output. status. success( ) ) ;
413
+
414
+ for file in output. stdout . lines ( ) {
415
+ let file = std:: str:: from_utf8 ( file) . unwrap ( ) ;
416
+ let crate_name = filename. replace ( '-' , "_" ) ;
417
+ let path = config. config . out_dir . join ( file) ;
418
+ extra_args. push ( "--extern" . into ( ) ) ;
419
+ let mut cname = OsString :: from ( & crate_name) ;
420
+ cname. push ( "=" ) ;
421
+ cname. push ( path) ;
422
+ extra_args. push ( cname) ;
423
+ // Help cargo find the crates added with `--extern`.
424
+ extra_args. push ( "-L" . into ( ) ) ;
425
+ extra_args. push ( config. config . out_dir . as_os_str ( ) . to_os_string ( ) ) ;
426
+ }
427
+ Ok ( extra_args)
428
+ }
323
429
}
0 commit comments