2
2
3
3
use std:: env;
4
4
use std:: ffi:: OsStr ;
5
- use std:: fmt:: Write ;
6
5
use std:: path:: PathBuf ;
7
6
use std:: process:: { self , Command } ;
8
7
9
- use rustc_build_sysroot:: { BuildMode , SysrootBuilder , SysrootConfig } ;
8
+ use rustc_build_sysroot:: { BuildMode , SysrootBuilder , SysrootConfig , SysrootStatus } ;
10
9
use rustc_version:: VersionMeta ;
11
10
12
11
use crate :: util:: * ;
@@ -24,6 +23,7 @@ pub fn setup(
24
23
let only_setup = matches ! ( subcommand, MiriCommand :: Setup ) ;
25
24
let ask_user = !only_setup;
26
25
let print_sysroot = only_setup && has_arg_flag ( "--print-sysroot" ) ; // whether we just print the sysroot path
26
+ let show_setup = only_setup && !print_sysroot;
27
27
if !only_setup {
28
28
if let Some ( sysroot) = std:: env:: var_os ( "MIRI_SYSROOT" ) {
29
29
// Skip setup step if MIRI_SYSROOT is explicitly set, *unless* we are `cargo miri setup`.
@@ -115,18 +115,16 @@ pub fn setup(
115
115
// `config.toml`.
116
116
command. env ( "RUSTC_WRAPPER" , "" ) ;
117
117
118
- if only_setup && !print_sysroot {
118
+ if show_setup {
119
119
// Forward output. Even make it verbose, if requested.
120
+ command. stdout ( process:: Stdio :: inherit ( ) ) ;
121
+ command. stderr ( process:: Stdio :: inherit ( ) ) ;
120
122
for _ in 0 ..verbose {
121
123
command. arg ( "-v" ) ;
122
124
}
123
125
if quiet {
124
126
command. arg ( "--quiet" ) ;
125
127
}
126
- } else {
127
- // Suppress output.
128
- command. stdout ( process:: Stdio :: null ( ) ) ;
129
- command. stderr ( process:: Stdio :: null ( ) ) ;
130
128
}
131
129
132
130
command
@@ -137,49 +135,52 @@ pub fn setup(
137
135
// not apply `RUSTFLAGS` to the sysroot either.
138
136
let rustflags = & [ "-Cdebug-assertions=off" , "-Coverflow-checks=on" ] ;
139
137
140
- // Do the build.
141
- if print_sysroot || quiet {
142
- // Be silent.
143
- } else {
144
- let mut msg = String :: new ( ) ;
145
- write ! ( msg, "Preparing a sysroot for Miri (target: {target})" ) . unwrap ( ) ;
146
- if verbose > 0 {
147
- write ! ( msg, " in {}" , sysroot_dir. display( ) ) . unwrap ( ) ;
148
- }
149
- write ! ( msg, "..." ) . unwrap ( ) ;
150
- if only_setup {
151
- // We want to be explicit.
152
- eprintln ! ( "{msg}" ) ;
153
- } else {
154
- // We want to be quiet, but still let the user know that something is happening.
155
- eprint ! ( "{msg} " ) ;
138
+ let mut after_build_output = String :: new ( ) ; // what should be printed when the build is done.
139
+ let notify = || {
140
+ if !quiet {
141
+ eprint ! ( "Preparing a sysroot for Miri (target: {target})" ) ;
142
+ if verbose > 0 {
143
+ eprint ! ( " in {}" , sysroot_dir. display( ) ) ;
144
+ }
145
+ if show_setup {
146
+ // Cargo will print things, so we need to finish this line.
147
+ eprintln ! ( "..." ) ;
148
+ after_build_output = format ! (
149
+ "A sysroot for Miri is now available in `{}`.\n " ,
150
+ sysroot_dir. display( )
151
+ ) ;
152
+ } else {
153
+ // Keep all output on a single line.
154
+ eprint ! ( "... " ) ;
155
+ after_build_output = format ! ( "done\n " ) ;
156
+ }
156
157
}
157
- }
158
- SysrootBuilder :: new ( & sysroot_dir, target)
158
+ } ;
159
+
160
+ // Do the build.
161
+ let status = SysrootBuilder :: new ( & sysroot_dir, target)
159
162
. build_mode ( BuildMode :: Check )
160
163
. rustc_version ( rustc_version. clone ( ) )
161
164
. sysroot_config ( sysroot_config)
162
165
. rustflags ( rustflags)
163
166
. cargo ( cargo_cmd)
164
- . build_from_source ( & rust_src)
165
- . unwrap_or_else ( |err| {
166
- if print_sysroot {
167
- show_error ! ( "failed to build sysroot" )
168
- } else if only_setup {
169
- show_error ! ( "failed to build sysroot: {err:?}" )
170
- } else {
171
- show_error ! (
172
- "failed to build sysroot; run `cargo miri setup` to see the error details"
173
- )
174
- }
175
- } ) ;
176
- if print_sysroot || quiet {
177
- // Be silent.
178
- } else if only_setup {
179
- eprintln ! ( "A sysroot for Miri is now available in `{}`." , sysroot_dir. display( ) ) ;
180
- } else {
181
- eprintln ! ( "done" ) ;
167
+ . when_build_required ( notify)
168
+ . build_from_source ( & rust_src) ;
169
+ match status {
170
+ Ok ( SysrootStatus :: AlreadyCached ) =>
171
+ if !quiet && show_setup {
172
+ eprintln ! (
173
+ "A sysroot for Miri is already available in `{}`." ,
174
+ sysroot_dir. display( )
175
+ ) ;
176
+ } ,
177
+ Ok ( SysrootStatus :: SysrootBuilt ) => {
178
+ // Print what `notify` prepared.
179
+ eprint ! ( "{after_build_output}" ) ;
180
+ }
181
+ Err ( err) => show_error ! ( "failed to build sysroot: {err:?}" ) ,
182
182
}
183
+
183
184
if print_sysroot {
184
185
// Print just the sysroot and nothing else to stdout; this way we do not need any escaping.
185
186
println ! ( "{}" , sysroot_dir. display( ) ) ;
0 commit comments