Skip to content

Commit 32dafcb

Browse files
committed
Auto merge of #127926 - Oneirical:classical-orctestra, r=<try>
Migrate `foreign-double-unwind`, `issue-36710` and `foreign-exceptions` `run-make` tests to rmake Part of #121876 and the associated [Google Summer of Code project](https://blog.rust-lang.org/2024/05/01/gsoc-2024-selected-projects.html). ~~This is expected to fail CI, I am getting a weird `core dumped` error on `foreign-double-unwind` locally. Posting this to start a discussion.~~ EDIT: I got it, `foreign_double_unwind` is *supposed* to fail in the execution stage, but this wasn't obvious, because the original test was just piping the stdout to `CGREP` (which silently ignores errors). try-job: aarch64-apple try-job: armhf-gnu try-job: test-various try-job: x86_64-msvc try-job: x86_64-gnu-llvm-18 try-job: i686-msvc try-job: dist-i586-gnu-i586-i686-musl
2 parents 71b2116 + 0e9fa9b commit 32dafcb

File tree

12 files changed

+149
-48
lines changed

12 files changed

+149
-48
lines changed

src/tools/run-make-support/src/external_deps/c_build.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ use std::path::PathBuf;
22

33
use super::cygpath::get_windows_path;
44
use crate::artifact_names::{dynamic_lib_name, static_lib_name};
5-
use crate::external_deps::cc::cc;
5+
use crate::external_deps::cc::{cc, cxx};
66
use crate::external_deps::llvm::llvm_ar;
77
use crate::path_helpers::path;
88
use crate::targets::{is_darwin, is_msvc, is_windows};
99

1010
// FIXME(Oneirical): These native build functions should take a Path-based generic.
1111

1212
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
13+
/// Built from a C file.
1314
#[track_caller]
1415
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
1516
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
@@ -58,3 +59,24 @@ pub fn build_native_dynamic_lib(lib_name: &str) -> PathBuf {
5859
}
5960
path(lib_path)
6061
}
62+
63+
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
64+
/// Built from a C++ file.
65+
#[track_caller]
66+
pub fn build_native_static_lib_cxx(lib_name: &str) -> PathBuf {
67+
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
68+
let src = format!("{lib_name}.cpp");
69+
let lib_path = static_lib_name(lib_name);
70+
if is_msvc() {
71+
cxx().arg("-EHs").arg("-c").out_exe(&obj_file).input(src).run();
72+
} else {
73+
cxx().arg("-c").out_exe(&obj_file).input(src).run();
74+
};
75+
let obj_file = if is_msvc() {
76+
PathBuf::from(format!("{lib_name}.obj"))
77+
} else {
78+
PathBuf::from(format!("{lib_name}.o"))
79+
};
80+
llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
81+
path(lib_path)
82+
}

src/tools/run-make-support/src/external_deps/rustc.rs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::command::Command;
55
use crate::env::env_var;
66
use crate::path_helpers::cwd;
77
use crate::util::set_host_rpath;
8+
use crate::{is_darwin, is_msvc, is_windows, uname};
89

910
/// Construct a new `rustc` invocation. This will automatically set the library
1011
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
@@ -314,4 +315,62 @@ impl Rustc {
314315
self.cmd.arg(format!("-Clinker-flavor={linker_flavor}"));
315316
self
316317
}
318+
319+
/// `EXTRARSCXXFLAGS`
320+
pub fn extra_rs_cxx_flags(&mut self) -> &mut Self {
321+
// Adapted from tools.mk (trimmed):
322+
//
323+
// ```makefile
324+
// ifdef IS_WINDOWS
325+
// ifdef IS_MSVC
326+
// else
327+
// EXTRARSCXXFLAGS := -lstatic:-bundle=stdc++
328+
// endif
329+
// else
330+
// ifeq ($(UNAME),Darwin)
331+
// EXTRARSCXXFLAGS := -lc++
332+
// else
333+
// ifeq ($(UNAME),FreeBSD)
334+
// else
335+
// ifeq ($(UNAME),SunOS)
336+
// else
337+
// ifeq ($(UNAME),OpenBSD)
338+
// else
339+
// EXTRARSCXXFLAGS := -lstdc++
340+
// endif
341+
// endif
342+
// endif
343+
// endif
344+
// endif
345+
// ```
346+
let flag = if is_windows() {
347+
// So this is a bit hacky: we can't use the DLL version of libstdc++ because
348+
// it pulls in the DLL version of libgcc, which means that we end up with 2
349+
// instances of the DW2 unwinding implementation. This is a problem on
350+
// i686-pc-windows-gnu because each module (DLL/EXE) needs to register its
351+
// unwind information with the unwinding implementation, and libstdc++'s
352+
// __cxa_throw won't see the unwinding info we registered with our statically
353+
// linked libgcc.
354+
//
355+
// Now, simply statically linking libstdc++ would fix this problem, except
356+
// that it is compiled with the expectation that pthreads is dynamically
357+
// linked as a DLL and will fail to link with a statically linked libpthread.
358+
//
359+
// So we end up with the following hack: we link use static:-bundle to only
360+
// link the parts of libstdc++ that we actually use, which doesn't include
361+
// the dependency on the pthreads DLL.
362+
if is_msvc() { None } else { Some("-lstatic:-bundle=stdc++") }
363+
} else if is_darwin() {
364+
Some("-lc++")
365+
} else {
366+
match &uname()[..] {
367+
"FreeBSD" | "SunOS" | "OpenBSD" => None,
368+
_ => Some("-lstdc++"),
369+
}
370+
};
371+
if let Some(flag) = flag {
372+
self.cmd.arg(flag);
373+
}
374+
self
375+
}
317376
}

