Skip to content

Commit 0781c47

Browse files
committed
Always build miri for the host in x run miri
1 parent d327d65 commit 0781c47

File tree

4 files changed

+56
-17
lines changed

4 files changed

+56
-17
lines changed

src/bootstrap/src/core/build_steps/run.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
66
use std::path::PathBuf;
77

8+
use build_helper::exit;
89
use clap_complete::{Generator, shells};
910

1011
use crate::core::build_steps::dist::distdir;
1112
use crate::core::build_steps::test;
1213
use crate::core::build_steps::tool::{self, RustcPrivateCompilers, SourceType, Tool};
1314
use crate::core::build_steps::vendor::{Vendor, default_paths_to_vendor};
14-
use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
15+
use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata};
1516
use crate::core::config::TargetSelection;
1617
use crate::core::config::flags::get_completion;
1718
use crate::utils::exec::command;
@@ -100,8 +101,17 @@ impl Step for ReplaceVersionPlaceholder {
100101
}
101102
}
102103

104+
/// Invoke the Miri tool on a specified file.
105+
///
106+
/// Note that Miri always executed on the host, as it is an interpreter.
107+
/// That means that `x run miri --target FOO` will build miri for the host,
108+
/// prepare a miri sysroot for the target `FOO` and then execute miri with
109+
/// the target `FOO`.
103110
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
104111
pub struct Miri {
112+
/// The build compiler that will build miri and the target compiler to which miri links.
113+
compilers: RustcPrivateCompilers,
114+
/// The target which will miri interpret.
105115
target: TargetSelection,
106116
}
107117

@@ -113,14 +123,9 @@ impl Step for Miri {
113123
}
114124

115125
fn make_run(run: RunConfig<'_>) {
116-
run.builder.ensure(Miri { target: run.target });
117-
}
118-
119-
fn run(self, builder: &Builder<'_>) {
120-
let host = builder.build.host_target;
121-
let target = self.target;
126+
let builder = run.builder;
122127

123-
// `x run` uses stage 0 by default but miri does not work well with stage 0.
128+
// `x run` uses stage 0 by default, but miri does not work well with stage 0.
124129
// Change the stage to 1 if it's not set explicitly.
125130
let stage = if builder.config.is_explicit_stage() || builder.top_stage >= 1 {
126131
builder.top_stage
@@ -129,14 +134,22 @@ impl Step for Miri {
129134
};
130135

131136
if stage == 0 {
132-
eprintln!("miri cannot be run at stage 0");
133-
std::process::exit(1);
137+
eprintln!("ERROR: miri cannot be run at stage 0");
138+
exit!(1);
134139
}
135140

136-
// This compiler runs on the host, we'll just use it for the target.
137-
let compilers = RustcPrivateCompilers::new(builder, stage, target);
138-
let miri_build = builder.ensure(tool::Miri::from_compilers(compilers));
139-
let host_compiler = miri_build.build_compiler;
141+
// Miri always runs on the host, because it can interpret code for any target
142+
let compilers = RustcPrivateCompilers::new(builder, stage, builder.host_target);
143+
144+
run.builder.ensure(Miri { compilers, target: run.target });
145+
}
146+
147+
fn run(self, builder: &Builder<'_>) {
148+
let host = builder.build.host_target;
149+
let compilers = self.compilers;
150+
let target = self.target;
151+
152+
builder.ensure(tool::Miri::from_compilers(compilers));
140153

141154
// Get a target sysroot for Miri.
142155
let miri_sysroot =
@@ -147,7 +160,7 @@ impl Step for Miri {
147160
// add_rustc_lib_path does not add the path that contains librustc_driver-<...>.so.
148161
let mut miri = tool::prepare_tool_cargo(
149162
builder,
150-
host_compiler,
163+
compilers.build_compiler(),
151164
Mode::ToolRustc,
152165
host,
153166
Kind::Run,
@@ -167,6 +180,10 @@ impl Step for Miri {
167180

168181
miri.into_cmd().run(builder);
169182
}
183+
184+
fn metadata(&self) -> Option<StepMetadata> {
185+
Some(StepMetadata::run("miri", self.target).built_by(self.compilers.build_compiler()))
186+
}
170187
}
171188

172189
#[derive(Debug, Clone, Hash, PartialEq, Eq)]

src/bootstrap/src/core/builder/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@ impl StepMetadata {
182182
Self::new(name, target, Kind::Test)
183183
}
184184

185+
pub fn run(name: &str, target: TargetSelection) -> Self {
186+
Self::new(name, target, Kind::Run)
187+
}
188+
185189
fn new(name: &str, target: TargetSelection, kind: Kind) -> Self {
186190
Self { name: name.to_string(), kind, target, built_by: None, stage: None, metadata: None }
187191
}

src/bootstrap/src/core/builder/tests.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2372,6 +2372,24 @@ mod snapshot {
23722372
[dist] src <>
23732373
");
23742374
}
2375+
2376+
// Check that `x run miri --target FOO` actually builds miri for the host.
2377+
#[test]
2378+
fn run_miri() {
2379+
let ctx = TestCtx::new();
2380+
insta::assert_snapshot!(
2381+
ctx.config("run")
2382+
.path("miri")
2383+
.stage(1)
2384+
.targets(&[TEST_TRIPLE_1])
2385+
.render_steps(), @r"
2386+
[build] llvm <host>
2387+
[build] rustc 0 <host> -> rustc 1 <host>
2388+
[build] rustc 0 <host> -> miri 1 <host>
2389+
[build] rustc 0 <host> -> cargo-miri 1 <host>
2390+
[run] rustc 0 <host> -> miri 1 <target1>
2391+
");
2392+
}
23752393
}
23762394

23772395
struct ExecutedSteps {

src/bootstrap/src/core/config/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -961,8 +961,8 @@ impl Config {
961961
Subcommand::Dist => flags_stage.or(build_dist_stage).unwrap_or(2),
962962
Subcommand::Install => flags_stage.or(build_install_stage).unwrap_or(2),
963963
Subcommand::Perf { .. } => flags_stage.unwrap_or(1),
964-
// These are all bootstrap tools, which don't depend on the compiler.
965-
// The stage we pass shouldn't matter, but use 0 just in case.
964+
// Most of the run commands execute bootstrap tools, which don't depend on the compiler.
965+
// Other commands listed here should always use bootstrap tools.
966966
Subcommand::Clean { .. }
967967
| Subcommand::Run { .. }
968968
| Subcommand::Setup { .. }

0 commit comments

Comments
 (0)