1use std::borrow::Cow;
23use crate::spec::{
4BinaryFormat, Cc, DebuginfoKind, Env, LinkSelfContainedDefault, LinkerFlavor, Lld, Os,
5SplitDebuginfo, TargetOptions, add_link_args, crt_objects, cvs,
6};
78pub(crate) fn opts() -> TargetOptions {
9let mut pre_link_args = TargetOptions::link_args(
10 LinkerFlavor::Gnu(Cc::No, Lld::No),
11&[
12// Enable ASLR
13"--dynamicbase",
14// ASLR will rebase it anyway so leaving that option enabled only leads to confusion
15"--disable-auto-image-base",
16 ],
17 );
18add_link_args(
19&mut pre_link_args,
20 LinkerFlavor::Gnu(Cc::Yes, Lld::No),
21&[
22// Tell GCC to avoid linker plugins, because we are not bundling
23 // them with Windows installer, and Rust does its own LTO anyways.
24"-fno-use-linker-plugin",
25"-Wl,--dynamicbase",
26"-Wl,--disable-auto-image-base",
27 ],
28 );
2930// Order of `late_link_args*` was found through trial and error to work with various
31 // mingw-w64 versions (not tested on the CI). It's expected to change from time to time.
32let mingw_libs = &[
33"-lmsvcrt",
34"-lmingwex",
35"-lmingw32",
36"-lgcc", // alas, mingw* libraries above depend on libgcc
37 // mingw's msvcrt is a weird hybrid import library and static library.
38 // And it seems that the linker fails to use import symbols from msvcrt
39 // that are required from functions in msvcrt in certain cases. For example
40 // `_fmode` that is used by an implementation of `__p__fmode` in x86_64.
41 // The library is purposely listed twice to fix that.
42 //
43 // See https://github.com/rust-lang/rust/pull/47483 for some more details.
44"-lmsvcrt",
45// Math functions missing in MSVCRT (they are present in UCRT) require
46 // this dependency cycle: `libmingwex.a` -> `libmsvcrt.a` -> `libmingwex.a`.
47"-lmingwex",
48"-luser32",
49"-lkernel32",
50 ];
51let mut late_link_args =
52TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
53add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs);
54// If any of our crates are dynamically linked then we need to use
55 // the shared libgcc_s-dw2-1.dll. This is required to support
56 // unwinding across DLL boundaries.
57let dynamic_unwind_libs = &["-lgcc_s"];
58let mut late_link_args_dynamic =
59TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs);
60add_link_args(
61&mut late_link_args_dynamic,
62 LinkerFlavor::Gnu(Cc::Yes, Lld::No),
63dynamic_unwind_libs,
64 );
65// If all of our crates are statically linked then we can get away
66 // with statically linking the libgcc unwinding code. This allows
67 // binaries to be redistributed without the libgcc_s-dw2-1.dll
68 // dependency, but unfortunately break unwinding across DLL
69 // boundaries when unwinding across FFI boundaries.
70let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
71let mut late_link_args_static =
72TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs);
73add_link_args(
74&mut late_link_args_static,
75 LinkerFlavor::Gnu(Cc::Yes, Lld::No),
76static_unwind_libs,
77 );
7879TargetOptions {
80 os: Os::Windows,
81 env: Env::Gnu,
82 vendor: "pc".into(),
83// FIXME(#13846) this should be enabled for windows
84function_sections: false,
85 linker: Some("gcc".into()),
86 dynamic_linking: true,
87 dll_tls_export: false,
88 dll_prefix: "".into(),
89 dll_suffix: ".dll".into(),
90 exe_suffix: ".exe".into(),
91 families: ::std::borrow::Cow::Borrowed(&[::std::borrow::Cow::Borrowed("windows")])cvs!["windows"],
92 is_like_windows: true,
93 binary_format: BinaryFormat::Coff,
94 allows_weak_linkage: false,
95pre_link_args,
96 pre_link_objects_self_contained: crt_objects::pre_mingw_self_contained(),
97 link_self_contained: LinkSelfContainedDefault::InferredForMingw,
98late_link_args,
99late_link_args_dynamic,
100late_link_args_static,
101 abi_return_struct_as_int: true,
102 emit_debug_gdb_scripts: false,
103 requires_uwtable: true,
104 eh_frame_header: false,
105 debuginfo_kind: DebuginfoKind::Dwarf,
106// FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
107 // output DWO, despite using DWARF, doesn't use ELF..
108supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
109 ..Default::default()
110 }
111}