]> git.lizzy.rs Git - rust.git/blob - miri
f12a49afe474008291031b65d11e86e3457cd3d0
[rust.git] / miri
1 #!/bin/sh
2 ## Usage
3 #
4 # COMMANDS
5 #
6 # ./miri install <flags>:
7 # Installs the miri driver and cargo-miri. <flags> are passed to `cargo
8 # install`.  Sets up the rpath such that the installed binary should work in any
9 # working directory.
10 #
11 # ./miri build <flags>:
12 # Just build miri.  <flags> are passed to `cargo build`.
13 #
14 # ./miri test <flags>:
15 # Build miri, set up a sysroot and then run the test suite. <flags> are passed
16 # to the final `cargo test` invocation.
17 #
18 # ./miri run <flags>:
19 # Build miri, set up a sysroot and then run the driver with the given <flags>.
20 #
21 # All commands also exist in a "-debug" variant (e.g. "./miri run-debug
22 # <flags>") which uses debug builds instead of release builds, for faster build
23 # times and slower execution times.
24 #
25 # ENVIRONMENT VARIABLES
26 #
27 # MIRI_SYSROOT:
28 # If already set, the "sysroot setup" step is skipped.
29 #
30 # CARGO_EXTRA_FLAGS:
31 # Pass extra flags to all cargo invocations.
32
33 ## Preparation
34 set -e
35 # I'd love to use `jq` for parsing the JSON properly, but macOS is totally underequipped for this kind of work.
36 TARGET=$(rustc --print target-spec-json -Z unstable-options | grep llvm-target | cut -d '"' -f 4)
37 SYSROOT=$(rustc --print sysroot)
38 # We set the rpath so that Miri finds the private rustc libraries it needs.
39 # We enable debug-assertions to get tracing.
40 # We enable line-only debuginfo for backtraces.
41 export RUSTFLAGS="-C link-args=-Wl,-rpath,$SYSROOT/lib/rustlib/$TARGET/lib -C debug-assertions -C debuginfo=1"
42
43 ## Helper functions
44
45 # Build a sysroot and set MIRI_SYSROOT to use it.  Arguments are passed to `cargo miri setup`.
46 build_sysroot() {
47     # Build once, for the user to see.
48     cargo run $CARGO_BUILD_FLAGS --bin cargo-miri -- miri setup "$@"
49     # Call again, to just set env var.
50     eval $(cargo run $CARGO_BUILD_FLAGS -q --bin cargo-miri -- miri setup --env "$@")
51     export MIRI_SYSROOT
52 }
53
54 # Prepare and set MIRI_SYSROOT.  Respects `MIRI_TEST_TARGET` and takes into account
55 # locally built vs. distributed rustc.
56 find_sysroot() {
57     # Get ourselves a sysroot
58     if [ -n "$MIRI_SYSROOT" ]; then
59         # Sysroot already set, use that.
60         true
61     elif echo "$SYSROOT" | egrep -q 'build/[^/]+/stage'; then
62         # A local rustc build.
63         if [ -n "$MIRI_TEST_TARGET" ]; then
64             # Foreign targets still need a build.  Use the rustc sources.
65             export XARGO_RUST_SRC="$SYSROOT/../../../src"
66             build_sysroot --target "$MIRI_TEST_TARGET"
67         else
68             # Assume we have a proper host libstd in $SYSROOT.
69             true
70         fi
71     else
72         # A normal toolchain.  We have to build a sysroot either way.
73         if [ -n "$MIRI_TEST_TARGET" ]; then
74             build_sysroot --target "$MIRI_TEST_TARGET"
75         else
76             build_sysroot
77         fi
78     fi
79 }
80
81 ## Main
82
83 # Determine command.
84 COMMAND="$1"
85 shift
86
87 # Determine flags passed to all cargo invocations.
88 case "$COMMAND" in
89 *-debug)
90     CARGO_INSTALL_FLAGS="--debug $CARGO_EXTRA_FLAGS"
91     CARGO_BUILD_FLAGS="$CARGO_EXTRA_FLAGS"
92     ;;
93 *)
94     CARGO_INSTALL_FLAGS="$CARGO_EXTRA_FLAGS"
95     CARGO_BUILD_FLAGS="--release $CARGO_EXTRA_FLAGS"
96     ;;
97 esac
98
99 # Run command.
100 case "$COMMAND" in
101 install|install-debug)
102     # "--locked" to respect the Cargo.lock file if it exists,
103     # "--offline" to avoid querying the registry (for yanked packages).
104     exec cargo install --path "$(dirname "$0")" --force --locked --offline "$@"
105     ;;
106 build|build-debug)
107     # Build, and let caller control flags.
108     exec cargo build $CARGO_BUILD_FLAGS "$@"
109     ;;
110 test|test-debug)
111     # First build and get a sysroot.
112     cargo build $CARGO_BUILD_FLAGS
113     find_sysroot
114     # Then test, and let caller control flags.
115     exec cargo test $CARGO_BUILD_FLAGS "$@"
116     ;;
117 run|run-debug)
118     # Scan for "--target" to set the "MIRI_TEST_TARGET" env var so
119     # that we set the MIRI_SYSROOT up the right way.
120     if [ -z "$MIRI_TEST_TARGET" ]; then
121         for ARG in "$@"; do
122             if [ "$LAST_ARG" = "--target" ]; then
123                 # Found it!
124                 export MIRI_TEST_TARGET="$ARG"
125                 break
126             fi
127             LAST_ARG="$ARG"
128         done
129     fi
130     # First build and get a sysroot.
131     cargo build $CARGO_BUILD_FLAGS
132     find_sysroot
133     # Then run the actual command.
134     exec cargo run $CARGO_BUILD_FLAGS "$@"
135     ;;
136 esac