src/tools/run-make-support/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ pub use wasmparser;
4343
pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
4444

4545
// These rely on external dependencies.
46-
pub use c_build::{build_native_dynamic_lib, build_native_static_lib};
4746
pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
47+
pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_cxx};
4848
pub use clang::{clang, Clang};
4949
pub use htmldocck::htmldocck;
5050
pub use llvm::{

src/tools/tidy/src/allowed_run_make_makefiles.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,8 @@ run-make/dep-info/Makefile
1111
run-make/emit-to-stdout/Makefile
1212
run-make/extern-fn-reachable/Makefile
1313
run-make/fmt-write-bloat/Makefile
14-
run-make/foreign-double-unwind/Makefile
15-
run-make/foreign-exceptions/Makefile
1614
run-make/incr-add-rust-src-component/Makefile
1715
run-make/issue-35164/Makefile
18-
run-make/issue-36710/Makefile
1916
run-make/issue-47551/Makefile
2017
run-make/issue-69368/Makefile
2118
run-make/issue-84395-lto-embed-bitcode/Makefile
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Some start files were missed when originally writing the logic to swap in musl start files.
2+
// This caused #36710. After the fix in #50105, this test checks that linking to C++ code
3+
// with global destructors works.
4+
// See https://github.com/rust-lang/rust/pull/50105
5+
6+
//@ ignore-cross-compile
7+
// Reason: the compiled binary is executed
8+
9+
// FIXME(Oneirical): are these really necessary? This test is supposed to test a musl
10+
// bug... and it ignores musl? This wasn't part of the original test at its creation, which
11+
// had no ignores.
12+
13+
//# ignore-none no-std is not supported
14+
//# ignore-wasm32 FIXME: don't attempt to compile C++ to WASM
15+
//# ignore-wasm64 FIXME: don't attempt to compile C++ to WASM
16+
//# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for `std`
17+
//# ignore-musl FIXME: this makefile needs teaching how to use a musl toolchain
18+
//# (see dist-i586-gnu-i586-i686-musl Dockerfile)
19+
//# ignore-sgx
20+
21+
use run_make_support::{build_native_static_lib_cxx, run, rustc};
22+
23+
fn main() {
24+
build_native_static_lib_cxx("foo");
25+
rustc().input("foo.rs").arg("-lfoo").extra_rs_cxx_flags().run();
26+
run("foo");
27+
}

tests/run-make/foreign-double-unwind/Makefile

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// When using foreign function interface (FFI) with C++, it is possible
2+
// to run into a "double unwind" if either both Rust and C++ run into a panic
3+
// and exception at the same time, or C++ encounters two exceptions. In this case,
4+
// one of the panic unwinds would be leaked and the other would be kept, leading
5+
// to undefined behaviour. After this was fixed in #92911, this test checks that
6+
// the keyword "unreachable" indicative of this bug triggering in this specific context
7+
// does not appear after successfully compiling and executing the program.
8+
// See https://github.com/rust-lang/rust/pull/92911
9+
10+
//@ needs-unwind
11+
// Reason: this test exercises panic unwinding
12+
//@ ignore-cross-compile
13+
// Reason: the compiled binary is executed
14+
15+
use run_make_support::{build_native_static_lib_cxx, run_fail, rustc};
16+
17+
fn main() {
18+
build_native_static_lib_cxx("foo");
19+
rustc().input("foo.rs").arg("-lfoo").extra_rs_cxx_flags().run();
20+
run_fail("foo").assert_stdout_not_contains("unreachable");
21+
}

tests/run-make/foreign-exceptions/Makefile

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// This test was created to check that compilation and execution still works
2+
// after the addition of a new feature, in #65646: the ability to unwind panics
3+
// and exceptions back and forth between Rust and C++. Should this feature be broken,
4+
// the test should fail.
5+
// See https://github.com/rust-lang/rust/pull/65646
6+
7+
//@ needs-unwind
8+
// Reason: this test exercises panic unwinding
9+
//@ ignore-cross-compile
10+
// Reason: the compiled binary is executed
11+
12+
use run_make_support::{build_native_static_lib_cxx, run, rustc};
13+
14+
fn main() {
15+
build_native_static_lib_cxx("foo");
16+
rustc().input("foo.rs").arg("-lfoo").extra_rs_cxx_flags().run();
17+
run("foo");
18+
}

tests/run-make/issue-36710/Makefile

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)