Skip to content

Commit d7d2266

Browse files
committed
Auto merge of #1249 - RalfJung:rustup, r=RalfJung
Cross-test targets We should now be able to run Linux targets on macOS hosts and vice versa. Cc #1198
2 parents 7f47626 + b843de6 commit d7d2266

19 files changed

+78
-53
lines changed

.travis.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ env:
2121
- RUST_BACKTRACE=1
2222

2323
before_script:
24-
# Linux: install extra stuff for cross-compilation
25-
- if [[ "$TRAVIS_OS_NAME" == linux ]]; then sudo apt update && sudo apt install gcc-multilib; fi
2624
# Compute the rust version we use. We do not use "language: rust" to have more control here.
2725
- |
2826
if [[ "$TRAVIS_EVENT_TYPE" == cron ]]; then

CONTRIBUTING.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,19 @@ all the same flags as `rustc` (though the ones only affecting code generation
5252
and linking obviously will have no effect) [and more][miri-flags].
5353

5454
Running the Miri driver requires some fiddling with environment variables, so
55-
the `miri` script helps you do that. For example, you can run the driver on a
56-
particular file by doing
55+
the `miri` script helps you do that. For example, you can (cross-)run the
56+
driver on a particular file by doing
5757

5858
```sh
5959
./miri run tests/run-pass/format.rs
6060
./miri run tests/run-pass/hello.rs --target i686-unknown-linux-gnu
6161
```
6262

63-
and you can run the test suite using:
63+
and you can (cross-)run the test suite using:
6464

6565
```
6666
./miri test
67+
MIRI_TEST_TARGET=i686-unknown-linux-gnu ./miri test
6768
```
6869

6970
`./miri test FILTER` only runs those tests that contain `FILTER` in their
@@ -104,7 +105,8 @@ and then you can use it as if it was installed by `rustup`. Make sure you use
104105
the same toolchain when calling `cargo miri` that you used when installing Miri!
105106

106107
There's a test for the cargo wrapper in the `test-cargo-miri` directory; run
107-
`./run-test.py` in there to execute it.
108+
`./run-test.py` in there to execute it. Like `./miri test`, this respects the
109+
`MIRI_TEST_TARGET` environment variable to execute the test for another target.
108110

109111
## Building Miri with a locally built rustc
110112

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ Now you can run your project in Miri:
7676
The first time you run Miri, it will perform some extra setup and install some
7777
dependencies. It will ask you for confirmation before installing anything.
7878

79+
Miri supports cross-execution: if you want to run the program as if it was a
80+
Linux program, you can do `cargo miri run --target x86_64-unknown-linux-gnu`.
81+
This is particularly useful if you are using Windows, as the Linux target is
82+
much better supported than Windows targets.
83+
7984
You can pass arguments to Miri after the first `--`, and pass arguments to the
8085
interpreted program or test suite after the second `--`. For example, `cargo
8186
miri run -- -Zmiri-disable-validation` runs the program without validation of

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
98803c182b2ba6ef5dccb6bf501958249295eac0
1+
38114ff16e7856f98b2b4be7ab4cd29b38bed59a

src/eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
190190
/// Returns `Some(return_code)` if program executed completed.
191191
/// Returns `None` if an evaluation error occured.
192192
pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) -> Option<i64> {
193-
// FIXME: We always ignore leaks on some platforms where we do not
193+
// FIXME: We always ignore leaks on some OSs where we do not
194194
// correctly implement TLS destructors.
195195
let target_os = tcx.sess.target.target.target_os.as_str();
196196
let ignore_leaks = config.ignore_leaks || target_os == "windows" || target_os == "macos";

src/helpers.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,16 +374,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
374374
}
375375
Ok(())
376376
}
377-
/// Helper function used inside the shims of foreign functions to assert that the target
378-
/// platform is `platform`. It panics showing a message with the `name` of the foreign function
377+
/// Helper function used inside the shims of foreign functions to assert that the target OS
378+
/// is `target_os`. It panics showing a message with the `name` of the foreign function
379379
/// if this is not the case.
380-
fn assert_platform(&self, platform: &str, name: &str) {
380+
fn assert_target_os(&self, target_os: &str, name: &str) {
381381
assert_eq!(
382382
self.eval_context_ref().tcx.sess.target.target.target_os,
383-
platform,
384-
"`{}` is only available on the `{}` platform",
383+
target_os,
384+
"`{}` is only available on the `{}` target OS",
385385
name,
386-
platform,
386+
target_os,
387387
)
388388
}
389389

src/machine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ impl MemoryExtra {
126126
.insert(Symbol::intern("environ"), this.machine.env_vars.environ.unwrap().ptr.assert_ptr().alloc_id)
127127
.unwrap_none();
128128
}
129-
_ => {} // No "extern statics" supported on this platform
129+
_ => {} // No "extern statics" supported on this target
130130
}
131131
Ok(())
132132
}

