Skip to content

Commit 6580a22

Browse files
committed
Allow test targets to be set via CLI args
1 parent 720ff0d commit 6580a22

File tree

2 files changed

+75
-23
lines changed

2 files changed

+75
-23
lines changed

src/tools/miri/miri-script/src/commands.rs

+40-17
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ const JOSH_PORT: &str = "42042";
2323

2424
impl MiriEnv {
2525
/// Returns the location of the sysroot.
26-
fn build_miri_sysroot(&mut self, quiet: bool) -> Result<PathBuf> {
26+
///
27+
/// If the target is None the sysroot will be built for the host machine.
28+
fn build_miri_sysroot(&mut self, quiet: bool, target: Option<&str>) -> Result<PathBuf> {
2729
if let Some(miri_sysroot) = self.sh.var_os("MIRI_SYSROOT") {
2830
// Sysroot already set, use that.
2931
return Ok(miri_sysroot.into());
@@ -35,26 +37,27 @@ impl MiriEnv {
3537
self.build(path!(self.miri_dir / "Cargo.toml"), &[], quiet)?;
3638
self.build(&manifest_path, &[], quiet)?;
3739

38-
let target = &match self.sh.var("MIRI_TEST_TARGET") {
39-
Ok(target) => vec!["--target".into(), target],
40-
Err(_) => vec![],
41-
};
40+
let target_flag =
41+
&if let Some(target) = target { vec!["--target", target] } else { vec![] };
42+
4243
if !quiet {
43-
match self.sh.var("MIRI_TEST_TARGET") {
44-
Ok(target) => eprintln!("$ (building Miri sysroot for {target})"),
45-
Err(_) => eprintln!("$ (building Miri sysroot)"),
44+
if let Some(target) = target {
45+
eprintln!("$ (building Miri sysroot for {target})");
46+
} else {
47+
eprintln!("$ (building Miri sysroot)");
4648
}
4749
}
50+
4851
let output = cmd!(self.sh,
4952
"cargo +{toolchain} --quiet run {cargo_extra_flags...} --manifest-path {manifest_path} --
50-
miri setup --print-sysroot {target...}"
53+
miri setup --print-sysroot {target_flag...}"
5154
).read();
5255
let Ok(output) = output else {
5356
// Run it again (without `--print-sysroot` or `--quiet`) so the user can see the error.
5457
cmd!(
5558
self.sh,
5659
"cargo +{toolchain} run {cargo_extra_flags...} --manifest-path {manifest_path} --
57-
miri setup {target...}"
60+
miri setup {target_flag...}"
5861
)
5962
.run()
6063
.with_context(|| "`cargo miri setup` failed")?;
@@ -161,7 +164,7 @@ impl Command {
161164
Command::Install { flags } => Self::install(flags),
162165
Command::Build { flags } => Self::build(flags),
163166
Command::Check { flags } => Self::check(flags),
164-
Command::Test { bless, flags } => Self::test(bless, flags),
167+
Command::Test { bless, flags, target } => Self::test(bless, flags, target),
165168
Command::Run { dep, verbose, many_seeds, flags } =>
166169
Self::run(dep, verbose, many_seeds, flags),
167170
Command::Fmt { flags } => Self::fmt(flags),
@@ -446,16 +449,23 @@ impl Command {
446449
Ok(())
447450
}
448451

449-
fn test(bless: bool, flags: Vec<OsString>) -> Result<()> {
452+
fn test(bless: bool, flags: Vec<OsString>, target: Option<String>) -> Result<()> {
450453
let mut e = MiriEnv::new()?;
454+
455+
if let Some(target) = target.as_deref() {
456+
// Tell the sysroot which target to test.
457+
e.sh.set_var("MIRI_TEST_TARGET", target);
458+
}
459+
451460
// Prepare a sysroot.
452-
e.build_miri_sysroot(/* quiet */ false)?;
461+
e.build_miri_sysroot(/* quiet */ false, target.as_deref())?;
453462

454463
// Then test, and let caller control flags.
455464
// Only in root project as `cargo-miri` has no tests.
456465
if bless {
457466
e.sh.set_var("RUSTC_BLESS", "Gesundheit");
458467
}
468+
459469
e.test(path!(e.miri_dir / "Cargo.toml"), &flags)?;
460470
Ok(())
461471
}
@@ -476,14 +486,26 @@ impl Command {
476486
.take_while(|arg| *arg != "--")
477487
.tuple_windows()
478488
.find(|(first, _)| *first == "--target");
479-
if let Some((_, target)) = target {
489+
490+
let target_triple = if let Some((_, target)) = target {
480491
// Found it!
481492
e.sh.set_var("MIRI_TEST_TARGET", target);
493+
494+
let triple = target
495+
.clone()
496+
.into_string()
497+
.map_err(|_| anyhow!("invalid target triple encoding"))?;
498+
Some(triple)
482499
} else if let Ok(target) = std::env::var("MIRI_TEST_TARGET") {
483500
// Convert `MIRI_TEST_TARGET` into `--target`.
484501
flags.push("--target".into());
485-
flags.push(target.into());
486-
}
502+
flags.push(target.clone().into());
503+
504+
Some(target)
505+
} else {
506+
None
507+
};
508+
487509
// Scan for "--edition", set one ourselves if that flag is not present.
488510
let have_edition =
489511
flags.iter().take_while(|arg| *arg != "--").any(|arg| *arg == "--edition");
@@ -492,7 +514,8 @@ impl Command {
492514
}
493515

494516
// Prepare a sysroot, and add it to the flags.
495-
let miri_sysroot = e.build_miri_sysroot(/* quiet */ !verbose)?;
517+
let miri_sysroot =
518+
e.build_miri_sysroot(/* quiet */ !verbose, target_triple.as_deref())?;
496519
flags.push("--sysroot".into());
497520
flags.push(miri_sysroot.into());
498521

src/tools/miri/miri-script/src/main.rs

+35-6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ pub enum Command {
3333
bless: bool,
3434
/// Flags that are passed through to `cargo test`.
3535
flags: Vec<OsString>,
36+
/// The cross-interpretation target.
37+
/// If none then the host is the target.
38+
target: Option<String>,
3639
},
3740
/// Build miri, set up a sysroot and then run the driver with the given <flags>.
3841
/// (Also respects MIRIFLAGS environment variable.)
@@ -84,9 +87,9 @@ Just build miri. <flags> are passed to `cargo build`.
8487
./miri check <flags>:
8588
Just check miri. <flags> are passed to `cargo check`.
8689
87-
./miri test [--bless] <flags>:
90+
./miri test [--bless] [--target] <flags>:
8891
Build miri, set up a sysroot and then run the test suite. <flags> are passed
89-
to the final `cargo test` invocation.
92+
to the test harness.
9093
9194
./miri run [--dep] [-v|--verbose] [--many-seeds|--many-seeds=..to|--many-seeds=from..to] <flags>:
9295
Build miri, set up a sysroot and then run the driver with the given <flags>.
@@ -147,12 +150,38 @@ fn main() -> Result<()> {
147150
Some("build") => Command::Build { flags: args.collect() },
148151
Some("check") => Command::Check { flags: args.collect() },
149152
Some("test") => {
150-
let bless = args.peek().is_some_and(|a| a.to_str() == Some("--bless"));
151-
if bless {
152-
// Consume the flag.
153+
let mut target = std::env::var("MIRI_TEST_TARGET").ok();
154+
let mut bless = false;
155+
156+
while let Some(arg) = args.peek().and_then(|s| s.to_str()) {
157+
match arg {
158+
"--bless" => bless = true,
159+
"--target" => {
160+
// Skip "--target"
161+
args.next().unwrap();
162+
163+
// Check that there is a target triple, and that it is unicode.
164+
target = if let Some(value) = args.peek() {
165+
let target_str = value
166+
.clone()
167+
.into_string()
168+
.map_err(|_| anyhow!("invalid target triple encoding"))?;
169+
Some(target_str)
170+
} else {
171+
bail!("no target triple found")
172+
}
173+
}
174+
// Only parse the leading flags.
175+
_ => break,
176+
}
177+
178+
// Consume the flag, look at the next one.
153179
args.next().unwrap();
154180
}
155-
Command::Test { bless, flags: args.collect() }
181+
182+
// Prepend a "--" so that the rest of the arguments are passed to the test driver.
183+
let args = std::iter::once(OsString::from("--")).chain(args);
184+
Command::Test { bless, flags: args.collect(), target }
156185
}
157186
Some("run") => {
158187
let mut dep = false;

0 commit comments

Comments
 (0)