commit
3c930e48e1
@ -16,7 +16,6 @@ env:
|
|||||||
global:
|
global:
|
||||||
- RUST_TEST_NOCAPTURE=1
|
- RUST_TEST_NOCAPTURE=1
|
||||||
- RUST_BACKTRACE=1
|
- RUST_BACKTRACE=1
|
||||||
- RUSTFLAGS="-C debug-assertions"
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
# Linux: install extra stuff for cross-compilation
|
# Linux: install extra stuff for cross-compilation
|
||||||
|
@ -40,12 +40,15 @@ rustc_version = { version = "0.2.3", optional = true }
|
|||||||
env_logger = "0.6"
|
env_logger = "0.6"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
shell-escape = "0.1.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.
|
# 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`
|
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
|
||||||
# for more information.
|
# for more information.
|
||||||
rustc-workspace-hack = "1.0.0"
|
rustc-workspace-hack = "1.0.0"
|
||||||
hex = "0.3.2"
|
# Depend on num-traits with default features to avoid having to rebuild
|
||||||
rand = "0.6"
|
# between "cargo build" and "cargo intall".
|
||||||
|
num-traits = "*"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
vergen = "3"
|
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
|
all the same flags as `rustc` (though the ones only affecting code generation
|
||||||
and linking obviously will have no effect) [and more][miri-flags].
|
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
|
Running the Miri driver requires some fiddling with environment variables, so
|
||||||
set to an appropriate sysroot. You can generate such a sysroot with the
|
the `miri` script helps you do that. For example, you can run the driver on a
|
||||||
following incantation:
|
particular file by doing
|
||||||
|
|
||||||
```
|
|
||||||
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
|
|
||||||
|
|
||||||
```sh
|
```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.
|
`./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
|
||||||
`cargo test --release FILTER` only runs those tests that contain `FILTER` in
|
compile-fail tests).
|
||||||
their filename (including the base directory, e.g. `cargo test --release fail`
|
|
||||||
will run all compile-fail tests).
|
|
||||||
|
|
||||||
You can get a trace of which MIR statements are being executed by setting the
|
You can get a trace of which MIR statements are being executed by setting the
|
||||||
`MIRI_LOG` environment variable. For example:
|
`MIRI_LOG` environment variable. For example:
|
||||||
|
|
||||||
```sh
|
```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
|
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:
|
stacked borrows implementation:
|
||||||
|
|
||||||
```sh
|
```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
|
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
|
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
|
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
|
With this, you should now have a working development setup! See
|
||||||
[above][testing-miri] for how to proceed working with the Miri driver. Notice
|
[above][testing-miri] for how to proceed working with the Miri driver.
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
### Miri `-Z` flags and environment variables
|
### Miri `-Z` flags and environment variables
|
||||||
[miri-flags]: #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();
|
File::create(dir.join("lib.rs")).unwrap();
|
||||||
// Run xargo.
|
// Run xargo.
|
||||||
let target = get_arg_flag_value("--target");
|
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");
|
let mut command = Command::new("xargo");
|
||||||
command.arg("build").arg("-q")
|
command.arg("build").arg("-q")
|
||||||
.current_dir(&dir)
|
.current_dir(&dir)
|
||||||
@ -265,7 +266,9 @@ path = "lib.rs"
|
|||||||
};
|
};
|
||||||
let sysroot = if is_host { dir.join("HOST") } else { PathBuf::from(dir) };
|
let sysroot = if is_host { dir.join("HOST") } else { PathBuf::from(dir) };
|
||||||
std::env::set_var("MIRI_SYSROOT", &sysroot);
|
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());
|
println!("A libstd for Miri is now available in `{}`", sysroot.display());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
19
travis.sh
19
travis.sh
@ -3,36 +3,29 @@ set -euo pipefail
|
|||||||
|
|
||||||
# Determine configuration
|
# Determine configuration
|
||||||
if [ "$TRAVIS_OS_NAME" == osx ]; then
|
if [ "$TRAVIS_OS_NAME" == osx ]; then
|
||||||
MIRI_SYSROOT_BASE=~/Library/Caches/miri.miri.miri/
|
|
||||||
FOREIGN_TARGET=i686-apple-darwin
|
FOREIGN_TARGET=i686-apple-darwin
|
||||||
else
|
else
|
||||||
MIRI_SYSROOT_BASE=~/.cache/miri/
|
|
||||||
FOREIGN_TARGET=i686-unknown-linux-gnu
|
FOREIGN_TARGET=i686-unknown-linux-gnu
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Prepare
|
# Prepare
|
||||||
echo "Build and install miri"
|
echo "Build and install miri"
|
||||||
cargo build --release --all-features --all-targets
|
./miri build --all-features --all-targets
|
||||||
cargo install --all-features --force --path .
|
./miri install
|
||||||
echo
|
|
||||||
|
|
||||||
echo "Get ourselves a MIR-full libstd for the host and a foreign architecture"
|
|
||||||
cargo miri setup
|
|
||||||
cargo miri setup --target "$FOREIGN_TARGET"
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Test
|
# Test
|
||||||
function run_tests {
|
function run_tests {
|
||||||
cargo test --release --all-features
|
./miri test
|
||||||
|
# "miri test" has built the sysroot for us, now this should pass without
|
||||||
|
# any interactive questions.
|
||||||
test-cargo-miri/run-test.py
|
test-cargo-miri/run-test.py
|
||||||
}
|
}
|
||||||
|
|
||||||
echo "Test host architecture"
|
echo "Test host architecture"
|
||||||
export MIRI_SYSROOT="$MIRI_SYSROOT_BASE"/HOST
|
|
||||||
run_tests
|
run_tests
|
||||||
echo
|
echo
|
||||||
|
|
||||||
echo "Test foreign architecture ($FOREIGN_TARGET)"
|
echo "Test foreign architecture ($FOREIGN_TARGET)"
|
||||||
export MIRI_SYSROOT="$MIRI_SYSROOT_BASE" MIRI_TEST_TARGET="$FOREIGN_TARGET"
|
MIRI_TEST_TARGET="$FOREIGN_TARGET" run_tests
|
||||||
run_tests
|
|
||||||
echo
|
echo
|
||||||
|
Loading…
x
Reference in New Issue
Block a user