1use std::fmt::Display;
2
3use serde::{Deserialize, Serialize};
4use turbo_tasks::{NonLocalValue, Vc, trace::TraceRawVcs};
5
6#[turbo_tasks::value(shared, serialization = "auto_for_input")]
7#[derive(Hash, Debug, Copy, Clone)]
8pub struct CompileTarget {
9 pub arch: Arch,
11 pub platform: Platform,
13 pub endianness: Endianness,
15 pub libc: Libc,
16}
17
18impl Default for CompileTarget {
19 fn default() -> Self {
20 CompileTarget {
21 arch: Arch::Unknown,
22 platform: Platform::Unknown,
23 endianness: Endianness::Big,
24 libc: Libc::Unknown,
25 }
26 }
27}
28
29#[turbo_tasks::value_impl]
30impl CompileTarget {
31 #[turbo_tasks::function]
32 pub fn current() -> Vc<Self> {
33 Self::cell(Self::current_raw())
34 }
35
36 #[turbo_tasks::function]
37 pub fn unknown() -> Vc<Self> {
38 Self::cell(CompileTarget {
39 arch: Arch::Unknown,
40 platform: Platform::Unknown,
41 endianness: Endianness::Big,
42 libc: Libc::Unknown,
43 })
44 }
45}
46
47impl Display for CompileTarget {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 write!(f, "{self:?}")
50 }
51}
52
53impl CompileTarget {
54 pub fn current_raw() -> Self {
55 CompileTarget {
56 arch: CompileTarget::current_arch(),
57 platform: CompileTarget::current_platform(),
58 endianness: CompileTarget::current_endianness(),
59 libc: CompileTarget::current_libc(),
60 }
61 }
62
63 pub fn dylib_ext(&self) -> &'static str {
65 let platform = self.platform;
66 match platform {
67 Platform::Win32 => ".dll",
68 Platform::Darwin => ".dylib",
69 _ => ".so",
70 }
71 }
72
73 fn current_endianness() -> Endianness {
74 #[cfg(target_endian = "little")]
75 {
76 Endianness::Little
77 }
78 #[cfg(target_endian = "big")]
79 {
80 Endianness::Big
81 }
82 }
83
84 #[allow(unreachable_code)]
85 fn current_arch() -> Arch {
86 #[cfg(target_arch = "x86")]
87 {
88 return Arch::Ia32;
89 }
90 #[cfg(target_arch = "x86_64")]
91 {
92 return Arch::X64;
93 }
94 #[cfg(target_arch = "arm")]
95 {
96 return Arch::Arm;
97 }
98 #[cfg(target_arch = "aarch64")]
99 {
100 return Arch::Arm64;
101 }
102 #[cfg(target_arch = "mips")]
103 {
104 return Arch::Mips;
105 }
106 #[cfg(target_arch = "powerpc")]
107 {
108 return Arch::Ppc;
109 }
110 #[cfg(target_arch = "powerpc64")]
111 {
112 return Arch::Ppc64;
113 }
114 #[cfg(target_arch = "s390x")]
115 {
116 return Arch::S390x;
117 }
118 Arch::Unknown
119 }
120
121 #[allow(unreachable_code)]
122 fn current_platform() -> Platform {
123 #[cfg(target_os = "windows")]
124 {
125 return Platform::Win32;
126 }
127 #[cfg(target_os = "linux")]
128 {
129 return Platform::Linux;
130 }
131 #[cfg(target_os = "macos")]
132 {
133 return Platform::Darwin;
134 }
135 #[cfg(target_os = "android")]
136 {
137 return Platform::Android;
138 }
139 #[cfg(target_os = "freebsd")]
140 {
141 return Platform::Freebsd;
142 }
143 #[cfg(target_os = "openbsd")]
144 {
145 return Platform::Openbsd;
146 }
147 #[cfg(target_os = "solaris")]
148 {
149 return Platform::Sunos;
150 }
151 Platform::Unknown
152 }
153
154 #[allow(unreachable_code)]
155 fn current_libc() -> Libc {
156 #[cfg(target_env = "gnu")]
157 {
158 return Libc::Glibc;
159 }
160 #[cfg(target_env = "musl")]
161 {
162 return Libc::Musl;
163 }
164 #[cfg(target_env = "msvc")]
165 {
166 return Libc::Msvc;
167 }
168 #[cfg(target_env = "sgx")]
169 {
170 return Libc::Sgx;
171 }
172 Libc::Unknown
173 }
174}
175
176#[derive(
177 PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, Serialize, Deserialize, NonLocalValue,
178)]
179#[repr(u8)]
180#[non_exhaustive]
181pub enum Arch {
182 Arm,
183 Arm64,
184 Ia32,
185 Mips,
186 Mipsel,
187 Ppc,
188 Ppc64,
189 S390,
190 S390x,
191 X64,
192 Unknown,
193}
194
195impl Arch {
196 pub fn as_str(&self) -> &'static str {
197 match self {
198 Self::Arm => "arm",
199 Self::Arm64 => "arm64",
200 Self::Ia32 => "ia32",
201 Self::Mips => "mips",
202 Self::Mipsel => "mipsel",
203 Self::Ppc => "ppc",
204 Self::Ppc64 => "ppc64",
205 Self::S390 => "s390",
206 Self::S390x => "s390x",
207 Self::X64 => "x64",
208 Self::Unknown => "unknown",
209 }
210 }
211}
212
213impl Display for Arch {
214 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215 f.write_str(self.as_str())
216 }
217}
218
219#[derive(
220 PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, Serialize, Deserialize, NonLocalValue,
221)]
222#[repr(u8)]
223#[non_exhaustive]
224pub enum Platform {
225 Aix,
226 Android,
227 Darwin,
228 Freebsd,
229 Linux,
230 Openbsd,
231 Sunos,
232 Win32,
233 Unknown,
234}
235
236impl Platform {
237 pub fn as_str(&self) -> &'static str {
238 match self {
239 Self::Aix => "aix",
240 Self::Android => "android",
241 Self::Darwin => "darwin",
242 Self::Freebsd => "freebsd",
243 Self::Linux => "linux",
244 Self::Openbsd => "openbsd",
245 Self::Sunos => "sunos",
246 Self::Win32 => "win32",
247 Self::Unknown => "unknown",
248 }
249 }
250}
251
252impl Display for Platform {
253 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
254 f.write_str(self.as_str())
255 }
256}
257
258#[derive(
259 PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, Serialize, Deserialize, NonLocalValue,
260)]
261#[repr(u8)]
262pub enum Endianness {
263 Big,
264 Little,
265}
266
267impl Endianness {
268 pub fn as_str(&self) -> &'static str {
269 match self {
270 Self::Big => "BE",
271 Self::Little => "LE",
272 }
273 }
274}
275
276impl Display for Endianness {
277 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
278 f.write_str(self.as_str())
279 }
280}
281
282#[derive(
283 PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, Serialize, Deserialize, NonLocalValue,
284)]
285#[repr(u8)]
286pub enum Libc {
287 Glibc,
288 Musl,
289 Msvc,
290 Unknown,
291}
292
293impl Libc {
294 pub fn as_str(&self) -> &'static str {
295 match self {
296 Self::Glibc => "glibc",
297 Self::Musl => "musl",
298 Self::Msvc => "msvc",
299 Self::Unknown => "unknown",
300 }
301 }
302}
303
304impl Display for Libc {
305 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
306 f.write_str(self.as_str())
307 }
308}