From 1c945b9c06d0d8b402a28f5e96ab63316e02dca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 10 Apr 2020 20:12:18 +0200 Subject: [PATCH] MinGW: move unwind linkage to libunwind --- src/librustc_codegen_ssa/back/link.rs | 23 ++----------- src/librustc_target/spec/mod.rs | 12 ------- src/librustc_target/spec/windows_base.rs | 32 +------------------ src/libunwind/build.rs | 2 +- src/libunwind/lib.rs | 16 ++++++++++ .../windows-binary-no-external-deps/Makefile | 9 ++++++ .../windows-binary-no-external-deps/hello.rs | 3 ++ 7 files changed, 32 insertions(+), 65 deletions(-) create mode 100644 src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile create mode 100644 src/test/run-make-fulldeps/windows-binary-no-external-deps/hello.rs diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index 20e64f0c48851..e54898faa2b87 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1218,29 +1218,10 @@ fn add_user_defined_link_args( /// 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: config::CrateType, - codegen_results: &CodegenResults, -) { +fn add_late_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) { cmd.args(args); } - let any_dynamic_crate = crate_type == config::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.target.options.late_link_args_dynamic.get(&flavor) { - cmd.args(args); - } - } else { - if let Some(args) = sess.target.target.options.late_link_args_static.get(&flavor) { - cmd.args(args); - } - } } /// Add arbitrary "post-link" args defined by the target spec. @@ -1581,7 +1562,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>( cmd.finalize(); // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT - add_late_link_args(cmd, sess, flavor, crate_type, codegen_results); + add_late_link_args(cmd, sess, flavor); // NO-OPT-OUT, OBJECT-FILES-YES add_post_link_objects(cmd, sess, crate_type); diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 1bc2bf12fad9e..50409cdf862bb 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -581,12 +581,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, /// Objects to link after all others, always found within the /// sysroot folder. pub post_link_objects: Vec, // ... unconditionally @@ -858,8 +852,6 @@ impl Default for TargetOptions { post_link_objects: Vec::new(), post_link_objects_crt: Vec::new(), 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(), @@ -1136,8 +1128,6 @@ impl Target { key!(pre_link_objects_exe_crt, list); key!(pre_link_objects_dll, list); key!(late_link_args, link_args); - key!(late_link_args_dynamic, link_args); - key!(late_link_args_static, link_args); key!(post_link_objects, list); key!(post_link_objects_crt, list); key!(post_link_args, link_args); @@ -1363,8 +1353,6 @@ impl ToJson for Target { target_option_val!(pre_link_objects_exe_crt); target_option_val!(pre_link_objects_dll); 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!(post_link_objects); target_option_val!(post_link_objects_crt); target_option_val!(link_args - post_link_args); diff --git a/src/librustc_target/spec/windows_base.rs b/src/librustc_target/spec/windows_base.rs index 34fcdf251b89b..9b15fb99c90ab 100644 --- a/src/librustc_target/spec/windows_base.rs +++ b/src/librustc_target/spec/windows_base.rs @@ -17,13 +17,12 @@ 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(); late_link_args.insert( LinkerFlavor::Gcc, vec![ "-lmingwex".to_string(), "-lmingw32".to_string(), + "-lgcc".to_string(), "-lmsvcrt".to_string(), // mingw's msvcrt is a weird hybrid import library and static library. // And it seems that the linker fails to use import symbols from msvcrt @@ -38,33 +37,6 @@ pub fn opts() -> TargetOptions { "-lkernel32".to_string(), ], ); - late_link_args_dynamic.insert( - LinkerFlavor::Gcc, - 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(), - "-lgcc".to_string(), - "-lkernel32".to_string(), - ], - ); - late_link_args_static.insert( - LinkerFlavor::Gcc, - 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".to_string(), - "-lgcc_eh".to_string(), - "-lpthread".to_string(), - // libpthread depends on libmsvcrt, so we need to link it *again*. - "-lmsvcrt".to_string(), - "-lkernel32".to_string(), - ], - ); TargetOptions { // FIXME(#13846) this should be enabled for windows @@ -90,8 +62,6 @@ pub fn opts() -> TargetOptions { "rsbegin.o".to_string(), ], late_link_args, - late_link_args_dynamic, - late_link_args_static, post_link_objects: vec!["rsend.o".to_string()], abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, diff --git a/src/libunwind/build.rs b/src/libunwind/build.rs index 0628e5d2fc03a..70b34df6e3ce0 100644 --- a/src/libunwind/build.rs +++ b/src/libunwind/build.rs @@ -33,7 +33,7 @@ fn main() { } else if target.contains("dragonfly") { println!("cargo:rustc-link-lib=gcc_pic"); } else if target.contains("pc-windows-gnu") { - // This is handled in the target spec with late_link_args_[static|dynamic] + // This is handled in lib.rs // cfg!(bootstrap) doesn't work in build scripts if env::var("RUSTC_STAGE").ok() == Some("0".to_string()) { diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index 18d41be77398b..393e69990a645 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -27,3 +27,19 @@ extern "C" {} #[link(name = "gcc_eh", kind = "static-nobundle", cfg(target_feature = "crt-static"))] #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] extern "C" {} + +// 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. +// 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. +// +// Linking order matters a lot here! +#[cfg(all(not(bootstrap), target_os = "windows", target_env = "gnu", target_vendor = "pc"))] +#[link(name = "gcc_eh", kind = "static-nobundle")] +#[link(name = "pthread", kind = "static-nobundle")] +#[link(name = "gcc_s")] +extern "C" {} 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 new file mode 100644 index 0000000000000..f6adb6d76279d --- /dev/null +++ b/src/test/run-make-fulldeps/windows-binary-no-external-deps/Makefile @@ -0,0 +1,9 @@ +-include ../tools.mk + +# only-windows + +PATH=$(SYSTEMROOT)/system32 + +all: + $(RUSTC) hello.rs + $(TMPDIR)/hello.exe diff --git a/src/test/run-make-fulldeps/windows-binary-no-external-deps/hello.rs b/src/test/run-make-fulldeps/windows-binary-no-external-deps/hello.rs new file mode 100644 index 0000000000000..47ad8c634112b --- /dev/null +++ b/src/test/run-make-fulldeps/windows-binary-no-external-deps/hello.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello World!"); +}