]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_target/src/spec/crt_objects.rs
New upstream version 1.51.0+dfsg1
[rustc.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"]),
68 (LinkOutputKind::DynamicPicExe, &["Scrt1.o", "crti.o"]),
69 (LinkOutputKind::StaticNoPicExe, &["crt1.o", "crti.o"]),
70 (LinkOutputKind::StaticPicExe, &["rcrt1.o", "crti.o"]),
71 (LinkOutputKind::DynamicDylib, &["crti.o"]),
72 (LinkOutputKind::StaticDylib, &["crti.o"]),
73 ])
74 }
75
76 pub(super) fn post_musl_fallback() -> CrtObjects {
77 all("crtn.o")
78 }
79
80 pub(super) fn pre_mingw_fallback() -> CrtObjects {
81 new(&[
82 (LinkOutputKind::DynamicNoPicExe, &["crt2.o", "rsbegin.o"]),
83 (LinkOutputKind::DynamicPicExe, &["crt2.o", "rsbegin.o"]),
84 (LinkOutputKind::StaticNoPicExe, &["crt2.o", "rsbegin.o"]),
85 (LinkOutputKind::StaticPicExe, &["crt2.o", "rsbegin.o"]),
86 (LinkOutputKind::DynamicDylib, &["dllcrt2.o", "rsbegin.o"]),
87 (LinkOutputKind::StaticDylib, &["dllcrt2.o", "rsbegin.o"]),
88 ])
89 }
90
91 pub(super) fn post_mingw_fallback() -> CrtObjects {
92 all("rsend.o")
93 }
94
95 pub(super) fn pre_mingw() -> CrtObjects {
96 all("rsbegin.o")
97 }
98
99 pub(super) fn post_mingw() -> CrtObjects {
100 all("rsend.o")
101 }
102
103 pub(super) fn pre_wasi_fallback() -> CrtObjects {
104 new(&[
105 (LinkOutputKind::DynamicNoPicExe, &["crt1.o"]),
106 (LinkOutputKind::DynamicPicExe, &["crt1.o"]),
107 (LinkOutputKind::StaticNoPicExe, &["crt1.o"]),
108 (LinkOutputKind::StaticPicExe, &["crt1.o"]),
109 (LinkOutputKind::WasiReactorExe, &["crt1-reactor.o"]),
110 ])
111 }
112
113 pub(super) fn post_wasi_fallback() -> CrtObjects {
114 new(&[])
115 }
116
117 /// Which logic to use to determine whether to fall back to the "self-contained" mode or not.
118 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
119 pub enum CrtObjectsFallback {
120 Musl,
121 Mingw,
122 Wasm,
123 }
124
125 impl FromStr for CrtObjectsFallback {
126 type Err = ();
127
128 fn from_str(s: &str) -> Result<CrtObjectsFallback, ()> {
129 Ok(match s {
130 "musl" => CrtObjectsFallback::Musl,
131 "mingw" => CrtObjectsFallback::Mingw,
132 "wasm" => CrtObjectsFallback::Wasm,
133 _ => return Err(()),
134 })
135 }
136 }
137
138 impl ToJson for CrtObjectsFallback {
139 fn to_json(&self) -> Json {
140 match *self {
141 CrtObjectsFallback::Musl => "musl",
142 CrtObjectsFallback::Mingw => "mingw",
143 CrtObjectsFallback::Wasm => "wasm",
144 }
145 .to_json()
146 }
147 }