22
33use std:: env;
44use std:: ffi:: OsStr ;
5- use std:: fmt:: Write ;
65use std:: path:: PathBuf ;
76use std:: process:: { self , Command } ;
87
9- use rustc_build_sysroot:: { BuildMode , SysrootBuilder , SysrootConfig } ;
8+ use rustc_build_sysroot:: { BuildMode , SysrootBuilder , SysrootConfig , SysrootStatus } ;
109use rustc_version:: VersionMeta ;
1110
1211use crate :: util:: * ;
@@ -24,6 +23,7 @@ pub fn setup(
2423 let only_setup = matches ! ( subcommand, MiriCommand :: Setup ) ;
2524 let ask_user = !only_setup;
2625 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;
2727 if !only_setup {
2828 if let Some ( sysroot) = std:: env:: var_os ( "MIRI_SYSROOT" ) {
2929 // Skip setup step if MIRI_SYSROOT is explicitly set, *unless* we are `cargo miri setup`.
@@ -115,18 +115,16 @@ pub fn setup(
115115 // `config.toml`.
116116 command. env ( "RUSTC_WRAPPER" , "" ) ;
117117
118- if only_setup && !print_sysroot {
118+ if show_setup {
119119 // Forward output. Even make it verbose, if requested.
120+ command. stdout ( process:: Stdio :: inherit ( ) ) ;
121+ command. stderr ( process:: Stdio :: inherit ( ) ) ;
120122 for _ in 0 ..verbose {
121123 command. arg ( "-v" ) ;
122124 }
123125 if quiet {
124126 command. arg ( "--quiet" ) ;
125127 }
126- } else {
127- // Suppress output.
128- command. stdout ( process:: Stdio :: null ( ) ) ;
129- command. stderr ( process:: Stdio :: null ( ) ) ;
130128 }
131129
132130 command
@@ -137,49 +135,52 @@ pub fn setup(
137135 // not apply `RUSTFLAGS` to the sysroot either.
138136 let rustflags = & [ "-Cdebug-assertions=off" , "-Coverflow-checks=on" ] ;
139137
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+ }
156157 }
157- }
158- SysrootBuilder :: new ( & sysroot_dir, target)
158+ } ;
159+
160+ // Do the build.
161+ let status = SysrootBuilder :: new ( & sysroot_dir, target)
159162 . build_mode ( BuildMode :: Check )
160163 . rustc_version ( rustc_version. clone ( ) )
161164 . sysroot_config ( sysroot_config)
162165 . rustflags ( rustflags)
163166 . 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:?}" ) ,
182182 }
183+
183184 if print_sysroot {
184185 // Print just the sysroot and nothing else to stdout; this way we do not need any escaping.
185186 println ! ( "{}" , sysroot_dir. display( ) ) ;
0 commit comments