From: Ralf Jung Date: Fri, 19 Apr 2019 17:53:42 +0000 (+0200) Subject: rewirte development part of README X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=bf6b7aa550125aa6520e261da4ddc930239fa007;p=rust.git rewirte development part of README --- diff --git a/README.md b/README.md index 716c26c03a7..eb86d5b2ee3 100644 --- a/README.md +++ b/README.md @@ -113,63 +113,56 @@ find useful. ### Using a nightly rustc Miri heavily relies on internal rustc interfaces to execute MIR. Still, some -things (like adding support for a new intrinsic) can be done by working just on -the Miri side. +things (like adding support for a new intrinsic or a shim for an external +function being called) can be done by working just on the Miri side. -To prepare, make sure you are using a nightly Rust compiler. The most -convenient way is to install Miri using cargo, then you can easily run it on -other projects: - -```sh -rustup component remove miri # avoid having Miri installed twice -cargo +nightly install --path "$DIR" --force -cargo +nightly miri setup -``` - -(We are giving `+nightly` explicitly here all the time because it is important -that all of these commands get executed with the same toolchain.) +To prepare, make sure you are using a nightly Rust compiler. Then you should be +able to just `cargo build` Miri. In case this fails, your nightly might be incompatible with Miri master. The `rust-version` file contains the commit hash of rustc that Miri is currently tested against; you can use that to find a nightly that works or you might have to wait for the next nightly to get released. -If you want to use a different libstd (not the one that comes with the -nightly), you can do that by running +### Testing the Miri driver +[testing-miri]: #testing-the-miri-driver -```sh -XARGO_RUST_SRC=~/src/rust/rustc/src/ cargo +nightly miri setup +The Miri driver in the `miri` binary is the "heart" of Miri: it is basically a +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 ``` -Either way, you can now do `cargo +nightly miri run` to run Miri with your -local changes on whatever project you are debugging. +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. -`cargo miri setup` should end in printing the directory where the libstd was -built. For the next step to work, set that as your `MIRI_SYSROOT` environment -variable: +Now you can run the driver directly using ```sh -export MIRI_SYSROOT=~/.cache/miri/HOST # or whatever the previous command said +MIRI_SYSROOT=~/.cache/miri/HOST cargo run tests/run-pass/format.rs # or whatever test you like ``` -### Testing Miri +and you can run the test suite using -Instead of running an entire project using `cargo miri`, you can also use the -Miri "driver" directly to run just a single file. That can be easier during -debugging. - -```sh -cargo run tests/run-pass/format.rs # or whatever test you like ``` +cargo test +``` + +We recommend adding the `--release` flag to make tests run faster. -You can also run the test suite with `cargo test --release`. `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). We recommend using `--release` to make test running take -less time. +`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). -Now you are set up! You can write a failing test case, and tweak miri until it -fails no more. You can get a trace of which MIR statements are being executed by setting the `MIRI_LOG` environment variable. For example: @@ -177,26 +170,43 @@ You can get a trace of which MIR statements are being executed by setting the MIRI_LOG=info cargo 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 the `rustc::mir::interpret` and `rustc_mir::interpret` modules in rustc. You -can also do more targeted configuration, e.g. to debug the stacked borrows -implementation: +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 ``` In addition, you can set `MIRI_BACKTRACE=1` to get a backtrace of where an -evaluation error was originally created. +evaluation error was originally raised. + +### Testing `cargo miri` + +Working with the driver directly gives you full control, but you also lose all +the convenience provided by cargo. Once your test case depends on a crate, it +is probably easier to test it with the cargo wrapper. You can install your +development version of Miri using + +``` +cargo install --path . --force +``` + +and then you can use it as if it was installed by `rustup`. Make sure you use +the same toolchain when calling `cargo miri` that you used when installing Miri! +There's a test for the cargo wrapper in the `test-cargo-miri` directory; run +`./run-test.py` in there to execute it. ### Using a locally built rustc -Since the heart of Miri (the main interpreter engine) lives in rustc, working on -Miri will often require using a locally built rustc. The bug you want to fix -may actually be on the rustc side, or you just need to get more detailed trace -of the execution than what is possible with release builds -- in both cases, you -should develop miri against a rustc you compiled yourself, with debug assertions -(and hence tracing) enabled. +A big part of the Miri driver lives in rustc, so working on Miri will sometimes +require using a locally built rustc. The bug you want to fix may actually be on +the rustc side, or you just need to get more detailed trace of the execution +than what is possible with release builds -- in both cases, you should develop +miri against a rustc you compiled yourself, with debug assertions (and hence +tracing) enabled. The setup for a local rustc works as follows: ```sh @@ -216,18 +226,21 @@ rustup override set custom ``` With this, you should now have a working development setup! See -["Testing Miri"](#testing-miri) above for how to proceed. +[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 does not actually run without some environment variables. -But you can contort cargo into calling `cargo miri` the right way for you: +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 -# in some other project's directory, to run `cargo miri test`: -MIRI_SYSROOT=$(rustc +custom --print sysroot) cargo +custom run --manifest-path /path/to/miri/Cargo.toml --bin cargo-miri --release -- miri test +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-flags]: #miri--z-flags-and-environment-variables Several `-Z` flags are relevant for Miri: