diff options
Diffstat (limited to 'compiler/rustc_target/src/spec/windows_gnu_base.rs')
-rw-r--r-- | compiler/rustc_target/src/spec/windows_gnu_base.rs | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs new file mode 100644 index 000000000..90e0af3e3 --- /dev/null +++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs @@ -0,0 +1,91 @@ +use crate::spec::crt_objects::{self, CrtObjectsFallback}; +use crate::spec::{cvs, LinkerFlavor, TargetOptions}; + +pub fn opts() -> TargetOptions { + let mut pre_link_args = TargetOptions::link_args( + LinkerFlavor::Ld, + &[ + // Enable ASLR + "--dynamicbase", + // ASLR will rebase it anyway so leaving that option enabled only leads to confusion + "--disable-auto-image-base", + ], + ); + super::add_link_args( + &mut pre_link_args, + LinkerFlavor::Gcc, + &[ + // Tell GCC to avoid linker plugins, because we are not bundling + // them with Windows installer, and Rust does its own LTO anyways. + "-fno-use-linker-plugin", + "-Wl,--dynamicbase", + "-Wl,--disable-auto-image-base", + ], + ); + + // 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 = &[ + "-lmsvcrt", + "-lmingwex", + "-lmingw32", + "-lgcc", // alas, mingw* libraries above depend on libgcc + // 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", + "-luser32", + "-lkernel32", + ]; + let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs); + super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs); + // 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. + let dynamic_unwind_libs = &["-lgcc_s"]; + let mut late_link_args_dynamic = + TargetOptions::link_args(LinkerFlavor::Ld, dynamic_unwind_libs); + super::add_link_args(&mut late_link_args_dynamic, LinkerFlavor::Gcc, dynamic_unwind_libs); + // 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. + let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"]; + let mut late_link_args_static = TargetOptions::link_args(LinkerFlavor::Ld, static_unwind_libs); + super::add_link_args(&mut late_link_args_static, LinkerFlavor::Gcc, static_unwind_libs); + + TargetOptions { + os: "windows".into(), + env: "gnu".into(), + vendor: "pc".into(), + // FIXME(#13846) this should be enabled for windows + function_sections: false, + linker: Some("gcc".into()), + dynamic_linking: true, + dll_prefix: "".into(), + dll_suffix: ".dll".into(), + exe_suffix: ".exe".into(), + families: cvs!["windows"], + is_like_windows: true, + allows_weak_linkage: false, + pre_link_args, + pre_link_objects: crt_objects::pre_mingw(), + post_link_objects: crt_objects::post_mingw(), + pre_link_objects_fallback: crt_objects::pre_mingw_fallback(), + 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, + abi_return_struct_as_int: true, + emit_debug_gdb_scripts: false, + requires_uwtable: true, + eh_frame_header: false, + ..Default::default() + } +} |