]>
Commit | Line | Data |
---|---|---|
ba9703b0 | 1 | use super::super::*; |
064997fb | 2 | use std::assert_matches::assert_matches; |
ba9703b0 | 3 | |
29967ef6 XL |
4 | // Test target self-consistency and JSON encoding/decoding roundtrip. |
5 | pub(super) fn test_target(target: Target) { | |
6 | target.check_consistency(); | |
136023e0 | 7 | assert_eq!(Target::from_json(target.to_json()).map(|(j, _)| j), Ok(target)); |
ba9703b0 XL |
8 | } |
9 | ||
10 | impl Target { | |
11 | fn check_consistency(&self) { | |
923072b8 FG |
12 | assert_eq!(self.is_like_osx, self.vendor == "apple"); |
13 | assert_eq!(self.is_like_solaris, self.os == "solaris" || self.os == "illumos"); | |
14 | assert_eq!(self.is_like_windows, self.os == "windows" || self.os == "uefi"); | |
15 | assert_eq!(self.is_like_wasm, self.arch == "wasm32" || self.arch == "wasm64"); | |
fc512014 | 16 | assert!(self.is_like_windows || !self.is_like_msvc); |
923072b8 | 17 | |
064997fb FG |
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 [ | |
29967ef6 XL |
29 | &self.pre_link_args, |
30 | &self.late_link_args, | |
31 | &self.late_link_args_dynamic, | |
32 | &self.late_link_args_static, | |
33 | &self.post_link_args, | |
ba9703b0 | 34 | ] { |
064997fb FG |
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!( | |
50 | flavor, | |
51 | LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Gcc | |
52 | ) | |
53 | } | |
54 | (LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => { | |
55 | assert_matches!( | |
56 | flavor, | |
57 | LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link) | |
58 | ) | |
59 | } | |
60 | (LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc, LldFlavor::Wasm) => { | |
61 | assert_matches!( | |
62 | flavor, | |
63 | LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc | |
64 | ) | |
65 | } | |
66 | (LinkerFlavor::L4Bender, LldFlavor::Ld) => { | |
67 | assert_matches!(flavor, LinkerFlavor::L4Bender) | |
68 | } | |
69 | (LinkerFlavor::Em, LldFlavor::Wasm) => { | |
70 | assert_matches!(flavor, LinkerFlavor::Em) | |
71 | } | |
72 | (LinkerFlavor::BpfLinker, LldFlavor::Ld) => { | |
73 | assert_matches!(flavor, LinkerFlavor::BpfLinker) | |
74 | } | |
75 | (LinkerFlavor::PtxLinker, LldFlavor::Ld) => { | |
76 | assert_matches!(flavor, LinkerFlavor::PtxLinker) | |
77 | } | |
78 | flavors => unreachable!("unexpected flavor combination: {:?}", flavors), | |
79 | } | |
80 | ||
81 | // Check that link args for cc and non-cc versions of flavors are consistent. | |
82 | let check_noncc = |noncc_flavor| { | |
83 | if let Some(noncc_args) = args.get(&noncc_flavor) { | |
84 | for arg in flavor_args { | |
85 | if let Some(suffix) = arg.strip_prefix("-Wl,") { | |
86 | assert!(noncc_args.iter().any(|a| a == suffix)); | |
87 | } | |
88 | } | |
89 | } | |
90 | }; | |
91 | match self.linker_flavor { | |
92 | LinkerFlavor::Gcc => match self.lld_flavor { | |
93 | LldFlavor::Ld => { | |
94 | check_noncc(LinkerFlavor::Ld); | |
95 | check_noncc(LinkerFlavor::Lld(LldFlavor::Ld)); | |
96 | } | |
97 | LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)), | |
98 | LldFlavor::Ld64 | LldFlavor::Link => {} | |
99 | }, | |
100 | _ => {} | |
101 | } | |
102 | } | |
103 | ||
104 | // Check that link args for lld and non-lld versions of flavors are consistent. | |
105 | assert_eq!(args.get(&LinkerFlavor::Ld), args.get(&LinkerFlavor::Lld(LldFlavor::Ld))); | |
ba9703b0 XL |
106 | assert_eq!( |
107 | args.get(&LinkerFlavor::Msvc), | |
108 | args.get(&LinkerFlavor::Lld(LldFlavor::Link)), | |
109 | ); | |
ba9703b0 | 110 | } |
064997fb | 111 | |
f035d41b | 112 | assert!( |
29967ef6 XL |
113 | (self.pre_link_objects_fallback.is_empty() |
114 | && self.post_link_objects_fallback.is_empty()) | |
115 | || self.crt_objects_fallback.is_some() | |
f035d41b | 116 | ); |
064997fb FG |
117 | |
118 | // If your target really needs to deviate from the rules below, | |
119 | // except it and document the reasons. | |
fc512014 XL |
120 | // Keep the default "unknown" vendor instead. |
121 | assert_ne!(self.vendor, ""); | |
122 | if !self.can_use_os_unknown() { | |
123 | // Keep the default "none" for bare metal targets instead. | |
124 | assert_ne!(self.os, "unknown"); | |
125 | } | |
126 | } | |
127 | ||
128 | // Add your target to the whitelist if it has `std` library | |
129 | // and you certainly want "unknown" for the OS name. | |
130 | fn can_use_os_unknown(&self) -> bool { | |
131 | self.llvm_target == "wasm32-unknown-unknown" | |
cdc7bbd5 | 132 | || self.llvm_target == "wasm64-unknown-unknown" |
fc512014 | 133 | || (self.env == "sgx" && self.vendor == "fortanix") |
ba9703b0 XL |
134 | } |
135 | } |