diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index be50911f4e143..a311d19dd2c61 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1625,26 +1625,7 @@ fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) { /// Add arbitrary "late link" args defined by the target spec. /// FIXME: Determine where exactly these args need to be inserted. -fn add_late_link_args( - cmd: &mut dyn Linker, - sess: &Session, - flavor: LinkerFlavor, - crate_type: CrateType, - codegen_results: &CodegenResults, -) { - let any_dynamic_crate = crate_type == CrateType::Dylib - || codegen_results.crate_info.dependency_formats.iter().any(|(ty, list)| { - *ty == crate_type && list.iter().any(|&linkage| linkage == Linkage::Dynamic) - }); - if any_dynamic_crate { - if let Some(args) = sess.target.late_link_args_dynamic.get(&flavor) { - cmd.args(args); - } - } else { - if let Some(args) = sess.target.late_link_args_static.get(&flavor) { - cmd.args(args); - } - } +fn add_late_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let Some(args) = sess.target.late_link_args.get(&flavor) { cmd.args(args); } @@ -1870,7 +1851,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( // FIXME: Built-in target specs occasionally use this for linking system libraries, // eliminate all such uses by migrating them to `#[link]` attributes in `lib(std,c,unwind)` // and remove the option. - add_late_link_args(cmd, sess, flavor, crate_type, codegen_results); + add_late_link_args(cmd, sess, flavor); // ------------ Arbitrary order-independent options ------------ diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 484593dcf4d78..5e0eba3b6d06b 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1077,12 +1077,6 @@ pub struct TargetOptions { /// user-defined but before post-link objects. Standard platform /// libraries that should be always be linked to, usually go here. pub late_link_args: LinkArgs, - /// Linker arguments used in addition to `late_link_args` if at least one - /// Rust dependency is dynamically linked. - pub late_link_args_dynamic: LinkArgs, - /// Linker arguments used in addition to `late_link_args` if aall Rust - /// dependencies are statically linked. - pub late_link_args_static: LinkArgs, /// Linker arguments that are unconditionally passed *after* any /// user-defined libraries. pub post_link_args: LinkArgs, @@ -1416,8 +1410,6 @@ impl Default for TargetOptions { post_link_objects_fallback: Default::default(), crt_objects_fallback: None, late_link_args: LinkArgs::new(), - late_link_args_dynamic: LinkArgs::new(), - late_link_args_static: LinkArgs::new(), link_env: Vec::new(), link_env_remove: Vec::new(), archive_format: "gnu".to_string(), @@ -1965,8 +1957,6 @@ impl Target { key!(crt_objects_fallback, crt_objects_fallback)?; key!(pre_link_args, link_args); key!(late_link_args, link_args); - key!(late_link_args_dynamic, link_args); - key!(late_link_args_static, link_args); key!(post_link_args, link_args); key!(link_script, optional); key!(link_env, env); @@ -2204,8 +2194,6 @@ impl ToJson for Target { target_option_val!(crt_objects_fallback); target_option_val!(link_args - pre_link_args); target_option_val!(link_args - late_link_args); - target_option_val!(link_args - late_link_args_dynamic); - target_option_val!(link_args - late_link_args_static); target_option_val!(link_args - post_link_args); target_option_val!(link_script); target_option_val!(env - link_env); diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index 6730319dcfae2..b206290e335c3 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -18,13 +18,7 @@ impl Target { self.lld_flavor == LldFlavor::Link, ); assert_eq!(self.is_like_msvc, self.lld_flavor == LldFlavor::Link); - for args in &[ - &self.pre_link_args, - &self.late_link_args, - &self.late_link_args_dynamic, - &self.late_link_args_static, - &self.post_link_args, - ] { + for args in &[&self.pre_link_args, &self.late_link_args, &self.post_link_args] { assert_eq!( args.get(&LinkerFlavor::Msvc), args.get(&LinkerFlavor::Lld(LldFlavor::Link)), diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs index 35a52896f6fa6..835e250bd4227 100644 --- a/compiler/rustc_target/src/spec/windows_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs @@ -17,8 +17,6 @@ pub fn opts() -> TargetOptions { ); let mut late_link_args = LinkArgs::new(); - let mut late_link_args_dynamic = LinkArgs::new(); - let mut late_link_args_static = LinkArgs::new(); // Order of `late_link_args*` was found through trial and error to work with various // mingw-w64 versions (not tested on the CI). It's expected to change from time to time. let mingw_libs = vec![ @@ -39,25 +37,6 @@ pub fn opts() -> TargetOptions { ]; late_link_args.insert(LinkerFlavor::Gcc, mingw_libs.clone()); late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs); - let dynamic_unwind_libs = vec![ - // If any of our crates are dynamically linked then we need to use - // the shared libgcc_s-dw2-1.dll. This is required to support - // unwinding across DLL boundaries. - "-lgcc_s".to_string(), - ]; - late_link_args_dynamic.insert(LinkerFlavor::Gcc, dynamic_unwind_libs.clone()); - late_link_args_dynamic.insert(LinkerFlavor::Lld(LldFlavor::Ld), dynamic_unwind_libs); - let static_unwind_libs = vec![ - // If all of our crates are statically linked then we can get away - // with statically linking the libgcc unwinding code. This allows - // binaries to be redistributed without the libgcc_s-dw2-1.dll - // dependency, but unfortunately break unwinding across DLL - // boundaries when unwinding across FFI boundaries. - "-lgcc_eh".to_string(), - "-l:libpthread.a".to_string(), - ]; - late_link_args_static.insert(LinkerFlavor::Gcc, static_unwind_libs.clone()); - late_link_args_static.insert(LinkerFlavor::Lld(LldFlavor::Ld), static_unwind_libs); TargetOptions { os: "windows".to_string(), @@ -81,8 +60,8 @@ pub fn opts() -> TargetOptions { post_link_objects_fallback: crt_objects::post_mingw_fallback(), crt_objects_fallback: Some(CrtObjectsFallback::Mingw), late_link_args, - late_link_args_dynamic, - late_link_args_static, + crt_static_allows_dylibs: true, + crt_static_respected: true, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, requires_uwtable: true, diff --git a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs index 86df816f10dc2..d7c989c9cddb1 100644 --- a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs @@ -6,8 +6,6 @@ pub fn opts() -> TargetOptions { // FIXME: This should be updated for the exception machinery changes from #67502 // and inherit from `windows_gnu_base`, at least partially. let mut late_link_args = LinkArgs::new(); - let late_link_args_dynamic = LinkArgs::new(); - let late_link_args_static = LinkArgs::new(); let mingw_libs = vec![ //"-lwinstorecompat".to_string(), //"-lmingwex".to_string(), @@ -30,8 +28,6 @@ pub fn opts() -> TargetOptions { executables: false, limit_rdylib_exports: false, late_link_args, - late_link_args_dynamic, - late_link_args_static, ..base } diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 1941f2b5a0026..6f5e4c4d5a744 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -24,11 +24,11 @@ cc = "1.0.69" [features] -# Only applies for Linux and Fuchsia targets +# Only applies for MinGW, Linux and Fuchsia targets # Static link to the in-tree build of llvm libunwind llvm-libunwind = [] -# Only applies for Linux and Fuchsia targets +# Only applies for MinGW, Linux and Fuchsia targets # If crt-static is enabled, static link to `libunwind.a` provided by system # If crt-static is disabled, dynamic link to `libunwind.so` provided by system system-llvm-libunwind = [] diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 079626f0fea54..dad75fadf7ee8 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -83,6 +83,32 @@ extern "C" {} #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] extern "C" {} +#[cfg(all( + windows, + target_env = "gnu", + not(feature = "llvm-libunwind"), + not(feature = "system-llvm-libunwind") +))] +#[link(name = "gcc_eh", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] +#[link( + name = "pthread", + kind = "static", + modifiers = "-bundle", + cfg(target_feature = "crt-static") +)] +#[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] +extern "C" {} + +#[cfg(all( + windows, + target_env = "gnu", + not(feature = "llvm-libunwind"), + feature = "system-llvm-libunwind" +))] +#[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] +#[link(name = "unwind", cfg(not(target_feature = "crt-static")))] +extern "C" {} + #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] #[link(name = "unwind", kind = "static", modifiers = "-bundle")] extern "C" {} diff --git a/src/test/run-make-fulldeps/foreign-exceptions/Makefile b/src/test/run-make-fulldeps/foreign-exceptions/Makefile index 7eba52f3c24e8..fd15db9f15176 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 $(EXTRARSCXXFLAGS) + $(RUSTC) $< -lfoo $(EXTRACXXFLAGS) $(TMPDIR)/libfoo.o: foo.cpp $(call COMPILE_OBJ_CXX,$@,$<) diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk index 9655d09df0f2a..6426c3de6294d 100644 --- a/src/test/run-make-fulldeps/tools.mk +++ b/src/test/run-make-fulldeps/tools.mk @@ -105,28 +105,11 @@ ifdef IS_MSVC else EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt 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:-bundle to only - # link the parts of libstdc++ that we actually use, which doesn't include - # the dependency on the pthreads DLL. - EXTRARSCXXFLAGS := -l static:-bundle=stdc++ -Z unstable-options endif else ifeq ($(UNAME),Darwin) EXTRACFLAGS := -lresolv EXTRACXXFLAGS := -lc++ - EXTRARSCXXFLAGS := -lc++ else ifeq ($(UNAME),FreeBSD) EXTRACFLAGS := -lm -lpthread -lgcc_s @@ -140,7 +123,6 @@ ifeq ($(UNAME),OpenBSD) else EXTRACFLAGS := -lm -lrt -ldl -lpthread EXTRACXXFLAGS := -lstdc++ - EXTRARSCXXFLAGS := -lstdc++ endif endif endif diff --git a/src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile b/src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile index f6adb6d76279d..96204a2356b33 100644 --- a/src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile +++ b/src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile @@ -5,5 +5,5 @@ PATH=$(SYSTEMROOT)/system32 all: - $(RUSTC) hello.rs + $(RUSTC) hello.rs -C target-feature=+crt-static $(TMPDIR)/hello.exe diff --git a/src/test/run-make/issue-36710/Makefile b/src/test/run-make/issue-36710/Makefile index b5270ad2ba9d4..758b699db04c7 100644 --- a/src/test/run-make/issue-36710/Makefile +++ b/src/test/run-make/issue-36710/Makefile @@ -14,7 +14,7 @@ all: foo $(call RUN,foo) foo: foo.rs $(call NATIVE_STATICLIB,foo) - $(RUSTC) $< -lfoo $(EXTRARSCXXFLAGS) --target $(TARGET) + $(RUSTC) $< -lfoo $(EXTRACXXFLAGS) --target $(TARGET) $(TMPDIR)/libfoo.o: foo.cpp $(call COMPILE_OBJ_CXX,$@,$<)