1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
//! Object files providing support for basic runtime facilities and added to the produced binaries
//! at the start and at the end of linking.
//!
//! Table of CRT objects for popular toolchains.
//! The `crtx` ones are generally distributed with libc and the `begin/end` ones with gcc.
//! See <https://dev.gentoo.org/~vapier/crt.txt> for some more details.
//!
//! | Pre-link CRT objects | glibc | musl | bionic | mingw | wasi |
//! |----------------------|------------------------|------------------------|------------------|-------------------|--------------|
//! | dynamic-nopic-exe | crt1, crti, crtbegin | crt1, crti, crtbegin | crtbegin_dynamic | crt2, crtbegin | crt1 |
//! | dynamic-pic-exe | Scrt1, crti, crtbeginS | Scrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
//! | static-nopic-exe | crt1, crti, crtbeginT | crt1, crti, crtbegin | crtbegin_static | crt2, crtbegin | crt1 |
//! | static-pic-exe | rcrt1, crti, crtbeginS | rcrt1, crti, crtbeginS | crtbegin_dynamic | crt2, crtbegin | crt1 |
//! | dynamic-dylib | crti, crtbeginS | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
//! | static-dylib (gcc) | crti, crtbeginT | crti, crtbeginS | crtbegin_so | dllcrt2, crtbegin | - |
//! | static-dylib (clang) | crti, crtbeginT | N/A | crtbegin_static | dllcrt2, crtbegin | - |
//! | wasi-reactor-exe | N/A | N/A | N/A | N/A | crt1-reactor |
//!
//! | Post-link CRT objects | glibc | musl | bionic | mingw | wasi |
//! |-----------------------|---------------|---------------|----------------|--------|------|
//! | dynamic-nopic-exe | crtend, crtn | crtend, crtn | crtend_android | crtend | - |
//! | dynamic-pic-exe | crtendS, crtn | crtendS, crtn | crtend_android | crtend | - |
//! | static-nopic-exe | crtend, crtn | crtend, crtn | crtend_android | crtend | - |
//! | static-pic-exe | crtendS, crtn | crtendS, crtn | crtend_android | crtend | - |
//! | dynamic-dylib | crtendS, crtn | crtendS, crtn | crtend_so | crtend | - |
//! | static-dylib (gcc) | crtend, crtn | crtendS, crtn | crtend_so | crtend | - |
//! | static-dylib (clang) | crtendS, crtn | N/A | crtend_so | crtend | - |
//!
//! Use cases for rustc linking the CRT objects explicitly:
//! - rustc needs to add its own Rust-specific objects (mingw is the example)
//! - gcc wrapper cannot be used for some reason and linker like ld or lld is used directly.
//! - gcc wrapper pulls wrong CRT objects (e.g. from glibc when we are targeting musl).
//!
//! In general it is preferable to rely on the target's native toolchain to pull the objects.
//! However, for some targets (musl, mingw) rustc historically provides a more self-contained
//! installation not requiring users to install the native target's toolchain.
//! In that case rustc distributes the objects as a part of the target's Rust toolchain
//! and falls back to linking with them manually.
//! Unlike native toolchains, rustc only currently adds the libc's objects during linking,
//! but not gcc's. As a result rustc cannot link with C++ static libraries (#36710)
//! when linking in self-contained mode.
use crate::spec::LinkOutputKind;
use std::borrow::Cow;
use std::collections::BTreeMap;
pub type CrtObjects = BTreeMap<LinkOutputKind, Vec<Cow<'static, str>>>;
pub(super) fn new(obj_table: &[(LinkOutputKind, &[&'static str])]) -> CrtObjects {
obj_table.iter().map(|(z, k)| (*z, k.iter().map(|b| (*b).into()).collect())).collect()
}
pub(super) fn all(obj: &'static str) -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &[obj]),
(LinkOutputKind::DynamicPicExe, &[obj]),
(LinkOutputKind::StaticNoPicExe, &[obj]),
(LinkOutputKind::StaticPicExe, &[obj]),
(LinkOutputKind::DynamicDylib, &[obj]),
(LinkOutputKind::StaticDylib, &[obj]),
])
}
pub(super) fn pre_musl_self_contained() -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crt1.o", "crti.o", "crtbegin.o"]),
(LinkOutputKind::DynamicPicExe, &["Scrt1.o", "crti.o", "crtbeginS.o"]),
(LinkOutputKind::StaticNoPicExe, &["crt1.o", "crti.o", "crtbegin.o"]),
(LinkOutputKind::StaticPicExe, &["rcrt1.o", "crti.o", "crtbeginS.o"]),
(LinkOutputKind::DynamicDylib, &["crti.o", "crtbeginS.o"]),
(LinkOutputKind::StaticDylib, &["crti.o", "crtbeginS.o"]),
])
}
pub(super) fn post_musl_self_contained() -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crtend.o", "crtn.o"]),
(LinkOutputKind::DynamicPicExe, &["crtendS.o", "crtn.o"]),
(LinkOutputKind::StaticNoPicExe, &["crtend.o", "crtn.o"]),
(LinkOutputKind::StaticPicExe, &["crtendS.o", "crtn.o"]),
(LinkOutputKind::DynamicDylib, &["crtendS.o", "crtn.o"]),
(LinkOutputKind::StaticDylib, &["crtendS.o", "crtn.o"]),
])
}
pub(super) fn pre_mingw_self_contained() -> CrtObjects {
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crt2.o", "rsbegin.o"]),
(LinkOutputKind::DynamicPicExe, &["crt2.o", "rsbegin.o"]),
(LinkOutputKind::StaticNoPicExe, &["crt2.o", "rsbegin.o"]),
(LinkOutputKind::StaticPicExe, &["crt2.o", "rsbegin.o"]),
(LinkOutputKind::DynamicDylib, &["dllcrt2.o", "rsbegin.o"]),
(LinkOutputKind::StaticDylib, &["dllcrt2.o", "rsbegin.o"]),
])
}
pub(super) fn post_mingw_self_contained() -> CrtObjects {
all("rsend.o")
}
pub(super) fn pre_mingw() -> CrtObjects {
all("rsbegin.o")
}
pub(super) fn post_mingw() -> CrtObjects {
all("rsend.o")
}
pub(super) fn pre_wasi_self_contained() -> CrtObjects {
// Use crt1-command.o instead of crt1.o to enable support for new-style
// commands. See https://reviews.llvm.org/D81689 for more info.
new(&[
(LinkOutputKind::DynamicNoPicExe, &["crt1-command.o"]),
(LinkOutputKind::DynamicPicExe, &["crt1-command.o"]),
(LinkOutputKind::StaticNoPicExe, &["crt1-command.o"]),
(LinkOutputKind::StaticPicExe, &["crt1-command.o"]),
(LinkOutputKind::WasiReactorExe, &["crt1-reactor.o"]),
])
}
pub(super) fn post_wasi_self_contained() -> CrtObjects {
new(&[])
}
|