Skip to content

Commit

Permalink
Auto merge of #3881 - RalfJung:miri-run, r=RalfJung
Browse files Browse the repository at this point in the history
./miri run: directly run binary instead of using 'cargo run'

This avoids re-building miri without dev dependencies, so it makes `./miri run` a lot faster if `./miri test` was already executed before.
  • Loading branch information
bors committed Sep 13, 2024
2 parents c0fb1a7 + 231cfd2 commit 6cab57f
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 48 deletions.
2 changes: 1 addition & 1 deletion ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ time ./miri install
# We enable all features to make sure the Stacked Borrows consistency check runs.
echo "Building debug version of Miri"
export CARGO_EXTRA_FLAGS="$CARGO_EXTRA_FLAGS --all-features"
time ./miri build --all-targets # the build that all the `./miri test` below will use
time ./miri build # the build that all the `./miri test` below will use

endgroup

Expand Down
118 changes: 88 additions & 30 deletions miri-script/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions miri-script/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ xshell = "0.2.6"
rustc_version = "0.4"
dunce = "1.0.4"
directories = "5"
serde_json = "1"
13 changes: 7 additions & 6 deletions miri-script/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,11 +494,15 @@ impl Command {
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")?;

// More flags that we will pass before `flags`
// (because `flags` may contain `--`).
let mut early_flags = Vec::<OsString>::new();

// Add target, edition to flags.
if let Some(target) = &target {
early_flags.push("--target".into());
early_flags.push(target.into());
Expand All @@ -508,9 +512,6 @@ impl Command {
}
early_flags.push("--edition".into());
early_flags.push(edition.as_deref().unwrap_or("2021").into());

// Prepare a sysroot, add it to the flags. (Also builds cargo-miri, which we need.)
let miri_sysroot = e.build_miri_sysroot(/* quiet */ !verbose, target.as_deref())?;
early_flags.push("--sysroot".into());
early_flags.push(miri_sysroot.into());

Expand All @@ -529,7 +530,7 @@ impl Command {
.arg("--")
.args(&["--miri-run-dep-mode"])
} else {
e.cargo_cmd(".", "run").args(quiet_flag).arg("--")
cmd!(e.sh, "{miri_bin}")
};
cmd.set_quiet(!verbose);
// Add Miri flags
Expand Down
42 changes: 31 additions & 11 deletions miri-script/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::ffi::{OsStr, OsString};
use std::io::BufRead;
use std::ops::Range;
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
use std::thread;

use anyhow::{anyhow, Context, Result};
use anyhow::{anyhow, bail, Context, Result};
use dunce::canonicalize;
use path_macro::path;
use xshell::{cmd, Cmd, Shell};
Expand Down Expand Up @@ -126,21 +127,40 @@ impl MiriEnv {

pub fn build(&self, crate_dir: impl AsRef<OsStr>, args: &[String], quiet: bool) -> Result<()> {
let quiet_flag = if quiet { Some("--quiet") } else { None };
// We build the tests as well, (a) to avoid having rebuilds when building the tests later
// and (b) to have more parallelism during the build of Miri and its tests.
// This means `./miri run` without `--dep` will build Miri twice (for the sysroot with
// dev-dependencies, and then for running without dev-dependencies), but the way more common
// `./miri test` will avoid building Miri twice.
let mut cmd = self
.cargo_cmd(crate_dir, "build")
.args(&["--bins", "--tests"])
.args(quiet_flag)
.args(args);
// We build all targets, since building *just* the bin target doesnot include
// `dev-dependencies` and that changes feature resolution. This also gets us more
// parallelism in `./miri test` as we build Miri and its tests together.
let mut cmd =
self.cargo_cmd(crate_dir, "build").args(&["--all-targets"]).args(quiet_flag).args(args);
cmd.set_quiet(quiet);
cmd.run()?;
Ok(())
}

/// Returns the path to the main crate binary. Assumes that `build` has been called before.
pub fn build_get_binary(&self, crate_dir: impl AsRef<OsStr>) -> Result<PathBuf> {
let cmd =
self.cargo_cmd(crate_dir, "build").args(&["--all-targets", "--message-format=json"]);
let output = cmd.output()?;
let mut bin = None;
for line in output.stdout.lines() {
let line = line?;
if line.starts_with("{") {
let json: serde_json::Value = serde_json::from_str(&line)?;
if json["reason"] == "compiler-artifact"
&& !json["profile"]["test"].as_bool().unwrap()
&& !json["executable"].is_null()
{
if bin.is_some() {
bail!("found two binaries in cargo output");
}
bin = Some(PathBuf::from(json["executable"].as_str().unwrap()))
}
}
}
bin.ok_or_else(|| anyhow!("found no binary in cargo output"))
}

pub fn check(&self, crate_dir: impl AsRef<OsStr>, args: &[String]) -> Result<()> {
self.cargo_cmd(crate_dir, "check").arg("--all-targets").args(args).run()?;
Ok(())
Expand Down

0 comments on commit 6cab57f

Please sign in to comment.