Skip to content

Commit

Permalink
A bunch of cleanup, fix check for build script
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaron1011 committed Nov 14, 2019
1 parent db95061 commit f41c720
Showing 1 changed file with 43 additions and 50 deletions.
93 changes: 43 additions & 50 deletions src/bin/cargo-miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,36 @@ fn get_arg_flag_value(name: &str) -> Option<String> {
}
}

fn list_targets() -> (impl Iterator<Item=cargo_metadata::Target>, String) {
fn is_build_dep(mut args: impl Iterator<Item = String>) -> bool {
args.any(|arg| arg.starts_with("--emit=") && arg.contains("link"))
}

// Returns whether or not Cargo invoked the wrapper (this binary) to compile
// the final, target crate (either a test for 'cargo test', or a binary for 'cargo run')
// Right now, this is an awful hack that checks several different pieces of information
// to try to figure out if the crate being compiled is the right one.
// Ideally, Cargo would set en environment variable indicating whether or
// not the wrapper is being invoked on the target crate.
// For now, this is the best we can do
fn is_target_crate(is_build_script: bool) -> bool {
// Cargo sets this to the directory containing the manifest of the crate
// the wrapper is being invoekd to compile. This should be unique
// across the entire build (except for build scripts, which we handle below).
// We cannot check the crate name, since this may not be unique
// (e.g. if the build contains multiple versions of the same crate,
// or the same crate from multiple sources)
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").ok();

// The manifest directory for our target crate. This is set by `cargo-miri`
// (the original invoation by the user) by using `cargo_metadata` to locate
// the manifest.
let expected_dir = std::env::var("MIRI_MAGIC_DIR").expect("MIRI_MAGIC_DIR not set!");

manifest_dir == Some(expected_dir) && !is_build_script

}

fn read_cargo_metadata() -> (impl Iterator<Item=cargo_metadata::Target>, String) {
// We need to get the manifest, and then the metadata, to enumerate targets.
let manifest_path = get_arg_flag_value("--manifest-path").map(|m|
Path::new(&m).canonicalize().unwrap()
Expand Down Expand Up @@ -411,7 +440,7 @@ fn in_cargo_miri() {
return;
}

let (targets, root_dir) = list_targets();
let (targets, root_dir) = read_cargo_metadata();

// Now run the command.
for target in targets {
Expand Down Expand Up @@ -460,14 +489,7 @@ fn in_cargo_miri() {

cmd.env("MIRI_MAGIC_ARGS", prefixed_args);
cmd.env("MIRI_MAGIC_DIR", root_dir.clone());
// Add `--` (to end the `cargo` flags), and then the user flags. We add markers around the
// user flags to be able to identify them later. "cargo rustc" adds more stuff after this,
// so we have to mark both the beginning and the end.
/*cmd
.arg("--")
.arg("cargo-miri-marker-begin")
.args(args)
.arg("cargo-miri-marker-end");*/

let path = std::env::current_exe().expect("current executable path invalid");
cmd.env("RUSTC_WRAPPER", path);
if verbose {
Expand All @@ -492,57 +514,34 @@ fn inside_cargo_rustc() {

let rustc_args = std::env::args().skip(2); // skip `cargo rustc`

let (mut args, is_build_script) = if std::env::args().skip(2).find(|arg| arg == "build_script_build").is_some() {
(rustc_args.collect(), true)

eprintln!("cargo rustc env: {:?}", std::env::vars().collect::<Vec<_>>());

let in_build_script = is_build_dep(std::env::args().skip(2));


let mut args = if in_build_script {
rustc_args.collect()
} else {
let mut args: Vec<String> = rustc_args
.chain(Some("--sysroot".to_owned()))
.chain(Some(sysroot))
.collect();
args.splice(0..0, miri::miri_default_args().iter().map(ToString::to_string));
(args, false)
args
};


let is_test = args.contains(&"--test".to_string());
let mut is_bin = false;
for (i, arg) in args.iter().enumerate() {
if arg == "--crate-type" && args[i + 1] == "bin" {
is_bin = true;
break;
}
}


let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").ok();
let expected_dir = std::env::var("MIRI_MAGIC_DIR").ok();

//eprintln!("Manifest: {:?}", manifest_dir);
//eprintln!("Magic dir: {:?}", expected_dir);


// See if we can find the `cargo-miri` markers. Those only get added to the binary we want to
// run. They also serve to mark the user-defined arguments, which we have to move all the way
// to the end (they get added somewhere in the middle).
//let needs_miri = if let Some(begin) = args.iter().position(|arg| arg == "cargo-miri-marker-begin") {
let needs_miri = if manifest_dir == expected_dir && (is_bin || is_test) && !is_build_script {
/*let end = args
.iter()
.position(|arg| arg == "cargo-miri-marker-end")
.expect("cannot find end marker");
// These mark the user arguments. We remove the first and last as they are the markers.
let mut user_args = args.drain(begin..=end);*/

let raw_args = std::env::var("MIRI_MAGIC_ARGS").expect("Misisng magic!");
let needs_miri = if is_target_crate(in_build_script) {
let raw_args = std::env::var("MIRI_MAGIC_ARGS").expect("Missing magic!");
let mut user_args = vec![];
let mut slice = raw_args.as_str();
//eprintln!("Raw args: {:?}", raw_args);
loop {
match slice.find(';') {
Some(pos) => {
//eprintln!("Slice: {:?} Len str: (pos {}) {:?}", slice, pos, &slice[..(pos)]);
let len: usize = slice[..(pos)].parse().unwrap();
//eprintln!("Parsed len: {:?}", len);
let arg = slice[(pos+1)..=(pos+len)].to_string();
user_args.push(arg);
slice = &slice[(pos+len+1)..];
Expand All @@ -551,12 +550,6 @@ fn inside_cargo_rustc() {
}
}

//println!("User args: {:?}", user_args);

//assert_eq!(user_args.next().unwrap(), "cargo-miri-marker-begin");
//assert_eq!(user_args.next_back().unwrap(), "cargo-miri-marker-end");
// Collect the rest and add it back at the end.
//let mut user_args = user_args.collect::<Vec<String>>();
args.append(&mut user_args);
// Run this in Miri.
true
Expand Down

0 comments on commit f41c720

Please sign in to comment.