commit
3c930e48e1
@ -16,7 +16,6 @@ env:
|
||||
global:
|
||||
- RUST_TEST_NOCAPTURE=1
|
||||
- RUST_BACKTRACE=1
|
||||
- RUSTFLAGS="-C debug-assertions"
|
||||
|
||||
before_script:
|
||||
# Linux: install extra stuff for cross-compilation
|
||||
|
@ -40,12 +40,15 @@ rustc_version = { version = "0.2.3", optional = true }
|
||||
env_logger = "0.6"
|
||||
log = "0.4"
|
||||
shell-escape = "0.1.4"
|
||||
hex = "0.3.2"
|
||||
rand = "0.6"
|
||||
# A noop dependency that changes in the Rust repository, it's a bit of a hack.
|
||||
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
|
||||
# for more information.
|
||||
rustc-workspace-hack = "1.0.0"
|
||||
hex = "0.3.2"
|
||||
rand = "0.6"
|
||||
# Depend on num-traits with default features to avoid having to rebuild
|
||||
# between "cargo build" and "cargo intall".
|
||||
num-traits = "*"
|
||||
|
||||
[build-dependencies]
|
||||
vergen = "3"
|
||||
|
51
README.md
51
README.md
@ -141,42 +141,30 @@ version of `rustc` that, instead of compiling your code, runs it. It accepts
|
||||
all the same flags as `rustc` (though the ones only affecting code generation
|
||||
and linking obviously will have no effect) [and more][miri-flags].
|
||||
|
||||
To run the Miri driver, you need to have the `MIRI_SYSROOT` environment variable
|
||||
set to an appropriate sysroot. You can generate such a sysroot with the
|
||||
following incantation:
|
||||
|
||||
```
|
||||
cargo run --bin cargo-miri -- miri setup
|
||||
```
|
||||
|
||||
This basically runs the `cargo-miri` binary (which backs the `cargo miri`
|
||||
subcommand) with `cargo`, and asks it to `setup`. It should in the end print
|
||||
the directory where the libstd was built. In the following, we will assume it
|
||||
is `~/.cache/miri/HOST`; you may have to adjust that if you are not using Linux.
|
||||
|
||||
Now you can run the driver directly using
|
||||
Running the Miri driver requires some fiddling with environment variables, so
|
||||
the `miri` script helps you do that. For example, you can run the driver on a
|
||||
particular file by doing
|
||||
|
||||
```sh
|
||||
MIRI_SYSROOT=~/.cache/miri/HOST cargo run tests/run-pass/format.rs # or whatever test you like
|
||||
./miri run tests/run-pass/format.rs
|
||||
./miri run tests/run-pass/hello.rs --target i686-unknown-linux-gnu
|
||||
```
|
||||
|
||||
and you can run the test suite using
|
||||
and you can run the test suite using:
|
||||
|
||||
```
|
||||
cargo test
|
||||
./miri test
|
||||
```
|
||||
|
||||
We recommend adding the `--release` flag to make tests run faster.
|
||||
|
||||
`cargo test --release FILTER` only runs those tests that contain `FILTER` in
|
||||
their filename (including the base directory, e.g. `cargo test --release fail`
|
||||
will run all compile-fail tests).
|
||||
`./miri test FILTER` only runs those tests that contain `FILTER` in their
|
||||
filename (including the base directory, e.g. `./miri test fail` will run all
|
||||
compile-fail tests).
|
||||
|
||||
You can get a trace of which MIR statements are being executed by setting the
|
||||
`MIRI_LOG` environment variable. For example:
|
||||
|
||||
```sh
|
||||
MIRI_LOG=info cargo run tests/run-pass/vecs.rs
|
||||
MIRI_LOG=info ./miri run tests/run-pass/vecs.rs
|
||||
```
|
||||
|
||||
Setting `MIRI_LOG` like this will configure logging for Miri itself as well as
|
||||
@ -185,7 +173,7 @@ can also do more targeted configuration, e.g. the following helps debug the
|
||||
stacked borrows implementation:
|
||||
|
||||
```sh
|
||||
MIRI_LOG=rustc_mir::interpret=info,miri::stacked_borrows cargo run tests/run-pass/vecs.rs
|
||||
MIRI_LOG=rustc_mir::interpret=info,miri::stacked_borrows ./miri run tests/run-pass/vecs.rs
|
||||
```
|
||||
|
||||
In addition, you can set `MIRI_BACKTRACE=1` to get a backtrace of where an
|
||||
@ -199,7 +187,7 @@ is probably easier to test it with the cargo wrapper. You can install your
|
||||
development version of Miri using
|
||||
|
||||
```
|
||||
cargo install --path . --force
|
||||
./miri install
|
||||
```
|
||||
|
||||
and then you can use it as if it was installed by `rustup`. Make sure you use
|
||||
@ -235,18 +223,7 @@ rustup override set custom
|
||||
```
|
||||
|
||||
With this, you should now have a working development setup! See
|
||||
[above][testing-miri] for how to proceed working with the Miri driver. Notice
|
||||
that rustc's sysroot is already built for Miri in this case, so you can set
|
||||
`MIRI_SYSROOT=$(rustc --print sysroot)`.
|
||||
|
||||
Running `cargo miri` in this setup is a bit more complicated, because the Miri
|
||||
binary you just created needs help to find the libraries it links against. On
|
||||
Linux, you can set the rpath to make this "just work":
|
||||
|
||||
```sh
|
||||
export RUSTFLAGS="-C link-args=-Wl,-rpath,$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/lib"
|
||||
cargo install --path . --force
|
||||
```
|
||||
[above][testing-miri] for how to proceed working with the Miri driver.
|
||||
|
||||
### Miri `-Z` flags and environment variables
|
||||
[miri-flags]: #miri--z-flags-and-environment-variables
|
||||
|
83
miri
Executable file
83
miri
Executable file
@ -0,0 +1,83 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
# I'd love to use `jq` for parsing the JSON properly, but macOS is totally underequipped for this kind of work.
|
||||
TARGET=$(rustc --print target-spec-json -Z unstable-options | grep llvm-target | cut -d '"' -f 4)
|
||||
SYSROOT=$(rustc --print sysroot)
|
||||
# We set the rpath so that Miri finds the private rustc libraries it needs.
|
||||
# We enable debug-assertions to get tracing.
|
||||
# We enable line-only debuginfo for backtraces.
|
||||
export RUSTFLAGS="-C link-args=-Wl,-rpath,$SYSROOT/lib/rustlib/$TARGET/lib -C debug-assertions -C debuginfo=1"
|
||||
|
||||
## Helper functions
|
||||
|
||||
# Build a sysroot and set MIRI_SYSROOT to use it. Arguments are passed to `cargo miri setup`.
|
||||
build_sysroot() {
|
||||
# Build once, for the user to see.
|
||||
cargo run --release --bin cargo-miri -- miri setup "$@"
|
||||
# Call again, to just set env var.
|
||||
eval $(cargo run --release -q --bin cargo-miri -- miri setup --env "$@")
|
||||
export MIRI_SYSROOT
|
||||
}
|
||||
|
||||
# Prepare and set MIRI_SYSROOT. Respects `MIRI_TEST_TARGET` and takes into account
|
||||
# locally built vs. distributed rustc.
|
||||
find_sysroot() {
|
||||
# Get ourselves a sysroot
|
||||
if [ -n "$MIRI_SYSROOT" ]; then
|
||||
# Sysroot already set, use that.
|
||||
true
|
||||
elif echo "$SYSROOT" | egrep -q 'build/[^/]+/stage'; then
|
||||
# A local rustc build.
|
||||
if [ -n "$MIRI_TEST_TARGET" ]; then
|
||||
# Foreign targets still need a build. Use the rustc sources.
|
||||
export XARGO_RUST_SRC="$SYSROOT/../../../src"
|
||||
build_sysroot --target "$MIRI_TEST_TARGET"
|
||||
else
|
||||
# Assume we have a proper host libstd in $SYSROOT.
|
||||
true
|
||||
fi
|
||||
else
|
||||
# A normal toolchain. We have to build a sysroot either way.
|
||||
if [ -n "$MIRI_TEST_TARGET" ]; then
|
||||
build_sysroot --target "$MIRI_TEST_TARGET"
|
||||
else
|
||||
build_sysroot
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
## Main
|
||||
|
||||
COMMAND="$1"
|
||||
shift
|
||||
|
||||
case "$COMMAND" in
|
||||
install)
|
||||
# "--locked" to respect the Cargo.lock file if it exists,
|
||||
# "--offline" to avoid querying the registry (for yanked packages).
|
||||
exec cargo "$COMMAND" --path "$(dirname "$0")" --force --locked --offline "$@"
|
||||
;;
|
||||
build)
|
||||
# Build, and let caller control flags.
|
||||
exec cargo "$COMMAND" --release "$@"
|
||||
;;
|
||||
test|run)
|
||||
# In "run" mode, scan for "--target" to set the "MIRI_TEST_TARGET" env var so
|
||||
# that we set the MIRI_SYSROOT up the right way.
|
||||
if [ "$COMMAND" = "run" ] && [ -z "$MIRI_TEST_TARGET" ]; then
|
||||
for ARG in "$@"; do
|
||||
if [ "$LAST_ARG" = "--target" ]; then
|
||||
# Found it!
|
||||
export MIRI_TEST_TARGET="$ARG"
|
||||
break
|
||||
fi
|
||||
LAST_ARG="$ARG"
|
||||
done
|
||||
fi
|
||||
# First build and get a sysroot.
|
||||
cargo build --release
|
||||
find_sysroot
|
||||
# Then run the actual command.
|
||||
exec cargo "$COMMAND" --release "$@"
|
||||
;;
|
||||
esac
|
@ -243,6 +243,7 @@ path = "lib.rs"
|
||||
File::create(dir.join("lib.rs")).unwrap();
|
||||
// Run xargo.
|
||||
let target = get_arg_flag_value("--target");
|
||||
let print_env = !ask_user && has_arg_flag("--env"); // whether we just print the necessary environment variable
|
||||
let mut command = Command::new("xargo");
|
||||
command.arg("build").arg("-q")
|
||||
.current_dir(&dir)
|
||||
@ -265,7 +266,9 @@ path = "lib.rs"
|
||||
};
|
||||
let sysroot = if is_host { dir.join("HOST") } else { PathBuf::from(dir) };
|
||||
std::env::set_var("MIRI_SYSROOT", &sysroot);
|
||||
if !ask_user {
|
||||
if print_env {
|
||||
println!("MIRI_SYSROOT={}", sysroot.display());
|
||||
} else if !ask_user {
|
||||
println!("A libstd for Miri is now available in `{}`", sysroot.display());
|
||||
}
|
||||
}
|
||||
|
21
travis.sh
21
travis.sh
@ -3,36 +3,29 @@ set -euo pipefail
|
||||
|
||||
# Determine configuration
|
||||
if [ "$TRAVIS_OS_NAME" == osx ]; then
|
||||
MIRI_SYSROOT_BASE=~/Library/Caches/miri.miri.miri/
|
||||
FOREIGN_TARGET=i686-apple-darwin
|
||||
else
|
||||
MIRI_SYSROOT_BASE=~/.cache/miri/
|
||||
FOREIGN_TARGET=i686-unknown-linux-gnu
|
||||
fi
|
||||
|
||||
# Prepare
|
||||
echo "Build and install miri"
|
||||
cargo build --release --all-features --all-targets
|
||||
cargo install --all-features --force --path .
|
||||
echo
|
||||
|
||||
echo "Get ourselves a MIR-full libstd for the host and a foreign architecture"
|
||||
cargo miri setup
|
||||
cargo miri setup --target "$FOREIGN_TARGET"
|
||||
./miri build --all-features --all-targets
|
||||
./miri install
|
||||
echo
|
||||
|
||||
# Test
|
||||
function run_tests {
|
||||
cargo test --release --all-features
|
||||
test-cargo-miri/run-test.py
|
||||
./miri test
|
||||
# "miri test" has built the sysroot for us, now this should pass without
|
||||
# any interactive questions.
|
||||
test-cargo-miri/run-test.py
|
||||
}
|
||||
|
||||
echo "Test host architecture"
|
||||
export MIRI_SYSROOT="$MIRI_SYSROOT_BASE"/HOST
|
||||
run_tests
|
||||
echo
|
||||
|
||||
echo "Test foreign architecture ($FOREIGN_TARGET)"
|
||||
export MIRI_SYSROOT="$MIRI_SYSROOT_BASE" MIRI_TEST_TARGET="$FOREIGN_TARGET"
|
||||
run_tests
|
||||
MIRI_TEST_TARGET="$FOREIGN_TARGET" run_tests
|
||||
echo
|
||||
|
Loading…
x
Reference in New Issue
Block a user