rustc_target: Some more tests and fixes for linker arguments · rust-lang/rust@456f65e (original) (raw)
1
1
`use super::super::*;
`
``
2
`+
use std::assert_matches::assert_matches;
`
2
3
``
3
4
`// Test target self-consistency and JSON encoding/decoding roundtrip.
`
4
5
`pub(super) fn test_target(target: Target) {
`
`@@ -14,35 +15,105 @@ impl Target {
`
14
15
`assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64");
`
15
16
`assert!(self.is_like_windows || !self.is_like_msvc);
`
16
17
``
17
``
`-
// Check that LLD with the given flavor is treated identically to the linker it emulates.
`
18
``
`-
// If your target really needs to deviate from the rules below, except it and document the
`
19
``
`-
// reasons.
`
20
``
`-
assert_eq!(
`
21
``
`-
self.linker_flavor == LinkerFlavor::Msvc
`
22
``
`-
|| self.linker_flavor == LinkerFlavor::Lld(LldFlavor::Link),
`
23
``
`-
self.lld_flavor == LldFlavor::Link,
`
24
``
`-
);
`
25
``
`-
assert_eq!(self.is_like_msvc, self.lld_flavor == LldFlavor::Link);
`
26
``
`-
for args in &[
`
``
18
`+
// Check that default linker flavor and lld flavor are compatible
`
``
19
`+
// with some other key properties.
`
``
20
`+
assert_eq!(self.is_like_osx, matches!(self.lld_flavor, LldFlavor::Ld64));
`
``
21
`+
assert_eq!(self.is_like_msvc, matches!(self.lld_flavor, LldFlavor::Link));
`
``
22
`+
assert_eq!(self.is_like_wasm, matches!(self.lld_flavor, LldFlavor::Wasm));
`
``
23
`+
assert_eq!(self.os == "l4re", matches!(self.linker_flavor, LinkerFlavor::L4Bender));
`
``
24
`+
assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::Em));
`
``
25
`+
assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::BpfLinker));
`
``
26
`+
assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::PtxLinker));
`
``
27
+
``
28
`+
for args in [
`
27
29
`&self.pre_link_args,
`
28
30
`&self.late_link_args,
`
29
31
`&self.late_link_args_dynamic,
`
30
32
`&self.late_link_args_static,
`
31
33
`&self.post_link_args,
`
32
34
`] {
`
``
35
`+
for (&flavor, flavor_args) in args {
`
``
36
`+
assert!(!flavor_args.is_empty());
`
``
37
`+
// Check that flavors mentioned in link args are compatible with the default flavor.
`
``
38
`+
match (self.linker_flavor, self.lld_flavor) {
`
``
39
`+
(
`
``
40
`+
LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc,
`
``
41
`+
LldFlavor::Ld,
`
``
42
`+
) => {
`
``
43
`+
assert_matches!(
`
``
44
`+
flavor,
`
``
45
`+
LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc
`
``
46
`+
)
`
``
47
`+
}
`
``
48
`+
(LinkerFlavor::Gcc, LldFlavor::Ld64) => {
`
``
49
`+
assert_matches!(flavor, LinkerFlavor::Gcc)
`
``
50
`+
}
`
``
51
`+
(LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => {
`
``
52
`+
assert_matches!(
`
``
53
`+
flavor,
`
``
54
`+
LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link)
`
``
55
`+
)
`
``
56
`+
}
`
``
57
`+
(LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc, LldFlavor::Wasm) => {
`
``
58
`+
assert_matches!(
`
``
59
`+
flavor,
`
``
60
`+
LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc
`
``
61
`+
)
`
``
62
`+
}
`
``
63
`+
(LinkerFlavor::L4Bender, LldFlavor::Ld) => {
`
``
64
`+
assert_matches!(flavor, LinkerFlavor::L4Bender)
`
``
65
`+
}
`
``
66
`+
(LinkerFlavor::Em, LldFlavor::Wasm) => {
`
``
67
`+
assert_matches!(flavor, LinkerFlavor::Em)
`
``
68
`+
}
`
``
69
`+
(LinkerFlavor::BpfLinker, LldFlavor::Ld) => {
`
``
70
`+
assert_matches!(flavor, LinkerFlavor::BpfLinker)
`
``
71
`+
}
`
``
72
`+
(LinkerFlavor::PtxLinker, LldFlavor::Ld) => {
`
``
73
`+
assert_matches!(flavor, LinkerFlavor::PtxLinker)
`
``
74
`+
}
`
``
75
`+
flavors => unreachable!("unexpected flavor combination: {:?}", flavors),
`
``
76
`+
}
`
``
77
+
``
78
`+
// Check that link args for cc and non-cc versions of flavors are consistent.
`
``
79
`+
let check_noncc = |noncc_flavor| {
`
``
80
`+
if let Some(noncc_args) = args.get(&noncc_flavor) {
`
``
81
`+
for arg in flavor_args {
`
``
82
`+
if let Some(suffix) = arg.strip_prefix("-Wl,") {
`
``
83
`+
assert!(noncc_args.iter().any(|a| a == suffix));
`
``
84
`+
}
`
``
85
`+
}
`
``
86
`+
}
`
``
87
`+
};
`
``
88
`+
match self.linker_flavor {
`
``
89
`+
LinkerFlavor::Gcc => match self.lld_flavor {
`
``
90
`+
LldFlavor::Ld => {
`
``
91
`+
check_noncc(LinkerFlavor::Ld);
`
``
92
`+
check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));
`
``
93
`+
}
`
``
94
`+
LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),
`
``
95
`+
LldFlavor::Ld64 | LldFlavor::Link => {}
`
``
96
`+
},
`
``
97
`+
_ => {}
`
``
98
`+
}
`
``
99
`+
}
`
``
100
+
``
101
`+
// Check that link args for lld and non-lld versions of flavors are consistent.
`
``
102
`+
assert_eq!(args.get(&LinkerFlavor::Ld), args.get(&LinkerFlavor::Lld(LldFlavor::Ld)));
`
33
103
`assert_eq!(
`
34
104
` args.get(&LinkerFlavor::Msvc),
`
35
105
` args.get(&LinkerFlavor::Lld(LldFlavor::Link)),
`
36
106
`);
`
37
``
`-
if args.contains_key(&LinkerFlavor::Msvc) {
`
38
``
`-
assert_eq!(self.lld_flavor, LldFlavor::Link);
`
39
``
`-
}
`
40
107
`}
`
``
108
+
41
109
`assert!(
`
42
110
`(self.pre_link_objects_fallback.is_empty()
`
43
111
` && self.post_link_objects_fallback.is_empty())
`
44
112
` || self.crt_objects_fallback.is_some()
`
45
113
`);
`
``
114
+
``
115
`+
// If your target really needs to deviate from the rules below,
`
``
116
`+
// except it and document the reasons.
`
46
117
`// Keep the default "unknown" vendor instead.
`
47
118
`assert_ne!(self.vendor, "");
`
48
119
`if !self.can_use_os_unknown() {
`