diff --git a/src/test/run-make-fulldeps/foreign-exceptions/Makefile b/src/test/run-make-fulldeps/foreign-exceptions/Makefile index fd15db9f15176..7eba52f3c24e8 100644 --- a/src/test/run-make-fulldeps/foreign-exceptions/Makefile +++ b/src/test/run-make-fulldeps/foreign-exceptions/Makefile @@ -4,7 +4,7 @@ all: foo $(call RUN,foo) foo: foo.rs $(call NATIVE_STATICLIB,foo) - $(RUSTC) $< -lfoo $(EXTRACXXFLAGS) + $(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS) $(TMPDIR)/libfoo.o: foo.cpp $(call COMPILE_OBJ_CXX,$@,$<) diff --git a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs index 83adf000d9efe..399c78f8d2d02 100644 --- a/src/test/run-make-fulldeps/foreign-exceptions/foo.rs +++ b/src/test/run-make-fulldeps/foreign-exceptions/foo.rs @@ -2,6 +2,9 @@ // are ignored by catch_unwind. Also tests that Rust panics can unwind through // C++ code. +// For linking libstdc++ on MinGW +#![cfg_attr(all(windows, target_env = "gnu"), feature(static_nobundle))] + #![feature(unwind_attributes)] use std::panic::{catch_unwind, AssertUnwindSafe}; diff --git a/src/test/run-make-fulldeps/issue-36710/Makefile b/src/test/run-make-fulldeps/issue-36710/Makefile index dc1fbb4cefb84..4f93d97636e60 100644 --- a/src/test/run-make-fulldeps/issue-36710/Makefile +++ b/src/test/run-make-fulldeps/issue-36710/Makefile @@ -6,7 +6,7 @@ all: foo $(call RUN,foo) foo: foo.rs $(call NATIVE_STATICLIB,foo) - $(RUSTC) $< -lfoo $(EXTRACXXFLAGS) + $(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS) $(TMPDIR)/libfoo.o: foo.cpp $(call COMPILE_OBJ_CXX,$@,$<) diff --git a/src/test/run-make-fulldeps/issue-36710/foo.rs b/src/test/run-make-fulldeps/issue-36710/foo.rs index a9d3effbd1806..061f07c324340 100644 --- a/src/test/run-make-fulldeps/issue-36710/foo.rs +++ b/src/test/run-make-fulldeps/issue-36710/foo.rs @@ -1,5 +1,8 @@ // Tests that linking to C++ code with global destructors works. +// For linking libstdc++ on MinGW +#![cfg_attr(all(windows, target_env = "gnu"), feature(static_nobundle))] + extern { fn get() -> u32; } fn main() { diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk index 98bae25220e9d..3194826371762 100644 --- a/src/test/run-make-fulldeps/tools.mk +++ b/src/test/run-make-fulldeps/tools.mk @@ -81,6 +81,22 @@ ifdef IS_MSVC else EXTRACFLAGS := -lws2_32 -luserenv EXTRACXXFLAGS := -lstdc++ + # 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-nobundle to only + # link the parts of libstdc++ that we actually use, which doesn't include + # the dependency on the pthreads DLL. + EXTRARSCXXFLAGS := -l static-nobundle=stdc++ endif else ifeq ($(UNAME),Darwin) @@ -98,6 +114,7 @@ ifeq ($(UNAME),OpenBSD) else EXTRACFLAGS := -lm -lrt -ldl -lpthread EXTRACXXFLAGS := -lstdc++ + EXTRARSCXXFLAGS := -lstdc++ endif endif endif