]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_target/src/spec/crt_objects.rs
Auto merge of #94566 - yanganto:show-ignore-message, r=m-ou-se
[rust.git] / compiler / rustc_target / src / spec / crt_objects.rs
1 //! Object files providing support for basic runtime facilities and added to the produced binaries
2 //! at the start and at the end of linking.
3 //!
4 //! Table of CRT objects for popular toolchains.
5 //! The `crtx` ones are generally distributed with libc and the `begin/end` ones with gcc.
6 //! See <https://dev.gentoo.org/~vapier/crt.txt> for some more details.
7 //!
8 //! | Pre-link CRT objects | glibc                  | musl                   | bionic           | mingw             | wasi         |
9 //! |----------------------|------------------------|------------------------|------------------|-------------------|--------------|
10 //! | dynamic-nopic-exe    | crt1, crti, crtbegin   | crt1, crti, crtbegin   | crtbegin_dynamic | crt2, crtbegin    | crt1         |
11 //! | dynamic-pic-exe      | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin    | crt1         |
12 //! | static-nopic-exe     | crt1, crti, crtbeginT  | crt1, crti, crtbegin   | crtbegin_static  | crt2, crtbegin    | crt1         |
13 //! | static-pic-exe       | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin    | crt1         |
14 //! | dynamic-dylib        | crti, crtbeginS        | crti, crtbeginS        | crtbegin_so      | dllcrt2, crtbegin | -            |
15 //! | static-dylib (gcc)   | crti, crtbeginT        | crti, crtbeginS        | crtbegin_so      | dllcrt2, crtbegin | -            |
16 //! | static-dylib (clang) | crti, crtbeginT        | N/A                    | crtbegin_static  | dllcrt2, crtbegin | -            |
17 //! | wasi-reactor-exe     | N/A                    | N/A                    | N/A              | N/A               | crt1-reactor |
18 //!
19 //! | Post-link CRT objects | glibc         | musl          | bionic         | mingw  | wasi |
20 //! |-----------------------|---------------|---------------|----------------|--------|------|
21 //! | dynamic-nopic-exe     | crtend, crtn  | crtend, crtn  | crtend_android | crtend | -    |
22 //! | dynamic-pic-exe       | crtendS, crtn | crtendS, crtn | crtend_android | crtend | -    |
23 //! | static-nopic-exe      | crtend, crtn  | crtend, crtn  | crtend_android | crtend | -    |
24 //! | static-pic-exe        | crtendS, crtn | crtendS, crtn | crtend_android | crtend | -    |
25 //! | dynamic-dylib         | crtendS, crtn | crtendS, crtn | crtend_so      | crtend | -    |
26 //! | static-dylib (gcc)    | crtend, crtn  | crtendS, crtn | crtend_so      | crtend | -    |
27 //! | static-dylib (clang)  | crtendS, crtn | N/A           | crtend_so      | crtend | -    |
28 //!
29 //! Use cases for rustc linking the CRT objects explicitly:
30 //!     - rustc needs to add its own Rust-specific objects (mingw is the example)
31 //!     - gcc wrapper cannot be used for some reason and linker like ld or lld is used directly.
32 //!     - gcc wrapper pulls wrong CRT objects (e.g. from glibc when we are targeting musl).
33 //!
34 //! In general it is preferable to rely on the target's native toolchain to pull the objects.
35 //! However, for some targets (musl, mingw) rustc historically provides a more self-contained
36 //! installation not requiring users to install the native target's toolchain.
37 //! In that case rustc distributes the objects as a part of the target's Rust toolchain
38 //! and falls back to linking with them manually.
39 //! Unlike native toolchains, rustc only currently adds the libc's objects during linking,
40 //! but not gcc's. As a result rustc cannot link with C++ static libraries (#36710)
41 //! when linking in self-contained mode.
42
43 use crate::spec::LinkOutputKind;
44 use rustc_serialize::json::{Json, ToJson};
45 use std::collections::BTreeMap;
46 use std::str::FromStr;
47
48 pub type CrtObjects = BTreeMap<LinkOutputKind, Vec<String>>;
49
50 pub(super) fn new(obj_table: &[(LinkOutputKind, &[&str])]) -> CrtObjects {
51     obj_table.iter().map(|(z, k)| (*z, k.iter().map(|b| b.to_string()).collect())).collect()
52 }
53
54 pub(super) fn all(obj: &str) -> CrtObjects {
55     new(&[
56         (LinkOutputKind::DynamicNoPicExe, &[obj]),
57         (LinkOutputKind::DynamicPicExe, &[obj]),
58         (LinkOutputKind::StaticNoPicExe, &[obj]),
59         (LinkOutputKind::StaticPicExe, &[obj]),
60         (LinkOutputKind::DynamicDylib, &[obj]),
61         (LinkOutputKind::StaticDylib, &[obj]),
62     ])
63 }
64
65 pub(super) fn pre_musl_fallback() -> CrtObjects {
66     new(&[
67         (LinkOutputKind::DynamicNoPicExe, &["crt1.o", "crti.o", "crtbegin.o"]),
68         (LinkOutputKind::DynamicPicExe, &["Scrt1.o", "crti.o", "crtbeginS.o"]),
69         (LinkOutputKind::StaticNoPicExe, &["crt1.o", "crti.o", "crtbegin.o"]),
70         (LinkOutputKind::StaticPicExe, &["rcrt1.o", "crti.o", "crtbeginS.o"]),
71         (LinkOutputKind::DynamicDylib, &["crti.o", "crtbeginS.o"]),
72         (LinkOutputKind::StaticDylib, &["crti.o", "crtbeginS.o"]),
73     ])
74 }
75
76 pub(super) fn post_musl_fallback() -> CrtObjects {
77     new(&[
78         (LinkOutputKind::DynamicNoPicExe, &["crtend.o", "crtn.o"]),
79         (LinkOutputKind::DynamicPicExe, &["crtendS.o", "crtn.o"]),
80         (LinkOutputKind::StaticNoPicExe, &["crtend.o", "crtn.o"]),
81         (LinkOutputKind::StaticPicExe, &["crtendS.o", "crtn.o"]),
82         (LinkOutputKind::DynamicDylib, &["crtendS.o", "crtn.o"]),
83         (LinkOutputKind::StaticDylib, &["crtendS.o", "crtn.o"]),
84     ])
85 }
86
87 pub(super) fn pre_mingw_fallback() -> CrtObjects {
88     new(&[
89         (LinkOutputKind::DynamicNoPicExe, &["crt2.o", "rsbegin.o"]),
90         (LinkOutputKind::DynamicPicExe, &["crt2.o", "rsbegin.o"]),
91         (LinkOutputKind::StaticNoPicExe, &["crt2.o", "rsbegin.o"]),
92         (LinkOutputKind::StaticPicExe, &["crt2.o", "rsbegin.o"]),
93         (LinkOutputKind::DynamicDylib, &["dllcrt2.o", "rsbegin.o"]),
94         (LinkOutputKind::StaticDylib, &["dllcrt2.o", "rsbegin.o"]),
95     ])
96 }
97
98 pub(super) fn post_mingw_fallback() -> CrtObjects {
99     all("rsend.o")
100 }
101
102 pub(super) fn pre_mingw() -> CrtObjects {
103     all("rsbegin.o")
104 }
105
106 pub(super) fn post_mingw() -> CrtObjects {
107     all("rsend.o")
108 }
109
110 pub(super) fn pre_wasi_fallback() -> CrtObjects {
111     // Use crt1-command.o instead of crt1.o to enable support for new-style
112     // commands. See https://reviews.llvm.org/D81689 for more info.
113     new(&[
114         (LinkOutputKind::DynamicNoPicExe, &["crt1-command.o"]),
115         (LinkOutputKind::DynamicPicExe, &["crt1-command.o"]),
116         (LinkOutputKind::StaticNoPicExe, &["crt1-command.o"]),
117         (LinkOutputKind::StaticPicExe, &["crt1-command.o"]),
118         (LinkOutputKind::WasiReactorExe, &["crt1-reactor.o"]),
119     ])
120 }
121
122 pub(super) fn post_wasi_fallback() -> CrtObjects {
123     new(&[])
124 }
125
126 /// Which logic to use to determine whether to fall back to the "self-contained" mode or not.
127 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
128 pub enum CrtObjectsFallback {
129     Musl,
130     Mingw,
131     Wasm,
132 }
133
134 impl FromStr for CrtObjectsFallback {
135     type Err = ();
136
137     fn from_str(s: &str) -> Result<CrtObjectsFallback, ()> {
138         Ok(match s {
139             "musl" => CrtObjectsFallback::Musl,
140             "mingw" => CrtObjectsFallback::Mingw,
141             "wasm" => CrtObjectsFallback::Wasm,
142             _ => return Err(()),
143         })
144     }
145 }
146
147 impl ToJson for CrtObjectsFallback {
148     fn to_json(&self) -> Json {
149         match *self {
150             CrtObjectsFallback::Musl => "musl",
151             CrtObjectsFallback::Mingw => "mingw",
152             CrtObjectsFallback::Wasm => "wasm",
153         }
154         .to_json()
155     }
156 }