about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/run-make-support/src/external_deps/c_build.rs24
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs59
-rw-r--r--src/tools/run-make-support/src/lib.rs2
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt3
-rw-r--r--tests/run-make/cpp-global-destructors/foo.cpp (renamed from tests/run-make/issue-36710/foo.cpp)0
-rw-r--r--tests/run-make/cpp-global-destructors/foo.rs (renamed from tests/run-make/issue-36710/foo.rs)0
-rw-r--r--tests/run-make/cpp-global-destructors/rmake.rs26
-rw-r--r--tests/run-make/foreign-double-unwind/Makefile12
-rw-r--r--tests/run-make/foreign-double-unwind/rmake.rs21
-rw-r--r--tests/run-make/foreign-exceptions/Makefile12
-rw-r--r--tests/run-make/foreign-exceptions/rmake.rs19
-rw-r--r--tests/run-make/issue-36710/Makefile19
12 files changed, 149 insertions, 48 deletions
diff --git a/src/tools/run-make-support/src/external_deps/c_build.rs b/src/tools/run-make-support/src/external_deps/c_build.rs
index 86c9c081831..15e02d04393 100644
--- a/src/tools/run-make-support/src/external_deps/c_build.rs
+++ b/src/tools/run-make-support/src/external_deps/c_build.rs
@@ -2,7 +2,7 @@ use std::path::PathBuf;
 
 use super::cygpath::get_windows_path;
 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::path_helpers::path;
 use crate::targets::{is_darwin, is_msvc, is_windows};
@@ -10,6 +10,7 @@ use crate::targets::{is_darwin, is_msvc, is_windows};
 // 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.
+/// Built from a C file.
 #[track_caller]
 pub fn build_native_static_lib(lib_name: &str) -> PathBuf {
     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)
 }
+
+/// 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)
+}
diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs
index 71d28dd9675..cece58d2956 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -5,6 +5,7 @@ use crate::command::Command;
 use crate::env::env_var;
 use crate::path_helpers::cwd;
 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
 /// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
@@ -314,4 +315,62 @@ impl Rustc {
         self.cmd.arg(format!("-Clinker-flavor={linker_flavor}"));
         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
+    }
 }
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 97c6bfe86d2..63c4c4d8863 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -44,8 +44,8 @@ pub use wasmparser;
 pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rustdoc};
 
 // 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 c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_cxx};
 pub use clang::{clang, Clang};
 pub use htmldocck::htmldocck;
 pub use llvm::{
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index a7c8df3e274..bd4f54d22da 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -9,10 +9,7 @@ run-make/dep-info-spaces/Makefile
 run-make/dep-info/Makefile
 run-make/emit-to-stdout/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/issue-36710/Makefile
 run-make/issue-84395-lto-embed-bitcode/Makefile
 run-make/issue-88756-default-output/Makefile
 run-make/jobserver-error/Makefile
diff --git a/tests/run-make/issue-36710/foo.cpp b/tests/run-make/cpp-global-destructors/foo.cpp
index 8f878c2c272..8f878c2c272 100644
--- a/tests/run-make/issue-36710/foo.cpp
+++ b/tests/run-make/cpp-global-destructors/foo.cpp
diff --git a/tests/run-make/issue-36710/foo.rs b/tests/run-make/cpp-global-destructors/foo.rs
index f30a35e27c0..f30a35e27c0 100644
--- a/tests/run-make/issue-36710/foo.rs
+++ b/tests/run-make/cpp-global-destructors/foo.rs
diff --git a/tests/run-make/cpp-global-destructors/rmake.rs b/tests/run-make/cpp-global-destructors/rmake.rs
new file mode 100644
index 00000000000..9bc5c84e10d
--- /dev/null
+++ b/tests/run-make/cpp-global-destructors/rmake.rs
@@ -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");
+}
diff --git a/tests/run-make/foreign-double-unwind/Makefile b/tests/run-make/foreign-double-unwind/Makefile
deleted file mode 100644
index b5e52808d2f..00000000000
--- a/tests/run-make/foreign-double-unwind/Makefile
+++ /dev/null
@@ -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,$@,$<)
diff --git a/tests/run-make/foreign-double-unwind/rmake.rs b/tests/run-make/foreign-double-unwind/rmake.rs
new file mode 100644
index 00000000000..9bd3b4c0fea
--- /dev/null
+++ b/tests/run-make/foreign-double-unwind/rmake.rs
@@ -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");
+}
diff --git a/tests/run-make/foreign-exceptions/Makefile b/tests/run-make/foreign-exceptions/Makefile
deleted file mode 100644
index 56c41b274fb..00000000000
--- a/tests/run-make/foreign-exceptions/Makefile
+++ /dev/null
@@ -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,$@,$<)
diff --git a/tests/run-make/foreign-exceptions/rmake.rs b/tests/run-make/foreign-exceptions/rmake.rs
new file mode 100644
index 00000000000..929319f049f
--- /dev/null
+++ b/tests/run-make/foreign-exceptions/rmake.rs
@@ -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");
+}
diff --git a/tests/run-make/issue-36710/Makefile b/tests/run-make/issue-36710/Makefile
deleted file mode 100644
index 7b91107a234..00000000000
--- a/tests/run-make/issue-36710/Makefile
+++ /dev/null
@@ -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,$@,$<)