Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 45 additions & 38 deletions miri-script/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ impl MiriEnv {
&mut self,
quiet: bool,
target: Option<impl AsRef<OsStr>>,
features: &[String],
) -> Result<PathBuf> {
if let Some(miri_sysroot) = self.sh.var_os("MIRI_SYSROOT") {
// Sysroot already set, use that.
return Ok(miri_sysroot.into());
}

// Make sure everything is built. Also Miri itself.
self.build(".", &[], quiet)?;
self.build("cargo-miri", &[], quiet)?;
self.build(".", features, &[], quiet)?;
self.build("cargo-miri", &[], &[], quiet)?;

let target_flag = if let Some(target) = &target {
vec![OsStr::new("--target"), target.as_ref()]
Expand All @@ -58,7 +59,7 @@ impl MiriEnv {
}

let mut cmd = self
.cargo_cmd("cargo-miri", "run")
.cargo_cmd("cargo-miri", "run", &[])
.arg("--quiet")
.arg("--")
.args(&["miri", "setup", "--print-sysroot"])
Expand Down Expand Up @@ -90,7 +91,9 @@ impl Command {
Self::fmt(vec![])?;
}
if auto_clippy {
Self::clippy(vec![])?;
// no features for auto actions, see
// https://github.com/rust-lang/miri/pull/4396#discussion_r2149654845
Self::clippy(vec![], vec![])?;
}

Ok(())
Expand Down Expand Up @@ -175,16 +178,16 @@ impl Command {
}
// Then run the actual command.
match self {
Command::Install { flags } => Self::install(flags),
Command::Build { flags } => Self::build(flags),
Command::Check { flags } => Self::check(flags),
Command::Test { bless, flags, target, coverage } =>
Self::test(bless, flags, target, coverage),
Command::Run { dep, verbose, target, edition, flags } =>
Self::run(dep, verbose, target, edition, flags),
Command::Doc { flags } => Self::doc(flags),
Command::Install { features, flags } => Self::install(features, flags),
Command::Build { features, flags } => Self::build(features, flags),
Command::Check { features, flags } => Self::check(features, flags),
Command::Test { bless, target, coverage, features, flags } =>
Self::test(bless, target, coverage, features, flags),
Command::Run { dep, verbose, target, edition, features, flags } =>
Self::run(dep, verbose, target, edition, features, flags),
Command::Doc { features, flags } => Self::doc(features, flags),
Command::Fmt { flags } => Self::fmt(flags),
Command::Clippy { flags } => Self::clippy(flags),
Command::Clippy { features, flags } => Self::clippy(features, flags),
Command::Bench { target, no_install, save_baseline, load_baseline, benches } =>
Self::bench(target, no_install, save_baseline, load_baseline, benches),
Command::Toolchain { flags } => Self::toolchain(flags),
Expand Down Expand Up @@ -494,7 +497,7 @@ impl Command {

if !no_install {
// Make sure we have an up-to-date Miri installed and selected the right toolchain.
Self::install(vec![])?;
Self::install(vec![], vec![])?;
}
let results_json_dir = if save_baseline.is_some() || load_baseline.is_some() {
Some(TempDir::new()?)
Expand Down Expand Up @@ -601,47 +604,48 @@ impl Command {
Ok(())
}

fn install(flags: Vec<String>) -> Result<()> {
fn install(features: Vec<String>, flags: Vec<String>) -> Result<()> {
let e = MiriEnv::new()?;
e.install_to_sysroot(e.miri_dir.clone(), &flags)?;
e.install_to_sysroot(path!(e.miri_dir / "cargo-miri"), &flags)?;
e.install_to_sysroot(".", &features, &flags)?;
e.install_to_sysroot("cargo-miri", &[], &flags)?;
Ok(())
}

fn build(flags: Vec<String>) -> Result<()> {
fn build(features: Vec<String>, flags: Vec<String>) -> Result<()> {
let e = MiriEnv::new()?;
e.build(".", &flags, /* quiet */ false)?;
e.build("cargo-miri", &flags, /* quiet */ false)?;
e.build(".", &features, &flags, /* quiet */ false)?;
e.build("cargo-miri", &[], &flags, /* quiet */ false)?;
Ok(())
}

fn check(flags: Vec<String>) -> Result<()> {
fn check(features: Vec<String>, flags: Vec<String>) -> Result<()> {
let e = MiriEnv::new()?;
e.check(".", &flags)?;
e.check("cargo-miri", &flags)?;
e.check(".", &features, &flags)?;
e.check("cargo-miri", &[], &flags)?;
Ok(())
}

fn doc(flags: Vec<String>) -> Result<()> {
fn doc(features: Vec<String>, flags: Vec<String>) -> Result<()> {
let e = MiriEnv::new()?;
e.doc(".", &flags)?;
e.doc("cargo-miri", &flags)?;
e.doc(".", &features, &flags)?;
e.doc("cargo-miri", &[], &flags)?;
Ok(())
}

fn clippy(flags: Vec<String>) -> Result<()> {
fn clippy(features: Vec<String>, flags: Vec<String>) -> Result<()> {
let e = MiriEnv::new()?;
e.clippy(".", &flags)?;
e.clippy("cargo-miri", &flags)?;
e.clippy("miri-script", &flags)?;
e.clippy(".", &features, &flags)?;
e.clippy("cargo-miri", &[], &flags)?;
e.clippy("miri-script", &[], &flags)?;
Ok(())
}

fn test(
bless: bool,
mut flags: Vec<String>,
target: Option<String>,
coverage: bool,
features: Vec<String>,
mut flags: Vec<String>,
) -> Result<()> {
let mut e = MiriEnv::new()?;

Expand All @@ -652,7 +656,7 @@ impl Command {
}

// Prepare a sysroot. (Also builds cargo-miri, which we need.)
e.build_miri_sysroot(/* quiet */ false, target.as_deref())?;
e.build_miri_sysroot(/* quiet */ false, target.as_deref(), &features)?;

// Forward information to test harness.
if bless {
Expand All @@ -672,10 +676,10 @@ impl Command {

// Then test, and let caller control flags.
// Only in root project as `cargo-miri` has no tests.
e.test(".", &flags)?;
e.test(".", &features, &flags)?;

if let Some(coverage) = &coverage {
coverage.show_coverage_report(&e)?;
coverage.show_coverage_report(&e, &features)?;
}

Ok(())
Expand All @@ -686,14 +690,17 @@ impl Command {
verbose: bool,
target: Option<String>,
edition: Option<String>,
features: Vec<String>,
flags: Vec<String>,
) -> Result<()> {
let mut e = MiriEnv::new()?;

// Preparation: get a sysroot, and get the miri binary.
let miri_sysroot = e.build_miri_sysroot(/* quiet */ !verbose, target.as_deref())?;
let miri_bin =
e.build_get_binary(".").context("failed to get filename of miri executable")?;
let miri_sysroot =
e.build_miri_sysroot(/* quiet */ !verbose, target.as_deref(), &features)?;
let miri_bin = e
.build_get_binary(".", &features)
.context("failed to get filename of miri executable")?;

// More flags that we will pass before `flags`
// (because `flags` may contain `--`).
Expand All @@ -718,7 +725,7 @@ impl Command {
// The basic command that executes the Miri driver.
let mut cmd = if dep {
// We invoke the test suite as that has all the logic for running with dependencies.
e.cargo_cmd(".", "test")
e.cargo_cmd(".", "test", &features)
.args(&["--test", "ui"])
.args(quiet_flag)
.arg("--")
Expand Down
7 changes: 4 additions & 3 deletions miri-script/src/coverage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl CoverageReport {

/// show_coverage_report will print coverage information using the artifact
/// files in `self.path`.
pub fn show_coverage_report(&self, e: &MiriEnv) -> Result<()> {
pub fn show_coverage_report(&self, e: &MiriEnv, features: &[String]) -> Result<()> {
let profraw_files = self.profraw_files()?;

let profdata_bin = path!(e.libdir / ".." / "bin" / "llvm-profdata");
Expand All @@ -63,8 +63,9 @@ impl CoverageReport {

// Create the coverage report.
let cov_bin = path!(e.libdir / ".." / "bin" / "llvm-cov");
let miri_bin =
e.build_get_binary(".").context("failed to get filename of miri executable")?;
let miri_bin = e
.build_get_binary(".", features)
.context("failed to get filename of miri executable")?;
cmd!(
e.sh,
"{cov_bin} report --instr-profile={merged_file} --object {miri_bin} --sources src/"
Expand Down
38 changes: 33 additions & 5 deletions miri-script/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,40 @@ pub enum Command {
/// Sets up the rpath such that the installed binary should work in any
/// working directory.
Install {
/// Pass features to cargo invocations on the "miri" crate in the root. This option does
/// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
#[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
features: Vec<String>,
/// Flags that are passed through to `cargo install`.
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
flags: Vec<String>,
},
/// Build Miri.
Build {
/// Pass features to cargo invocations on the "miri" crate in the root. This option does
/// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
#[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
features: Vec<String>,
/// Flags that are passed through to `cargo build`.
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
flags: Vec<String>,
},
/// Check Miri.
Check {
/// Pass features to cargo invocations on the "miri" crate in the root. This option does
/// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
#[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
features: Vec<String>,
/// Flags that are passed through to `cargo check`.
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
flags: Vec<String>,
},
/// Check Miri with Clippy.
Clippy {
/// Pass features to cargo invocations on the "miri" crate in the root. This option does
/// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
#[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
features: Vec<String>,
/// Flags that are passed through to `cargo clippy`.
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
flags: Vec<String>,
Expand All @@ -47,6 +63,10 @@ pub enum Command {
/// Produce coverage report.
#[arg(long)]
coverage: bool,
/// Pass features to cargo invocations on the "miri" crate in the root. This option does
/// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
#[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
features: Vec<String>,
/// Flags that are passed through to the test harness.
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
flags: Vec<String>,
Expand All @@ -67,6 +87,10 @@ pub enum Command {
/// The Rust edition.
#[arg(long)]
edition: Option<String>,
/// Pass features to cargo invocations on the "miri" crate in the root. This option does
/// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
#[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
features: Vec<String>,
/// Flags that are passed through to `miri`.
///
/// The flags set in `MIRIFLAGS` are added in front of these flags.
Expand All @@ -75,6 +99,10 @@ pub enum Command {
},
/// Build documentation.
Doc {
/// Pass features to cargo invocations on the "miri" crate in the root. This option does
/// **not** apply to other crates, so e.g. these features won't be used on "cargo-miri".
#[arg(long, value_delimiter = ',', action = clap::ArgAction::Append)]
features: Vec<String>,
/// Flags that are passed through to `cargo doc`.
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
flags: Vec<String>,
Expand Down Expand Up @@ -144,13 +172,13 @@ impl Command {
}

match self {
Self::Install { flags }
| Self::Build { flags }
| Self::Check { flags }
| Self::Doc { flags }
Self::Install { flags, .. }
| Self::Build { flags, .. }
| Self::Check { flags, .. }
| Self::Doc { flags, .. }
| Self::Fmt { flags }
| Self::Toolchain { flags }
| Self::Clippy { flags }
| Self::Clippy { flags, .. }
| Self::Run { flags, .. }
| Self::Test { flags, .. } => {
flags.extend(remainder);
Expand Down
Loading