From 8ec371747a742d8f96effe80b9bfcfa53ff6fa62 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 12 Dec 2018 11:03:42 +0100 Subject: [PATCH] do not auto-detect the targets in the sysroot, instead specify target manually through env var --- .travis.yml | 14 ++++--- README.md | 12 +++++- tests/compiletest.rs | 89 ++++++++++++-------------------------------- 3 files changed, 41 insertions(+), 74 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1d49394e29..a58ff4f67d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,12 @@ before_script: else export MIRI_SYSROOT_BASE=~/.cache/miri/ fi +- | + if [[ "$TRAVIS_OS_NAME" == osx ]]; then + FOREIGN_TARGET=i686-apple-darwin + else + FOREIGN_TARGET=i686-unknown-linux-gnu + fi # install Rust - curl https://build.travis-ci.org/files/rustup-init.sh -sSf | sh -s -- -y --default-toolchain "$RUST_TOOLCHAIN" - export PATH=$HOME/.cargo/bin:$PATH @@ -43,15 +49,11 @@ script: - | # Get ourselves a MIR-full libstd for the host and a foreign architecture cargo miri setup && - if [[ "$TRAVIS_OS_NAME" == osx ]]; then - cargo miri setup --target i686-apple-darwin - else - cargo miri setup --target i686-unknown-linux-gnu - fi + cargo miri setup --target "$FOREIGN_TARGET" - | # Test miri with full MIR, on the host and other architectures MIRI_SYSROOT=$MIRI_SYSROOT_BASE/HOST cargo test --release --all-features && - MIRI_SYSROOT=$MIRI_SYSROOT_BASE cargo test --release --all-features + MIRI_SYSROOT=$MIRI_SYSROOT_BASE MIRI_TARGET=$FOREIGN_TARGET cargo test --release --all-features - | # Test cargo integration (cd test-cargo-miri && MIRI_SYSROOT=$MIRI_SYSROOT_BASE/HOST ./run-test.py) diff --git a/README.md b/README.md index 1b9e5304bd..b6e1c20076 100644 --- a/README.md +++ b/README.md @@ -154,9 +154,9 @@ MIRI_LOG=rustc_mir::interpret=debug,miri::stacked_borrows cargo run tests/run-pa In addition, you can set `MIRI_BACKTRACE=1` to get a backtrace of where an evaluation error was originally created. -### Miri `-Z` flags +### Miri `-Z` flags and environment variables -Several `-Z` flags are relevant for miri: +Several `-Z` flags are relevant for Miri: * `-Zmir-opt-level` controls how many MIR optimizations are performed. miri overrides the default to be `0`; be advised that using any higher level can @@ -168,6 +168,14 @@ Several `-Z` flags are relevant for miri: enforcing the validity invariant, which is enforced by default. This is mostly useful for debugging; it means miri will miss bugs in your program. +Moreover, Miri recognizes some environment variables: + +* `MIRI_SYSROOT` (recognized by `miri`, `cargo miri` and the test suite) + indicates the sysroot to use. +* `MIRI_TARGET` (recognized by the test suite) indicates which target + architecture to test against. `miri` and `cargo miri` accept the `--target` + flag for the same purpose. + ## Contributing and getting help Check out the issues on this GitHub repository for some ideas. There's lots that diff --git a/tests/compiletest.rs b/tests/compiletest.rs index 7187a3caee..a0862d0032 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -34,10 +34,11 @@ fn mk_config(mode: &str) -> compiletest::common::ConfigWithTemp { config.compile_lib_path = rustc_lib_path(); } config.filter = env::args().nth(1); + config.host = get_host(); config } -fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, opt: bool) { +fn compile_fail(path: &str, target: &str, opt: bool) { let opt_str = if opt { " with optimizations" } else { "" }; eprintln!("{}", format!( "## Running compile-fail tests in {} against miri for target {}{}", @@ -47,7 +48,6 @@ fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, opt: bool) ).green().bold()); let mut flags = Vec::new(); - flags.push(format!("--sysroot {}", sysroot.display())); flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs flags.push("--edition 2018".to_owned()); if opt { @@ -60,12 +60,11 @@ fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, opt: bool) let mut config = mk_config("compile-fail"); config.src_base = PathBuf::from(path); config.target = target.to_owned(); - config.host = host.to_owned(); config.target_rustcflags = Some(flags.join(" ")); compiletest::run_tests(&config); } -fn miri_pass(sysroot: &Path, path: &str, target: &str, host: &str, opt: bool) { +fn miri_pass(path: &str, target: &str, opt: bool) { let opt_str = if opt { " with optimizations" } else { "" }; eprintln!("{}", format!( "## Running run-pass tests in {} against miri for target {}{}", @@ -75,7 +74,6 @@ fn miri_pass(sysroot: &Path, path: &str, target: &str, host: &str, opt: bool) { ).green().bold()); let mut flags = Vec::new(); - flags.push(format!("--sysroot {}", sysroot.display())); flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs flags.push("--edition 2018".to_owned()); if opt { @@ -87,57 +85,24 @@ fn miri_pass(sysroot: &Path, path: &str, target: &str, host: &str, opt: bool) { let mut config = mk_config("ui"); config.src_base = PathBuf::from(path); config.target = target.to_owned(); - config.host = host.to_owned(); config.target_rustcflags = Some(flags.join(" ")); compiletest::run_tests(&config); } -fn is_target_dir>(path: P) -> bool { - let mut path = path.into(); - path.push("lib"); - path.metadata().map(|m| m.is_dir()).unwrap_or(false) -} - -fn target_has_std>(path: P) -> bool { - let mut path = path.into(); - path.push("lib"); - std::fs::read_dir(path) - .expect("invalid target") - .map(|entry| entry.unwrap()) - .filter(|entry| entry.file_type().unwrap().is_file()) - .filter_map(|entry| entry.file_name().into_string().ok()) - .any(|file_name| file_name == "libstd.rlib") -} - - -fn for_all_targets(sysroot: &Path, f: F) { - let target_dir = sysroot.join("lib").join("rustlib"); - let mut targets = std::fs::read_dir(target_dir) - .expect("invalid sysroot") - .map(|entry| entry.unwrap()) - .filter(|entry| is_target_dir(entry.path())) - .filter(|entry| target_has_std(entry.path())) - .map(|entry| entry.file_name().into_string().unwrap()) - .peekable(); - - if targets.peek().is_none() { - panic!("No valid targets found"); +/// Make sure the MIRI_SYSROOT env var is set +fn set_sysroot() { + if std::env::var("MIRI_SYSROOT").is_ok() { + // Nothing to do + return; } - - targets.for_each(f); -} - -fn get_sysroot() -> PathBuf { - let sysroot = std::env::var("MIRI_SYSROOT").unwrap_or_else(|_| { - let sysroot = std::process::Command::new("rustc") - .arg("--print") - .arg("sysroot") - .output() - .expect("rustc not found") - .stdout; - String::from_utf8(sysroot).expect("sysroot is not utf8") - }); - PathBuf::from(sysroot.trim()) + let sysroot = std::process::Command::new("rustc") + .arg("--print") + .arg("sysroot") + .output() + .expect("rustc not found") + .stdout; + let sysroot = String::from_utf8(sysroot).expect("sysroot is not utf8"); + std::env::set_var("MIRI_SYSROOT", sysroot.trim()); } fn get_host() -> String { @@ -153,28 +118,20 @@ fn get_host() -> String { version_meta.host } -fn run_pass_miri(opt: bool) { - let sysroot = get_sysroot(); - let host = get_host(); +fn get_target() -> String { + std::env::var("MIRI_TARGET").unwrap_or_else(|_| get_host()) +} - for_all_targets(&sysroot, |target| { - miri_pass(&sysroot, "tests/run-pass", &target, &host, opt); - }); +fn run_pass_miri(opt: bool) { + miri_pass("tests/run-pass", &get_target(), opt); } fn compile_fail_miri(opt: bool) { - let sysroot = get_sysroot(); - let host = get_host(); - - for_all_targets(&sysroot, |target| { - compile_fail(&sysroot, "tests/compile-fail", &target, &host, opt); - }); + compile_fail("tests/compile-fail", &get_target(), opt); } fn test_runner(_tests: &[&()]) { - // We put everything into a single test to avoid the parallelism `cargo test` - // introduces. We still get parallelism within our tests because `compiletest` - // uses `libtest` which runs jobs in parallel. + set_sysroot(); run_pass_miri(false); run_pass_miri(true);