rustc_target/spec/base/
windows_gnu.rs

1use std::borrow::Cow;
2
3use crate::spec::{
4    Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions,
5    add_link_args, crt_objects, cvs,
6};
7
8pub(crate) fn opts() -> TargetOptions {
9    let 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    );
18    add_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    );
29
30    // 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.
32    let 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    ];
51    let mut late_link_args =
52        TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs);
53    add_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.
57    let dynamic_unwind_libs = &["-lgcc_s"];
58    let mut late_link_args_dynamic =
59        TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs);
60    add_link_args(
61        &mut late_link_args_dynamic,
62        LinkerFlavor::Gnu(Cc::Yes, Lld::No),
63        dynamic_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.
70    let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
71    let mut late_link_args_static =
72        TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs);
73    add_link_args(
74        &mut late_link_args_static,
75        LinkerFlavor::Gnu(Cc::Yes, Lld::No),
76        static_unwind_libs,
77    );
78
79    TargetOptions {
80        os: "windows".into(),
81        env: "gnu".into(),
82        vendor: "pc".into(),
83        // FIXME(#13846) this should be enabled for windows
84        function_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: cvs!["windows"],
92        is_like_windows: true,
93        allows_weak_linkage: false,
94        pre_link_args,
95        pre_link_objects: crt_objects::pre_mingw(),
96        post_link_objects: crt_objects::post_mingw(),
97        pre_link_objects_self_contained: crt_objects::pre_mingw_self_contained(),
98        post_link_objects_self_contained: crt_objects::post_mingw_self_contained(),
99        link_self_contained: LinkSelfContainedDefault::InferredForMingw,
100        late_link_args,
101        late_link_args_dynamic,
102        late_link_args_static,
103        abi_return_struct_as_int: true,
104        emit_debug_gdb_scripts: false,
105        requires_uwtable: true,
106        eh_frame_header: false,
107        debuginfo_kind: DebuginfoKind::Dwarf,
108        // FIXME(davidtwco): Support Split DWARF on Windows GNU - may require LLVM changes to
109        // output DWO, despite using DWARF, doesn't use ELF..
110        supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
111        ..Default::default()
112    }
113}