1+ use bstr:: ByteSlice ;
12use cargo_metadata:: { camino:: Utf8PathBuf , DependencyKind } ;
23use cargo_platform:: Cfg ;
34use color_eyre:: eyre:: { bail, eyre, Result } ;
45use std:: {
56 collections:: { hash_map:: Entry , HashMap , HashSet } ,
67 ffi:: OsString ,
7- path:: PathBuf ,
8+ path:: { Path , PathBuf } ,
89 process:: Command ,
910 str:: FromStr ,
1011 sync:: { Arc , OnceLock , RwLock } ,
1112} ;
1213
1314use 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 ,
1521} ;
1622
1723#[ derive( Default , Debug ) ]
@@ -290,7 +296,7 @@ impl<'a> BuildManager<'a> {
290296 Err ( ( ) )
291297 }
292298 } ,
293- Build :: Aux { aux_file } => match build_aux ( aux_file, config, self ) {
299+ Build :: Aux { aux_file } => match self . build_aux ( aux_file, config) {
294300 Ok ( args) => Ok ( args. iter ( ) . map ( Into :: into) . collect ( ) ) ,
295301 Err ( e) => {
296302 err = Some ( e) ;
@@ -300,7 +306,7 @@ impl<'a> BuildManager<'a> {
300306 } ;
301307 build. done (
302308 & res. as_ref ( )
303- . map ( |_| crate :: TestOk :: Ok )
309+ . map ( |_| crate :: test_result :: TestOk :: Ok )
304310 . map_err ( |( ) | Errored {
305311 command : Command :: new ( what. description ( ) ) ,
306312 errors : vec ! [ ] ,
@@ -320,4 +326,104 @@ impl<'a> BuildManager<'a> {
320326 } )
321327 } )
322328 }
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+ }
323429}
0 commit comments