src/shims/foreign_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
437437
_ => match this.tcx.sess.target.target.target_os.as_str() {
438438
"linux" | "macos" => return posix::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),
439439
"windows" => return windows::EvalContextExt::emulate_foreign_item_by_name(this, link_name, args, dest, ret),
440-
target => throw_unsup_format!("the {} target platform is not supported", target),
440+
target => throw_unsup_format!("the target `{}` is not supported", target),
441441
}
442442
};
443443

src/shims/fs.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ impl FileHandler {
6666

6767
impl<'mir, 'tcx> EvalContextExtPrivate<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
6868
trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
69-
/// Emulate `stat` or `lstat` on the `macos` platform. This function is not intended to be
69+
/// Emulate `stat` or `lstat` on `macos`. This function is not intended to be
7070
/// called directly from `emulate_foreign_item_by_name`, so it does not check if isolation is
71-
/// disabled or if the target platform is the correct one. Please use `macos_stat` or
71+
/// disabled or if the target OS is the correct one. Please use `macos_stat` or
7272
/// `macos_lstat` instead.
7373
fn macos_stat_or_lstat(
7474
&mut self,
@@ -114,7 +114,7 @@ trait EvalContextExtPrivate<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, '
114114
let blksize_t_layout = this.libc_ty_layout("blksize_t")?;
115115
let uint32_t_layout = this.libc_ty_layout("uint32_t")?;
116116

117-
// We need to add 32 bits of padding after `st_rdev` if we are on a 64-bit platform.
117+
// We need to add 32 bits of padding after `st_rdev` if we are on a 64-bit target.
118118
let pad_layout = if this.tcx.sess.target.ptr_width == 64 {
119119
uint32_t_layout
120120
} else {
@@ -258,10 +258,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
258258
let o_wronly = this.eval_libc_i32("O_WRONLY")?;
259259
let o_rdwr = this.eval_libc_i32("O_RDWR")?;
260260
// The first two bits of the flag correspond to the access mode in linux, macOS and
261-
// windows. We need to check that in fact the access mode flags for the current platform
262-
// only use these two bits, otherwise we are in an unsupported platform and should error.
261+
// windows. We need to check that in fact the access mode flags for the current target
262+
// only use these two bits, otherwise we are in an unsupported target and should error.
263263
if (o_rdonly | o_wronly | o_rdwr) & !0b11 != 0 {
264-
throw_unsup_format!("access mode flags on this platform are unsupported");
264+
throw_unsup_format!("access mode flags on this target are unsupported");
265265
}
266266
let mut writable = true;
267267

@@ -574,7 +574,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
574574
buf_op: OpTy<'tcx, Tag>,
575575
) -> InterpResult<'tcx, i32> {
576576
let this = self.eval_context_mut();
577-
this.assert_platform("macos", "stat");
577+
this.assert_target_os("macos", "stat");
578578
this.check_no_isolation("stat")?;
579579
// `stat` always follows symlinks.
580580
this.macos_stat_or_lstat(true, path_op, buf_op)
@@ -587,7 +587,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
587587
buf_op: OpTy<'tcx, Tag>,
588588
) -> InterpResult<'tcx, i32> {
589589
let this = self.eval_context_mut();
590-
this.assert_platform("macos", "lstat");
590+
this.assert_target_os("macos", "lstat");
591591
this.check_no_isolation("lstat")?;
592592
this.macos_stat_or_lstat(false, path_op, buf_op)
593593
}
@@ -599,7 +599,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
599599
) -> InterpResult<'tcx, i32> {
600600
let this = self.eval_context_mut();
601601

602-
this.assert_platform("macos", "fstat");
602+
this.assert_target_os("macos", "fstat");
603603
this.check_no_isolation("fstat")?;
604604

