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