@@ -7,7 +7,7 @@ use std::thread;
77use anyhow:: { anyhow, Context , Result } ;
88use dunce:: canonicalize;
99use path_macro:: path;
10- use xshell:: { cmd, Shell } ;
10+ use xshell:: { cmd, Cmd , Shell } ;
1111
1212pub fn miri_dir ( ) -> std:: io:: Result < PathBuf > {
1313 const MIRI_SCRIPT_ROOT_DIR : & str = env ! ( "CARGO_MANIFEST_DIR" ) ;
@@ -28,13 +28,14 @@ pub fn flagsplit(flags: &str) -> Vec<String> {
2828}
2929
3030/// Some extra state we track for building Miri, such as the right RUSTFLAGS.
31+ #[ derive( Clone ) ]
3132pub struct MiriEnv {
3233 /// miri_dir is the root of the miri repository checkout we are working in.
3334 pub miri_dir : PathBuf ,
3435 /// active_toolchain is passed as `+toolchain` argument to cargo/rustc invocations.
3536 pub toolchain : String ,
3637 /// Extra flags to pass to cargo.
37- pub cargo_extra_flags : Vec < String > ,
38+ cargo_extra_flags : Vec < String > ,
3839 /// The rustc sysroot
3940 pub sysroot : PathBuf ,
4041 /// The shell we use.
@@ -54,15 +55,14 @@ impl MiriEnv {
5455
5556 // Determine some toolchain properties
5657 if !libdir. exists ( ) {
57- println ! ( "Something went wrong determining the library dir." ) ;
58- println ! ( "I got {} but that does not exist." , libdir. display( ) ) ;
59- println ! ( "Please report a bug at https://github.com/rust-lang/miri/issues." ) ;
58+ eprintln ! ( "Something went wrong determining the library dir." ) ;
59+ eprintln ! ( "I got {} but that does not exist." , libdir. display( ) ) ;
60+ eprintln ! ( "Please report a bug at https://github.com/rust-lang/miri/issues." ) ;
6061 std:: process:: exit ( 2 ) ;
6162 }
62- // Share target dir between `miri` and `cargo-miri`.
63- let target_dir = std:: env:: var_os ( "CARGO_TARGET_DIR" )
64- . unwrap_or_else ( || path ! ( miri_dir / "target" ) . into ( ) ) ;
65- sh. set_var ( "CARGO_TARGET_DIR" , target_dir) ;
63+
64+ // Hard-code the target dir, since we rely on all binaries ending up in the same spot.
65+ sh. set_var ( "CARGO_TARGET_DIR" , path ! ( miri_dir / "target" ) ) ;
6666
6767 // We configure dev builds to not be unusably slow.
6868 let devel_opt_level =
@@ -91,17 +91,34 @@ impl MiriEnv {
9191 // Get extra flags for cargo.
9292 let cargo_extra_flags = std:: env:: var ( "CARGO_EXTRA_FLAGS" ) . unwrap_or_default ( ) ;
9393 let cargo_extra_flags = flagsplit ( & cargo_extra_flags) ;
94+ if cargo_extra_flags. iter ( ) . any ( |a| a == "--release" || a. starts_with ( "--profile" ) ) {
95+ // This makes binaries end up in different paths, let's not do that.
96+ eprintln ! (
97+ "Passing `--release` or `--profile` in `CARGO_EXTRA_FLAGS` will totally confuse miri-script, please don't do that."
98+ ) ;
99+ std:: process:: exit ( 1 ) ;
100+ }
94101
95102 Ok ( MiriEnv { miri_dir, toolchain, sh, sysroot, cargo_extra_flags } )
96103 }
97104
105+ pub fn cargo_cmd ( & self , manifest_path : impl AsRef < OsStr > , cmd : & str ) -> Cmd < ' _ > {
106+ let MiriEnv { toolchain, cargo_extra_flags, .. } = self ;
107+ let manifest_path = Path :: new ( manifest_path. as_ref ( ) ) ;
108+ cmd ! (
109+ self . sh,
110+ "cargo +{toolchain} {cmd} {cargo_extra_flags...} --manifest-path {manifest_path}"
111+ )
112+ }
113+
98114 pub fn install_to_sysroot (
99115 & self ,
100116 path : impl AsRef < OsStr > ,
101117 args : impl IntoIterator < Item = impl AsRef < OsStr > > ,
102118 ) -> Result < ( ) > {
103119 let MiriEnv { sysroot, toolchain, cargo_extra_flags, .. } = self ;
104120 // Install binaries to the miri toolchain's `sysroot` so they do not interact with other toolchains.
121+ // (Not using `cargo_cmd` as `install` is special and doesn't use `--manifest-path`.)
105122 cmd ! ( self . sh, "cargo +{toolchain} install {cargo_extra_flags...} --path {path} --force --root {sysroot} {args...}" ) . run ( ) ?;
106123 Ok ( ( ) )
107124 }
@@ -112,40 +129,34 @@ impl MiriEnv {
112129 args : & [ String ] ,
113130 quiet : bool ,
114131 ) -> Result < ( ) > {
115- let MiriEnv { toolchain, cargo_extra_flags, .. } = self ;
116132 let quiet_flag = if quiet { Some ( "--quiet" ) } else { None } ;
117133 // We build the tests as well, (a) to avoid having rebuilds when building the tests later
118134 // and (b) to have more parallelism during the build of Miri and its tests.
119- let mut cmd = cmd ! (
120- self . sh,
121- "cargo +{toolchain} build --bins --tests {cargo_extra_flags...} --manifest-path {manifest_path} {quiet_flag...} {args...}"
122- ) ;
135+ // This means `./miri run` without `--dep` will build Miri twice (for the sysroot with
136+ // dev-dependencies, and then for running without dev-dependencies), but the way more common
137+ // `./miri test` will avoid building Miri twice.
138+ let mut cmd = self
139+ . cargo_cmd ( manifest_path, "build" )
140+ . args ( & [ "--bins" , "--tests" ] )
141+ . args ( quiet_flag)
142+ . args ( args) ;
123143 cmd. set_quiet ( quiet) ;
124144 cmd. run ( ) ?;
125145 Ok ( ( ) )
126146 }
127147
128148 pub fn check ( & self , manifest_path : impl AsRef < OsStr > , args : & [ String ] ) -> Result < ( ) > {
129- let MiriEnv { toolchain, cargo_extra_flags, .. } = self ;
130- cmd ! ( self . sh, "cargo +{toolchain} check {cargo_extra_flags...} --manifest-path {manifest_path} --all-targets {args...}" )
131- . run ( ) ?;
149+ self . cargo_cmd ( manifest_path, "check" ) . arg ( "--all-targets" ) . args ( args) . run ( ) ?;
132150 Ok ( ( ) )
133151 }
134152
135153 pub fn clippy ( & self , manifest_path : impl AsRef < OsStr > , args : & [ String ] ) -> Result < ( ) > {
136- let MiriEnv { toolchain, cargo_extra_flags, .. } = self ;
137- cmd ! ( self . sh, "cargo +{toolchain} clippy {cargo_extra_flags...} --manifest-path {manifest_path} --all-targets {args...}" )
138- . run ( ) ?;
154+ self . cargo_cmd ( manifest_path, "clippy" ) . arg ( "--all-targets" ) . args ( args) . run ( ) ?;
139155 Ok ( ( ) )
140156 }
141157
142158 pub fn test ( & self , manifest_path : impl AsRef < OsStr > , args : & [ String ] ) -> Result < ( ) > {
143- let MiriEnv { toolchain, cargo_extra_flags, .. } = self ;
144- cmd ! (
145- self . sh,
146- "cargo +{toolchain} test {cargo_extra_flags...} --manifest-path {manifest_path} {args...}"
147- )
148- . run ( ) ?;
159+ self . cargo_cmd ( manifest_path, "test" ) . args ( args) . run ( ) ?;
149160 Ok ( ( ) )
150161 }
151162
@@ -155,7 +166,6 @@ impl MiriEnv {
155166 pub fn format_files (
156167 & self ,
157168 files : impl Iterator < Item = Result < PathBuf , walkdir:: Error > > ,
158- toolchain : & str ,
159169 config_path : & Path ,
160170 flags : & [ String ] ,
161171 ) -> anyhow:: Result < ( ) > {
@@ -166,6 +176,7 @@ impl MiriEnv {
166176 // Format in batches as not all our files fit into Windows' command argument limit.
167177 for batch in & files. chunks ( 256 ) {
168178 // Build base command.
179+ let toolchain = & self . toolchain ;
169180 let mut cmd = cmd ! (
170181 self . sh,
171182 "rustfmt +{toolchain} --edition=2021 --config-path {config_path} --unstable-features --skip-children {flags...}"
@@ -197,7 +208,7 @@ impl MiriEnv {
197208 pub fn run_many_times (
198209 & self ,
199210 range : Range < u32 > ,
200- run : impl Fn ( & Shell , u32 ) -> Result < ( ) > + Sync ,
211+ run : impl Fn ( & Self , u32 ) -> Result < ( ) > + Sync ,
201212 ) -> Result < ( ) > {
202213 // `next` is atomic so threads can concurrently fetch their next value to run.
203214 let next = AtomicU32 :: new ( range. start ) ;
@@ -207,10 +218,10 @@ impl MiriEnv {
207218 let mut handles = Vec :: new ( ) ;
208219 // Spawn one worker per core.
209220 for _ in 0 ..thread:: available_parallelism ( ) ?. get ( ) {
210- // Create a copy of the shell for this thread.
211- let local_shell = self . sh . clone ( ) ;
221+ // Create a copy of the environment for this thread.
222+ let local_miri = self . clone ( ) ;
212223 let handle = s. spawn ( || -> Result < ( ) > {
213- let local_shell = local_shell ; // move the copy into this thread.
224+ let local_miri = local_miri ; // move the copy into this thread.
214225 // Each worker thread keeps asking for numbers until we're all done.
215226 loop {
216227 let cur = next. fetch_add ( 1 , Ordering :: Relaxed ) ;
@@ -219,7 +230,7 @@ impl MiriEnv {
219230 break ;
220231 }
221232 // Run the command with this seed.
222- run ( & local_shell , cur) . inspect_err ( |_| {
233+ run ( & local_miri , cur) . inspect_err ( |_| {
223234 // If we failed, tell everyone about this.
224235 failed. store ( true , Ordering :: Relaxed ) ;
225236 } ) ?;
0 commit comments