@@ -5,7 +5,6 @@ use std::io::{self, BufRead, BufReader, BufWriter, Write};
5
5
use std:: ops:: Not ;
6
6
use std:: path:: { Path , PathBuf } ;
7
7
use std:: process:: Command ;
8
- use std:: collections:: HashMap ;
9
8
10
9
use serde:: { Deserialize , Serialize } ;
11
10
@@ -50,7 +49,16 @@ struct CrateRunInfo {
50
49
/// The command-line arguments.
51
50
args : Vec < OsString > ,
52
51
/// The environment.
53
- env : HashMap < OsString , OsString > ,
52
+ env : Vec < ( OsString , OsString ) > ,
53
+ }
54
+
55
+ impl CrateRunInfo {
56
+ /// Gather all the information we need.
57
+ fn collect ( args : env:: ArgsOs ) -> Self {
58
+ let args = args. collect ( ) ;
59
+ let env = env:: vars_os ( ) . collect ( ) ;
60
+ CrateRunInfo { args, env }
61
+ }
54
62
}
55
63
56
64
fn show_help ( ) {
@@ -128,6 +136,11 @@ fn xargo_check() -> Command {
128
136
Command :: new ( env:: var_os ( "XARGO_CHECK" ) . unwrap_or_else ( || OsString :: from ( "xargo-check" ) ) )
129
137
}
130
138
139
+ fn exec ( mut cmd : Command ) -> ! {
140
+ let exit_status = cmd. status ( ) . expect ( "failed to run command" ) ;
141
+ std:: process:: exit ( exit_status. code ( ) . unwrap_or ( -1 ) )
142
+ }
143
+
131
144
fn xargo_version ( ) -> Option < ( u32 , u32 , u32 ) > {
132
145
let out = xargo_check ( ) . arg ( "--version" ) . output ( ) . ok ( ) ?;
133
146
if !out. status . success ( ) {
@@ -346,17 +359,16 @@ path = "lib.rs"
346
359
}
347
360
}
348
361
349
- fn phase_cargo_miri ( mut args : env:: Args ) {
362
+ fn phase_cargo_miri ( mut args : env:: ArgsOs ) {
350
363
// Require a subcommand before any flags.
351
364
// We cannot know which of those flags take arguments and which do not,
352
365
// so we cannot detect subcommands later.
353
- let subcommand = match args. next ( ) . as_deref ( ) {
366
+ let subcommand = match args. next ( ) . as_deref ( ) . and_then ( |s| s . to_str ( ) ) {
354
367
Some ( "test" ) => MiriCommand :: Test ,
355
368
Some ( "run" ) => MiriCommand :: Run ,
356
369
Some ( "setup" ) => MiriCommand :: Setup ,
357
370
// Invalid command.
358
- None => show_error ( format ! ( "`cargo miri` must be immediately followed by `test`, `run`, or `setup`." ) ) ,
359
- Some ( s) => show_error ( format ! ( "unknown command `{}`" , s) ) ,
371
+ _ => show_error ( format ! ( "`cargo miri` must be immediately followed by `test`, `run`, or `setup`." ) ) ,
360
372
} ;
361
373
let verbose = has_arg_flag ( "-v" ) ;
362
374
@@ -410,13 +422,10 @@ fn phase_cargo_miri(mut args: env::Args) {
410
422
cmd. env ( "MIRI_VERBOSE" , "" ) ; // this makes `inside_cargo_rustc` verbose.
411
423
eprintln ! ( "+ {:?}" , cmd) ;
412
424
}
413
- let exit_status =
414
- cmd. spawn ( ) . expect ( "could not run cargo" ) . wait ( ) . expect ( "failed to wait for cargo?" ) ;
415
-
416
- std:: process:: exit ( exit_status. code ( ) . unwrap_or ( -1 ) )
425
+ exec ( cmd)
417
426
}
418
427
419
- fn phase_cargo_rustc ( mut args : env:: Args ) {
428
+ fn phase_cargo_rustc ( args : env:: ArgsOs ) {
420
429
/// Determines if we are being invoked (as rustc) to build a crate for
421
430
/// the "target" architecture, in contrast to the "host" architecture.
422
431
/// Host crates are for build scripts and proc macros and still need to
@@ -451,7 +460,7 @@ fn phase_cargo_rustc(mut args: env::Args) {
451
460
// like we want them.
452
461
// Instead of compiling, we write JSON into the output file with all the relevant command-line flags
453
462
// and environment variables; this is sued alter when cargo calls us again in the CARGO_TARGET_RUNNER phase.
454
- let info = CrateRunInfo { args : Vec :: new ( ) , env : HashMap :: new ( ) } ;
463
+ let info = CrateRunInfo :: collect ( args ) ;
455
464
456
465
let mut path = PathBuf :: from ( get_arg_flag_value ( "--out-dir" ) . unwrap ( ) ) ;
457
466
path. push ( format ! (
@@ -461,14 +470,12 @@ fn phase_cargo_rustc(mut args: env::Args) {
461
470
// (and cargo passes this before the filename so it should be unique)
462
471
get_arg_flag_value( "extra-filename" ) . unwrap_or( String :: new( ) ) ,
463
472
) ) ;
464
- eprintln ! ( "Miri is supposed to run {}" , path. display( ) ) ;
465
473
466
474
let file = File :: create ( & path)
467
475
. unwrap_or_else ( |_| show_error ( format ! ( "Cannot create {}" , path. display( ) ) ) ) ;
468
476
let file = BufWriter :: new ( file) ;
469
477
serde_json:: ser:: to_writer ( file, & info)
470
478
. unwrap_or_else ( |_| show_error ( format ! ( "Cannot write to {}" , path. display( ) ) ) ) ;
471
-
472
479
return ;
473
480
}
474
481
@@ -495,24 +502,36 @@ fn phase_cargo_rustc(mut args: env::Args) {
495
502
if verbose {
496
503
eprintln ! ( "+ {:?}" , cmd) ;
497
504
}
498
- match cmd. status ( ) {
499
- Ok ( exit) =>
500
- if !exit. success ( ) {
501
- std:: process:: exit ( exit. code ( ) . unwrap_or ( 42 ) ) ;
502
- } ,
503
- Err ( e) => panic ! ( "error running {:?}:\n {:?}" , cmd, e) ,
504
- }
505
+ exec ( cmd)
505
506
}
506
507
507
- fn phase_cargo_runner ( binary : & str , args : env:: Args ) {
508
- eprintln ! ( "Asked to execute {}, args: {:?}" , binary , args . collect :: < Vec <_>> ( ) ) ;
508
+ fn phase_cargo_runner ( binary : & str , args : env:: ArgsOs ) {
509
+ let verbose = std :: env :: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
509
510
510
511
let file = File :: open ( binary)
511
512
. unwrap_or_else ( |_| show_error ( format ! ( "File {:?} not found, or cargo-miri invoked incorrectly" , binary) ) ) ;
512
513
let file = BufReader :: new ( file) ;
513
514
let info: CrateRunInfo = serde_json:: from_reader ( file)
514
515
. unwrap_or_else ( |_| show_error ( format ! ( "File {:?} does not contain valid JSON" , binary) ) ) ;
515
516
// FIXME: remove the file.
517
+
518
+ let mut cmd = miri ( ) ;
519
+ // Forward rustc arguments,with our sysroot.
520
+ cmd. args ( info. args ) ;
521
+ let sysroot =
522
+ env:: var_os ( "MIRI_SYSROOT" ) . expect ( "The wrapper should have set MIRI_SYSROOT" ) ;
523
+ cmd. arg ( "--sysroot" ) ;
524
+ cmd. arg ( sysroot) ;
525
+
526
+ // Then pass binary arguments.
527
+ cmd. arg ( "--" ) ;
528
+ cmd. args ( args) ;
529
+
530
+ // Run it.
531
+ if verbose {
532
+ eprintln ! ( "+ {:?}" , cmd) ;
533
+ }
534
+ exec ( cmd)
516
535
}
517
536
518
537
fn main ( ) {
@@ -526,7 +545,7 @@ fn main() {
526
545
return ;
527
546
}
528
547
529
- let mut args = std:: env:: args ( ) ;
548
+ let mut args = std:: env:: args_os ( ) ;
530
549
// Skip binary name.
531
550
args. next ( ) . unwrap ( ) ;
532
551
@@ -537,7 +556,8 @@ fn main() {
537
556
// binary crates for later interpretation.
538
557
// - When we are executed due to CARGO_TARGET_RUNNER, we start interpretation based on the
539
558
// flags that were stored earlier.
540
- match & * args. next ( ) . unwrap ( ) {
559
+ // FIXME: report errors for these unwraps.
560
+ match & * args. next ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) {
541
561
"miri" => phase_cargo_miri ( args) ,
542
562
"rustc" => phase_cargo_rustc ( args) ,
543
563
binary => phase_cargo_runner ( binary, args) ,
0 commit comments