605605
let fd = this.read_scalar(fd_op)?.to_i32()?;
@@ -621,7 +621,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
621621
) -> InterpResult<'tcx, i32> {
622622
let this = self.eval_context_mut();
623623

624-
this.assert_platform("linux", "statx");
624+
this.assert_target_os("linux", "statx");
625625
this.check_no_isolation("statx")?;
626626

627627
let statxbuf_scalar = this.read_scalar(statxbuf_op)?.not_undef()?;
@@ -685,7 +685,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
685685
// the `_mask_op` paramter specifies the file information that the caller requested.
686686
// However `statx` is allowed to return information that was not requested or to not
687687
// return information that was requested. This `mask` represents the information we can
688-
// actually provide in any host platform.
688+
// actually provide for any target.
689689
let mut mask =
690690
this.eval_libc("STATX_TYPE")?.to_u32()? | this.eval_libc("STATX_SIZE")?.to_u32()?;
691691

@@ -880,7 +880,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
880880
) -> InterpResult<'tcx, i32> {
881881
let this = self.eval_context_mut();
882882

883-
this.assert_platform("linux", "readdir64_r");
883+
this.assert_target_os("linux", "readdir64_r");
884884
this.check_no_isolation("readdir64_r")?;
885885

886886
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;
@@ -967,7 +967,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
967967
) -> InterpResult<'tcx, i32> {
968968
let this = self.eval_context_mut();
969969

970-
this.assert_platform("macos", "readdir_r");
970+
this.assert_target_os("macos", "readdir_r");
971971
this.check_no_isolation("readdir_r")?;
972972

973973
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;

src/shims/panic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ pub struct CatchUnwindData<'tcx> {
3232

3333
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
3434
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
35-
/// Check if panicking is supported on this platform, and give a good error otherwise.
35+
/// Check if panicking is supported on this target, and give a good error otherwise.
3636
fn check_panic_supported(&self) -> InterpResult<'tcx> {
3737
match self.eval_context_ref().tcx.sess.target.target.target_os.as_str() {
3838
"linux" | "macos" => Ok(()),
39-
_ => throw_unsup_format!("panicking is not supported on this platform"),
39+
_ => throw_unsup_format!("panicking is not supported on this target"),
4040
}
4141
}
4242

src/shims/time.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
2020
) -> InterpResult<'tcx, i32> {
2121
let this = self.eval_context_mut();
2222

23-
this.assert_platform("linux", "clock_gettime");
23+
this.assert_target_os("linux", "clock_gettime");
2424
this.check_no_isolation("clock_gettime")?;
2525

2626
let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
@@ -58,7 +58,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5858
) -> InterpResult<'tcx, i32> {
5959
let this = self.eval_context_mut();
6060

61-
this.assert_platform("macos", "gettimeofday");
61+
this.assert_target_os("macos", "gettimeofday");
6262
this.check_no_isolation("gettimeofday")?;
6363

6464
// Using tz is obsolete and should always be null
@@ -88,7 +88,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8888
fn mach_absolute_time(&self) -> InterpResult<'tcx, u64> {
8989
let this = self.eval_context_ref();
9090

91-
this.assert_platform("macos", "mach_absolute_time");
91+
this.assert_target_os("macos", "mach_absolute_time");
9292
this.check_no_isolation("mach_absolute_time")?;
9393

9494
// This returns a u64, with time units determined dynamically by `mach_timebase_info`.

test-cargo-miri/run-test.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
import sys, subprocess, os
99

10+
CGREEN = '\33[32m'
11+
CBOLD = '\33[1m'
12+
CEND = '\33[0m'
13+
1014
def fail(msg):
1115
print("\nTEST FAIL: {}".format(msg))
1216
sys.exit(1)
@@ -67,6 +71,9 @@ def test_cargo_miri_test():
6771

6872
os.chdir(os.path.dirname(os.path.realpath(__file__)))
6973

74+
target_str = " for target {}".format(os.environ['MIRI_TEST_TARGET']) if 'MIRI_TEST_TARGET' in os.environ else ""
75+
print(CGREEN + CBOLD + "## Running `cargo miri` tests{}".format(target_str) + CEND)
76+
7077
if not 'MIRI_SYSROOT' in os.environ:
7178
# Make sure we got a working sysroot.
7279
# (If the sysroot gets built later when output is compared, that leads to test failures.)

