@@ -8,6 +8,8 @@ use std::path::{Path, PathBuf};
8
8
use std:: process:: Command ;
9
9
use std:: ffi:: OsString ;
10
10
11
+ use rustc_version:: VersionMeta ;
12
+
11
13
const XARGO_MIN_VERSION : ( u32 , u32 , u32 ) = ( 0 , 3 , 20 ) ;
12
14
13
15
const CARGO_MIRI_HELP : & str = r#"Interprets bin crates and tests in Miri
@@ -97,6 +99,10 @@ fn miri() -> Command {
97
99
Command :: new ( find_miri ( ) )
98
100
}
99
101
102
+ fn version_info ( ) -> VersionMeta {
103
+ VersionMeta :: for_command ( miri ( ) ) . expect ( "failed to determine underlying rustc version of Miri" )
104
+ }
105
+
100
106
fn cargo ( ) -> Command {
101
107
Command :: new ( env:: var_os ( "CARGO" ) . unwrap_or_else ( || OsString :: from ( "cargo" ) ) )
102
108
}
@@ -105,10 +111,6 @@ fn xargo_check() -> Command {
105
111
Command :: new ( env:: var_os ( "XARGO_CHECK" ) . unwrap_or_else ( || OsString :: from ( "xargo-check" ) ) )
106
112
}
107
113
108
- fn rustc ( ) -> Command {
109
- Command :: new ( env:: var_os ( "RUSTC" ) . unwrap_or_else ( || OsString :: from ( "rustc" ) ) )
110
- }
111
-
112
114
fn list_targets ( ) -> impl Iterator < Item = cargo_metadata:: Target > {
113
115
// We need to get the manifest, and then the metadata, to enumerate targets.
114
116
let manifest_path =
@@ -153,55 +155,6 @@ fn list_targets() -> impl Iterator<Item = cargo_metadata::Target> {
153
155
package. targets . into_iter ( )
154
156
}
155
157
156
- /// Make sure that the `miri` and `rustc` binary are from the same sysroot.
157
- /// This can be violated e.g. when miri is locally built and installed with a different
158
- /// toolchain than what is used when `cargo miri` is run.
159
- fn test_sysroot_consistency ( ) {
160
- fn get_sysroot ( mut cmd : Command ) -> PathBuf {
161
- let out = cmd
162
- . arg ( "--print" )
163
- . arg ( "sysroot" )
164
- . output ( )
165
- . expect ( "Failed to run rustc to get sysroot info" ) ;
166
- let stdout = String :: from_utf8 ( out. stdout ) . expect ( "stdout is not valid UTF-8" ) ;
167
- let stderr = String :: from_utf8 ( out. stderr ) . expect ( "stderr is not valid UTF-8" ) ;
168
- assert ! (
169
- out. status. success( ) ,
170
- "Bad status code {} when getting sysroot info via {:?}.\n stdout:\n {}\n stderr:\n {}" ,
171
- out. status,
172
- cmd,
173
- stdout,
174
- stderr,
175
- ) ;
176
- let stdout = stdout. trim ( ) ;
177
- PathBuf :: from ( stdout)
178
- . canonicalize ( )
179
- . unwrap_or_else ( |_| panic ! ( "Failed to canonicalize sysroot: {}" , stdout) )
180
- }
181
-
182
- // Do not check sysroots if we got built as part of a Rust distribution.
183
- // During `bootstrap`, the sysroot does not match anyway, and then some distros
184
- // play symlink tricks so the sysroots may be different even for the final stage
185
- // (see <https://github.com/mozilla/nixpkgs-mozilla/issues/198>).
186
- if option_env ! ( "RUSTC_STAGE" ) . is_some ( ) {
187
- return ;
188
- }
189
-
190
- let rustc_sysroot = get_sysroot ( rustc ( ) ) ;
191
- let miri_sysroot = get_sysroot ( miri ( ) ) ;
192
-
193
- if rustc_sysroot != miri_sysroot {
194
- show_error ( format ! (
195
- "miri was built for a different sysroot than the rustc in your current toolchain.\n \
196
- Make sure you use the same toolchain to run miri that you used to build it!\n \
197
- rustc sysroot: `{}`\n \
198
- miri sysroot: `{}`",
199
- rustc_sysroot. display( ) ,
200
- miri_sysroot. display( )
201
- ) ) ;
202
- }
203
- }
204
-
205
158
fn xargo_version ( ) -> Option < ( u32 , u32 , u32 ) > {
206
159
let out = xargo_check ( ) . arg ( "--version" ) . output ( ) . ok ( ) ?;
207
160
if !out. status . success ( ) {
@@ -300,10 +253,10 @@ fn setup(subcommand: MiriCommand) {
300
253
Some ( val) => PathBuf :: from ( val) ,
301
254
None => {
302
255
// Check for `rust-src` rustup component.
303
- let sysroot = rustc ( )
256
+ let sysroot = miri ( )
304
257
. args ( & [ "--print" , "sysroot" ] )
305
258
. output ( )
306
- . expect ( "failed to get rustc sysroot" )
259
+ . expect ( "failed to determine sysroot" )
307
260
. stdout ;
308
261
let sysroot = std:: str:: from_utf8 ( & sysroot) . unwrap ( ) ;
309
262
let sysroot = Path :: new ( sysroot. trim_end_matches ( '\n' ) ) ;
@@ -316,7 +269,7 @@ fn setup(subcommand: MiriCommand) {
316
269
ask_to_run (
317
270
cmd,
318
271
ask_user,
319
- "install the rustc -src component for the selected toolchain" ,
272
+ "install the `rust -src` component for the selected toolchain" ,
320
273
) ;
321
274
}
322
275
rustup_src
@@ -368,7 +321,7 @@ path = "lib.rs"
368
321
369
322
// Determine architectures.
370
323
// We always need to set a target so rustc bootstrap can tell apart host from target crates.
371
- let host = rustc_version :: version_meta ( ) . unwrap ( ) . host ;
324
+ let host = version_info ( ) . host ;
372
325
let target = get_arg_flag_value ( "--target" ) ;
373
326
let target = target. as_ref ( ) . unwrap_or ( & host) ;
374
327
// Now invoke xargo.
@@ -389,7 +342,6 @@ path = "lib.rs"
389
342
command. env ( "RUSTC" , find_miri ( ) ) ;
390
343
}
391
344
command. env ( "MIRI_BE_RUSTC" , "1" ) ;
392
- command. env ( "RUSTFLAGS" , miri:: miri_default_args ( ) . join ( " " ) ) ;
393
345
// Finally run it!
394
346
if command. status ( ) . expect ( "failed to run xargo" ) . success ( ) . not ( ) {
395
347
show_error ( format ! ( "Failed to run xargo" ) ) ;
@@ -424,9 +376,6 @@ fn in_cargo_miri() {
424
376
} ;
425
377
let verbose = has_arg_flag ( "-v" ) ;
426
378
427
- // Some basic sanity checks
428
- test_sysroot_consistency ( ) ;
429
-
430
379
// We always setup.
431
380
setup ( subcommand) ;
432
381
if subcommand == MiriCommand :: Setup {
@@ -478,7 +427,7 @@ fn in_cargo_miri() {
478
427
if get_arg_flag_value ( "--target" ) . is_none ( ) {
479
428
// When no `--target` is given, default to the host.
480
429
cmd. arg ( "--target" ) ;
481
- cmd. arg ( rustc_version :: version_meta ( ) . unwrap ( ) . host ) ;
430
+ cmd. arg ( version_info ( ) . host ) ;
482
431
}
483
432
484
433
// Serialize the remaining args into a special environemt variable.
@@ -540,51 +489,46 @@ fn inside_cargo_rustc() {
540
489
let verbose = std:: env:: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
541
490
let target_crate = is_target_crate ( ) ;
542
491
543
- // Figure out which arguments we need to pass.
544
- let mut args: Vec < String > = std:: env:: args ( ) . skip ( 2 ) . collect ( ) ; // skip `cargo-miri rustc`
545
- // We make sure to only specify our custom Xargo sysroot and
546
- // other args for target crates - that is, crates which are ultimately
547
- // going to get interpreted by Miri.
492
+ let mut cmd = miri ( ) ;
493
+ // Forward arguments.
494
+ cmd. args ( std:: env:: args ( ) . skip ( 2 ) ) ; // skip `cargo-miri rustc`
495
+
496
+ // We make sure to only specify our custom Xargo sysroot for target crates - that is,
497
+ // crates which are ultimately going to get interpreted by Miri.
548
498
if target_crate {
549
- // FIXME: breaks for non-UTF-8 sysroots (use `var_os` instead).
550
499
let sysroot =
551
- std:: env:: var ( "MIRI_SYSROOT" ) . expect ( "The wrapper should have set MIRI_SYSROOT" ) ;
552
- args. push ( "--sysroot" . to_owned ( ) ) ;
553
- args. push ( sysroot) ;
554
- args. splice ( 0 ..0 , miri:: miri_default_args ( ) . iter ( ) . map ( ToString :: to_string) ) ;
500
+ env:: var_os ( "MIRI_SYSROOT" ) . expect ( "The wrapper should have set MIRI_SYSROOT" ) ;
501
+ cmd. arg ( "--sysroot" ) ;
502
+ cmd. arg ( sysroot) ;
555
503
}
556
504
557
- // Figure out the binary we need to call. If this is a runnable target crate, we want to call
558
- // Miri to start interpretation; otherwise we want to call rustc to build the crate as usual.
559
- let mut command = if target_crate && is_runnable_crate ( ) {
560
- // This is the 'target crate' - the binary or test crate that
561
- // we want to interpret under Miri. We deserialize the user-provided arguments
562
- // from the special environment variable "MIRI_ARGS", and feed them
563
- // to the 'miri' binary.
505
+ // If this is a runnable target crate, we want Miri to start interpretation;
506
+ // otherwise we want Miri to behave like rustc and build the crate as usual.
507
+ if target_crate && is_runnable_crate ( ) {
508
+ // This is the binary or test crate that we want to interpret under Miri.
509
+ // We deserialize the arguments that are meant for Miri from the special environment
510
+ // variable "MIRI_ARGS", and feed them to the 'miri' binary.
564
511
//
565
512
// `env::var` is okay here, well-formed JSON is always UTF-8.
566
513
let magic = std:: env:: var ( "MIRI_ARGS" ) . expect ( "missing MIRI_ARGS" ) ;
567
- let mut user_args : Vec < String > =
514
+ let miri_args : Vec < String > =
568
515
serde_json:: from_str ( & magic) . expect ( "failed to deserialize MIRI_ARGS" ) ;
569
- args. append ( & mut user_args) ;
570
- // Run this in Miri.
571
- miri ( )
516
+ cmd. args ( miri_args) ;
572
517
} else {
573
- rustc ( )
518
+ // We want to compile, not interpret.
519
+ cmd. env ( "MIRI_BE_RUSTC" , "1" ) ;
574
520
} ;
575
521
576
522
// Run it.
577
- command. args ( & args) ;
578
523
if verbose {
579
- eprintln ! ( "+ {:?}" , command ) ;
524
+ eprintln ! ( "+ {:?}" , cmd ) ;
580
525
}
581
-
582
- match command. status ( ) {
526
+ match cmd. status ( ) {
583
527
Ok ( exit) =>
584
528
if !exit. success ( ) {
585
529
std:: process:: exit ( exit. code ( ) . unwrap_or ( 42 ) ) ;
586
530
} ,
587
- Err ( e) => panic ! ( "error running {:?}:\n {:?}" , command , e) ,
531
+ Err ( e) => panic ! ( "error running {:?}:\n {:?}" , cmd , e) ,
588
532
}
589
533
}
590
534
@@ -609,6 +553,6 @@ fn main() {
609
553
// dependencies get dispatched to `rustc`, the final test/binary to `miri`.
610
554
inside_cargo_rustc ( ) ;
611
555
} else {
612
- show_error ( format ! ( "must be called with either `miri` or `rustc` as first argument." ) )
556
+ show_error ( format ! ( "`cargo-miri` must be called with either `miri` or `rustc` as first argument." ) )
613
557
}
614
558
}
0 commit comments