Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

do not auto-detect the targets in the sysroot, instead specify target manually through env var #570

Merged
merged 1 commit into from
Dec 12, 2018
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
14 changes: 8 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
89 changes: 23 additions & 66 deletions tests/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {}{}",
Expand All @@ -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 {
Expand All @@ -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 {}{}",
Expand All @@ -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 {
Expand All @@ -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<P: Into<PathBuf>>(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<P: Into<PathBuf>>(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<F: FnMut(String)>(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 {
Expand All @@ -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| {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with this missing, CI isn't testing all the targets anymore that it was testing before

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is testing exactly the same targets as before: .travis-ci.yml now calls cargo test multiple times to do that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. I misread what's happening, we're just testing one target other than the host. I was looking for some kind of loop

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);
Expand Down