diff --git a/src/librustc_target/spec/i686_pc_windows_gnu.rs b/src/librustc_target/spec/i686_pc_windows_gnu.rs index d12afe5a40b..33c9008bb14 100644 --- a/src/librustc_target/spec/i686_pc_windows_gnu.rs +++ b/src/librustc_target/spec/i686_pc_windows_gnu.rs @@ -1,8 +1,10 @@ -use crate::spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_gnu_base::opts(); base.cpu = "pentium4".to_string(); + base.pre_link_args + .insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".to_string(), "i386pe".to_string()]); base.max_atomic_width = Some(64); base.eliminate_frame_pointer = false; // Required for backtraces base.linker = Some("i686-w64-mingw32-gcc".to_string()); diff --git a/src/librustc_target/spec/i686_uwp_windows_gnu.rs b/src/librustc_target/spec/i686_uwp_windows_gnu.rs index 4e582fb8c63..1c6d2e061bc 100644 --- a/src/librustc_target/spec/i686_uwp_windows_gnu.rs +++ b/src/librustc_target/spec/i686_uwp_windows_gnu.rs @@ -1,8 +1,10 @@ -use crate::spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_uwp_gnu_base::opts(); base.cpu = "pentium4".to_string(); + base.pre_link_args + .insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".to_string(), "i386pe".to_string()]); base.max_atomic_width = Some(64); base.eliminate_frame_pointer = false; // Required for backtraces diff --git a/src/librustc_target/spec/windows_gnu_base.rs b/src/librustc_target/spec/windows_gnu_base.rs index 69236e98e58..a864918655f 100644 --- a/src/librustc_target/spec/windows_gnu_base.rs +++ b/src/librustc_target/spec/windows_gnu_base.rs @@ -1,5 +1,5 @@ use crate::spec::crt_objects::{self, CrtObjectsFallback}; -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; pub fn opts() -> TargetOptions { let mut pre_link_args = LinkArgs::new(); @@ -19,51 +19,48 @@ pub fn opts() -> TargetOptions { 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. - late_link_args.insert( - LinkerFlavor::Gcc, - vec![ - "-lmsvcrt".to_string(), - "-lmingwex".to_string(), - "-lmingw32".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 - // that are required from functions in msvcrt in certain cases. For example - // `_fmode` that is used by an implementation of `__p__fmode` in x86_64. - // The library is purposely listed twice to fix that. - // - // See https://github.com/rust-lang/rust/pull/47483 for some more details. - "-lmsvcrt".to_string(), - "-luser32".to_string(), - "-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_eh".to_string(), - "-l:libpthread.a".to_string(), - "-lgcc".to_string(), - // libpthread depends on libmsvcrt, so we need to link it *again*. - "-lmsvcrt".to_string(), - "-lkernel32".to_string(), - ], - ); + let mingw_libs = vec![ + "-lmsvcrt".to_string(), + "-lmingwex".to_string(), + "-lmingw32".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 + // that are required from functions in msvcrt in certain cases. For example + // `_fmode` that is used by an implementation of `__p__fmode` in x86_64. + // The library is purposely listed twice to fix that. + // + // See https://github.com/rust-lang/rust/pull/47483 for some more details. + "-lmsvcrt".to_string(), + "-luser32".to_string(), + "-lkernel32".to_string(), + ]; + 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(), + "-lgcc".to_string(), + "-lkernel32".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(), + "-lgcc".to_string(), + // libpthread depends on libmsvcrt, so we need to link it *again*. + "-lmsvcrt".to_string(), + "-lkernel32".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 { // FIXME(#13846) this should be enabled for windows diff --git a/src/librustc_target/spec/windows_uwp_gnu_base.rs b/src/librustc_target/spec/windows_uwp_gnu_base.rs index e12a37144da..fd55a0fc6a1 100644 --- a/src/librustc_target/spec/windows_uwp_gnu_base.rs +++ b/src/librustc_target/spec/windows_uwp_gnu_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; pub fn opts() -> TargetOptions { let base = super::windows_gnu_base::opts(); @@ -8,22 +8,21 @@ pub fn opts() -> TargetOptions { let mut late_link_args = LinkArgs::new(); let late_link_args_dynamic = LinkArgs::new(); let late_link_args_static = LinkArgs::new(); - late_link_args.insert( - LinkerFlavor::Gcc, - vec![ - //"-lwinstorecompat".to_string(), - //"-lmingwex".to_string(), - //"-lwinstorecompat".to_string(), - "-lwinstorecompat".to_string(), - "-lruntimeobject".to_string(), - "-lsynchronization".to_string(), - "-lvcruntime140_app".to_string(), - "-lucrt".to_string(), - "-lwindowsapp".to_string(), - "-lmingwex".to_string(), - "-lmingw32".to_string(), - ], - ); + let mingw_libs = vec![ + //"-lwinstorecompat".to_string(), + //"-lmingwex".to_string(), + //"-lwinstorecompat".to_string(), + "-lwinstorecompat".to_string(), + "-lruntimeobject".to_string(), + "-lsynchronization".to_string(), + "-lvcruntime140_app".to_string(), + "-lucrt".to_string(), + "-lwindowsapp".to_string(), + "-lmingwex".to_string(), + "-lmingw32".to_string(), + ]; + late_link_args.insert(LinkerFlavor::Gcc, mingw_libs.clone()); + late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs.clone()); TargetOptions { executables: false, diff --git a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs index eb97fa56814..99af483f1d4 100644 --- a/src/librustc_target/spec/x86_64_pc_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_pc_windows_gnu.rs @@ -1,9 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args + .insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".to_string(), "i386pep".to_string()]); base.max_atomic_width = Some(64); base.linker = Some("x86_64-w64-mingw32-gcc".to_string()); diff --git a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs index ad6002f6b89..3bd18f23f6f 100644 --- a/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs +++ b/src/librustc_target/spec/x86_64_uwp_windows_gnu.rs @@ -1,9 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetResult}; +use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_uwp_gnu_base::opts(); base.cpu = "x86-64".to_string(); base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); + base.pre_link_args + .insert(LinkerFlavor::Lld(LldFlavor::Ld), vec!["-m".to_string(), "i386pep".to_string()]); base.max_atomic_width = Some(64); Ok(Target {