Auto merge of #127926 - Oneirical:classical-orctestra, r=jieyouxu
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
This commit is contained in:
commit
f82eb4d0a0
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use super::cygpath::get_windows_path;
|
use super::cygpath::get_windows_path;
|
||||||
use crate::artifact_names::{dynamic_lib_name, static_lib_name};
|
use crate::artifact_names::{dynamic_lib_name, static_lib_name};
|
||||||
use crate::external_deps::cc::cc;
|
use crate::external_deps::cc::{cc, cxx};
|
||||||
use crate::external_deps::llvm::llvm_ar;
|
use crate::external_deps::llvm::llvm_ar;
|
||||||
use crate::path_helpers::path;
|
use crate::path_helpers::path;
|
||||||
use crate::targets::{is_darwin, is_msvc, is_windows};
|
use crate::targets::{is_darwin, is_msvc, is_windows};
|
||||||
@ -10,6 +10,7 @@
|
|||||||
// FIXME(Oneirical): These native build functions should take a Path-based generic.
|
// FIXME(Oneirical): These native build functions should take a Path-based generic.
|
||||||
|
|
||||||
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
|
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
|
||||||
|
/// Built from a C file.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
|
pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
|
||||||
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
|
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 {
|
|||||||
}
|
}
|
||||||
path(lib_path)
|
path(lib_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name.
|
||||||
|
/// Built from a C++ file.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn build_native_static_lib_cxx(lib_name: &str) -> PathBuf {
|
||||||
|
let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") };
|
||||||
|
let src = format!("{lib_name}.cpp");
|
||||||
|
let lib_path = static_lib_name(lib_name);
|
||||||
|
if is_msvc() {
|
||||||
|
cxx().arg("-EHs").arg("-c").out_exe(&obj_file).input(src).run();
|
||||||
|
} else {
|
||||||
|
cxx().arg("-c").out_exe(&obj_file).input(src).run();
|
||||||
|
};
|
||||||
|
let obj_file = if is_msvc() {
|
||||||
|
PathBuf::from(format!("{lib_name}.obj"))
|
||||||
|
} else {
|
||||||
|
PathBuf::from(format!("{lib_name}.o"))
|
||||||
|
};
|
||||||
|
llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run();
|
||||||
|
path(lib_path)
|
||||||
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
use crate::env::env_var;
|
use crate::env::env_var;
|
||||||
use crate::path_helpers::cwd;
|
use crate::path_helpers::cwd;
|
||||||
use crate::util::set_host_rpath;
|
use crate::util::set_host_rpath;
|
||||||
|
use crate::{is_darwin, is_msvc, is_windows, uname};
|
||||||
|
|
||||||
/// Construct a new `rustc` invocation. This will automatically set the library
|
/// Construct a new `rustc` invocation. This will automatically set the library
|
||||||
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
|
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
|
||||||
@ -314,4 +315,62 @@ pub fn linker_flavor(&mut self, linker_flavor: &str) -> &mut Self {
|
|||||||
self.cmd.arg(format!("-Clinker-flavor={linker_flavor}"));
|
self.cmd.arg(format!("-Clinker-flavor={linker_flavor}"));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `EXTRARSCXXFLAGS`
|
||||||
|
pub fn extra_rs_cxx_flags(&mut self) -> &mut Self {
|
||||||
|
// Adapted from tools.mk (trimmed):
|
||||||
|
//
|
||||||
|
// ```makefile
|
||||||
|
// ifdef IS_WINDOWS
|
||||||
|
// ifdef IS_MSVC
|
||||||
|
// else
|
||||||
|
// EXTRARSCXXFLAGS := -lstatic:-bundle=stdc++
|
||||||
|
// endif
|
||||||
|
// else
|
||||||
|
// ifeq ($(UNAME),Darwin)
|
||||||
|
// EXTRARSCXXFLAGS := -lc++
|
||||||
|
// else
|
||||||
|
// ifeq ($(UNAME),FreeBSD)
|
||||||
|
// else
|
||||||
|
// ifeq ($(UNAME),SunOS)
|
||||||
|
// else
|
||||||
|
// ifeq ($(UNAME),OpenBSD)
|
||||||
|
// else
|
||||||
|
// EXTRARSCXXFLAGS := -lstdc++
|
||||||
|
// endif
|
||||||
|
// endif
|
||||||
|
// endif
|
||||||
|
// endif
|
||||||
|
// endif
|
||||||
|
// ```
|
||||||
|
let flag = if is_windows() {
|
||||||
|
// So this is a bit hacky: we can't use the DLL version of libstdc++ because
|
||||||
|
// it pulls in the DLL version of libgcc, which means that we end up with 2
|
||||||
|
// instances of the DW2 unwinding implementation. This is a problem on
|
||||||
|
// i686-pc-windows-gnu because each module (DLL/EXE) needs to register its
|
||||||
|
// unwind information with the unwinding implementation, and libstdc++'s
|
||||||
|
// __cxa_throw won't see the unwinding info we registered with our statically
|
||||||
|
// linked libgcc.
|
||||||
|
//
|
||||||
|
// Now, simply statically linking libstdc++ would fix this problem, except
|
||||||
|
// that it is compiled with the expectation that pthreads is dynamically
|
||||||
|
// linked as a DLL and will fail to link with a statically linked libpthread.
|
||||||
|
//
|
||||||
|
// So we end up with the following hack: we link use static:-bundle to only
|
||||||
|
// link the parts of libstdc++ that we actually use, which doesn't include
|
||||||
|
// the dependency on the pthreads DLL.
|
||||||
|
if is_msvc() { None } else { Some("-lstatic:-bundle=stdc++") }
|
||||||
|
} else if is_darwin() {
|
||||||
|
Some("-lc++")
|
||||||
|
} else {
|
||||||
|
match &uname()[..] {
|
||||||
|
"FreeBSD" | "SunOS" | "OpenBSD" => None,
|
||||||
|
_ => Some("-lstdc++"),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(flag) = flag {
|
||||||
|
self.cmd.arg(flag);
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,8 @@ pub mod rfs {
|
|||||||
pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
|
pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
|
||||||
|
|
||||||
// These rely on external dependencies.
|
// These rely on external dependencies.
|
||||||
pub use c_build::{build_native_dynamic_lib, build_native_static_lib};
|
|
||||||
pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
|
pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
|
||||||
|
pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_cxx};
|
||||||
pub use clang::{clang, Clang};
|
pub use clang::{clang, Clang};
|
||||||
pub use htmldocck::htmldocck;
|
pub use htmldocck::htmldocck;
|
||||||
pub use llvm::{
|
pub use llvm::{
|
||||||
|
@ -9,10 +9,7 @@ run-make/dep-info-spaces/Makefile
|
|||||||
run-make/dep-info/Makefile
|
run-make/dep-info/Makefile
|
||||||
run-make/emit-to-stdout/Makefile
|
run-make/emit-to-stdout/Makefile
|
||||||
run-make/extern-fn-reachable/Makefile
|
run-make/extern-fn-reachable/Makefile
|
||||||
run-make/foreign-double-unwind/Makefile
|
|
||||||
run-make/foreign-exceptions/Makefile
|
|
||||||
run-make/incr-add-rust-src-component/Makefile
|
run-make/incr-add-rust-src-component/Makefile
|
||||||
run-make/issue-36710/Makefile
|
|
||||||
run-make/issue-84395-lto-embed-bitcode/Makefile
|
run-make/issue-84395-lto-embed-bitcode/Makefile
|
||||||
run-make/issue-88756-default-output/Makefile
|
run-make/issue-88756-default-output/Makefile
|
||||||
run-make/jobserver-error/Makefile
|
run-make/jobserver-error/Makefile
|
||||||
|
26
tests/run-make/cpp-global-destructors/rmake.rs
Normal file
26
tests/run-make/cpp-global-destructors/rmake.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Some start files were missed when originally writing the logic to swap in musl start files.
|
||||||
|
// This caused #36710. After the fix in #50105, this test checks that linking to C++ code
|
||||||
|
// with global destructors works.
|
||||||
|
// See https://github.com/rust-lang/rust/pull/50105
|
||||||
|
|
||||||
|
//@ ignore-cross-compile
|
||||||
|
// Reason: the compiled binary is executed
|
||||||
|
|
||||||
|
//@ ignore-none
|
||||||
|
// Reason: no-std is not supported.
|
||||||
|
//@ ignore-wasm32
|
||||||
|
//@ ignore-wasm64
|
||||||
|
// Reason: compiling C++ to WASM may cause problems.
|
||||||
|
|
||||||
|
// Neither of these are tested in full CI.
|
||||||
|
//@ ignore-nvptx64-nvidia-cuda
|
||||||
|
// Reason: can't find crate "std"
|
||||||
|
//@ ignore-sgx
|
||||||
|
|
||||||
|
use run_make_support::{build_native_static_lib_cxx, run, rustc};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
build_native_static_lib_cxx("foo");
|
||||||
|
rustc().input("foo.rs").arg("-lfoo").extra_rs_cxx_flags().run();
|
||||||
|
run("foo");
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
# ignore-cross-compile
|
|
||||||
# needs-unwind
|
|
||||||
include ../tools.mk
|
|
||||||
|
|
||||||
all: foo
|
|
||||||
$(call RUN,foo) | $(CGREP) -v unreachable
|
|
||||||
|
|
||||||
foo: foo.rs $(call NATIVE_STATICLIB,foo)
|
|
||||||
$(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS)
|
|
||||||
|
|
||||||
$(TMPDIR)/libfoo.o: foo.cpp
|
|
||||||
$(call COMPILE_OBJ_CXX,$@,$<)
|
|
21
tests/run-make/foreign-double-unwind/rmake.rs
Normal file
21
tests/run-make/foreign-double-unwind/rmake.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// When using foreign function interface (FFI) with C++, it is possible
|
||||||
|
// to run into a "double unwind" if either both Rust and C++ run into a panic
|
||||||
|
// and exception at the same time, or C++ encounters two exceptions. In this case,
|
||||||
|
// one of the panic unwinds would be leaked and the other would be kept, leading
|
||||||
|
// to undefined behaviour. After this was fixed in #92911, this test checks that
|
||||||
|
// the keyword "unreachable" indicative of this bug triggering in this specific context
|
||||||
|
// does not appear after successfully compiling and executing the program.
|
||||||
|
// See https://github.com/rust-lang/rust/pull/92911
|
||||||
|
|
||||||
|
//@ needs-unwind
|
||||||
|
// Reason: this test exercises panic unwinding
|
||||||
|
//@ ignore-cross-compile
|
||||||
|
// Reason: the compiled binary is executed
|
||||||
|
|
||||||
|
use run_make_support::{build_native_static_lib_cxx, run_fail, rustc};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
build_native_static_lib_cxx("foo");
|
||||||
|
rustc().input("foo.rs").arg("-lfoo").extra_rs_cxx_flags().run();
|
||||||
|
run_fail("foo").assert_stdout_not_contains("unreachable");
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
# ignore-cross-compile
|
|
||||||
# needs-unwind
|
|
||||||
include ../tools.mk
|
|
||||||
|
|
||||||
all: foo
|
|
||||||
$(call RUN,foo)
|
|
||||||
|
|
||||||
foo: foo.rs $(call NATIVE_STATICLIB,foo)
|
|
||||||
$(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS)
|
|
||||||
|
|
||||||
$(TMPDIR)/libfoo.o: foo.cpp
|
|
||||||
$(call COMPILE_OBJ_CXX,$@,$<)
|
|
19
tests/run-make/foreign-exceptions/rmake.rs
Normal file
19
tests/run-make/foreign-exceptions/rmake.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// This test was created to check that compilation and execution still works
|
||||||
|
// after the addition of a new feature, in #65646: the ability to unwind panics
|
||||||
|
// and exceptions back and forth between Rust and C++. This is a basic smoke test,
|
||||||
|
// this feature being broken in quiet or subtle ways could still result in this test
|
||||||
|
// passing.
|
||||||
|
// See https://github.com/rust-lang/rust/pull/65646
|
||||||
|
|
||||||
|
//@ needs-unwind
|
||||||
|
// Reason: this test exercises panic unwinding
|
||||||
|
//@ ignore-cross-compile
|
||||||
|
// Reason: the compiled binary is executed
|
||||||
|
|
||||||
|
use run_make_support::{build_native_static_lib_cxx, run, rustc};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
build_native_static_lib_cxx("foo");
|
||||||
|
rustc().input("foo.rs").arg("-lfoo").extra_rs_cxx_flags().run();
|
||||||
|
run("foo");
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
# ignore-cross-compile
|
|
||||||
# ignore-none no-std is not supported
|
|
||||||
# ignore-wasm32 FIXME: don't attempt to compile C++ to WASM
|
|
||||||
# ignore-wasm64 FIXME: don't attempt to compile C++ to WASM
|
|
||||||
# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for `std`
|
|
||||||
# ignore-musl FIXME: this makefile needs teaching how to use a musl toolchain
|
|
||||||
# (see dist-i586-gnu-i586-i686-musl Dockerfile)
|
|
||||||
# ignore-sgx
|
|
||||||
|
|
||||||
include ../tools.mk
|
|
||||||
|
|
||||||
all: foo
|
|
||||||
$(call RUN,foo)
|
|
||||||
|
|
||||||
foo: foo.rs $(call NATIVE_STATICLIB,foo)
|
|
||||||
$(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS) --target $(TARGET)
|
|
||||||
|
|
||||||
$(TMPDIR)/libfoo.o: foo.cpp
|
|
||||||
$(call COMPILE_OBJ_CXX,$@,$<)
|
|
Loading…
Reference in New Issue
Block a user