test-cargo-miri/tests/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fn num_cpus() {
4545

4646
// FIXME: Remove this `cfg` once we fix https://github.com/rust-lang/miri/issues/1059.
4747
// We cfg-gate the `should_panic` attribute and the `panic!` itself, so that the test
48-
// stdout does not depend on the platform.
48+
// stdout does not depend on the target.
4949
#[test]
5050
#[cfg_attr(not(windows), should_panic(expected="Explicit panic"))]
5151
fn do_panic() { // In large, friendly letters :)

tests/compile-fail/panic/windows1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
// Test that panics on Windows give a reasonable error message.
55

6-
// error-pattern: panicking is not supported on this platform
6+
// error-pattern: panicking is not supported on this target
77
fn main() {
88
core::panic!("this is {}", "Windows");
99
}

tests/compile-fail/panic/windows2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
// Test that panics on Windows give a reasonable error message.
55

6-
// error-pattern: panicking is not supported on this platform
6+
// error-pattern: panicking is not supported on this target
77
fn main() {
88
std::panic!("this is Windows");
99
}

tests/compile-fail/panic/windows3.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
// Test that panics on Windows give a reasonable error message.
55

6-
// error-pattern: panicking is not supported on this platform
6+
// error-pattern: panicking is not supported on this target
77
#[allow(unconditional_panic)]
88
fn main() {
99
let _val = 1/0;

tests/run-pass/bitop-beyond-alignment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ fn is_u64_aligned(u: &Tag<u64>) -> bool {
3333

3434
pub fn main() {
3535
let x = mk_rec();
36-
is_u64_aligned(&x.t); // the result of this is non-deterministic (even with a fixed seed, results vary between platforms)
36+
is_u64_aligned(&x.t); // the result of this is non-deterministic (even with a fixed seed, results vary between targets)
3737
}

tests/run-pass/memchr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use core::slice::memchr::{memchr, memrchr};
44

5-
// test fallback implementations on all platforms
5+
// test fallback implementations on all targets
66
fn matches_one() {
77
assert_eq!(Some(0), memchr(b'a', b"a"));
88
}

travis.sh

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
set -euo pipefail
33

44
# Determine configuration
5-
if [ "$TRAVIS_OS_NAME" == linux ]; then
6-
FOREIGN_TARGET=i686-unknown-linux-gnu
7-
fi
85
export CARGO_EXTRA_FLAGS="--all-features"
96
export RUSTC_EXTRA_FLAGS="-D warnings"
107

@@ -16,19 +13,35 @@ echo
1613

1714
# Test
1815
function run_tests {
19-
./miri test --locked
16+
if [ -n "${MIRI_TEST_TARGET+exists}" ]; then
17+
echo "Testing foreign architecture $MIRI_TEST_TARGET"
18+
else
19+
echo "Testing host architecture"
20+
fi
21+
22+
./miri test --locked
23+
if ! [ -n "${MIRI_TEST_TARGET+exists}" ]; then
24+
# Only for host architecture: tests with MIR optimizations
2025
MIRI_TEST_FLAGS="-Z mir-opt-level=3" ./miri test
21-
# "miri test" has built the sysroot for us, now this should pass without
22-
# any interactive questions.
23-
test-cargo-miri/run-test.py
26+
fi
27+
# "miri test" has built the sysroot for us, now this should pass without
28+
# any interactive questions.
29+
test-cargo-miri/run-test.py
30+
31+
echo
2432
}
2533

26-
echo "Test host architecture"
34+
# host
2735
run_tests
28-
echo
36+
# cross-test 32bit Linux from everywhere
37+
MIRI_TEST_TARGET=i686-unknown-linux-gnu run_tests
2938

30-
if [ -n "${FOREIGN_TARGET+exists}" ]; then
31-
echo "Test foreign architecture ($FOREIGN_TARGET)"
32-
MIRI_TEST_TARGET="$FOREIGN_TARGET" run_tests
33-
echo
39+
if [ "$TRAVIS_OS_NAME" == linux ]; then
40+
# cross-test 64bit macOS from Linux
41+
MIRI_TEST_TARGET=x86_64-apple-darwin run_tests
42+
# cross-test 32bit Windows from Linux
43+
MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
44+
elif [ "$TRAVIS_OS_NAME" == osx ]; then
45+
# cross-test 64bit Windows from macOS
46+
MIRI_TEST_TARGET=x86_64-pc-windows-msvc run_tests
3447
fi

0 commit comments

Comments
 (0)