1 | // This file defines all the identifier enums and target-aware logic. |
2 | |
3 | use crate::triple::{Endianness, PointerWidth, Triple}; |
4 | use alloc::borrow::Cow; |
5 | use alloc::boxed::Box; |
6 | use alloc::format; |
7 | use alloc::string::String; |
8 | use core::fmt; |
9 | use core::hash::{Hash, Hasher}; |
10 | use core::str::FromStr; |
11 | |
12 | /// The "architecture" field, which in some cases also specifies a specific |
13 | /// subarchitecture. |
14 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
15 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
16 | #[allow (missing_docs)] |
17 | pub enum Architecture { |
18 | Unknown, |
19 | Arm(ArmArchitecture), |
20 | AmdGcn, |
21 | Aarch64(Aarch64Architecture), |
22 | Asmjs, |
23 | Avr, |
24 | Bpfeb, |
25 | Bpfel, |
26 | Hexagon, |
27 | X86_32(X86_32Architecture), |
28 | M68k, |
29 | LoongArch64, |
30 | Mips32(Mips32Architecture), |
31 | Mips64(Mips64Architecture), |
32 | Msp430, |
33 | Nvptx64, |
34 | Pulley32, |
35 | Pulley64, |
36 | Pulley32be, |
37 | Pulley64be, |
38 | Powerpc, |
39 | Powerpc64, |
40 | Powerpc64le, |
41 | Riscv32(Riscv32Architecture), |
42 | Riscv64(Riscv64Architecture), |
43 | S390x, |
44 | Sparc, |
45 | Sparc64, |
46 | Sparcv9, |
47 | Wasm32, |
48 | Wasm64, |
49 | X86_64, |
50 | /// x86_64 target that only supports Haswell-compatible Intel chips. |
51 | X86_64h, |
52 | XTensa, |
53 | Clever(CleverArchitecture), |
54 | /// A software machine that produces zero-knowledge proofs of the execution. |
55 | /// |
56 | /// See https://wiki.polygon.technology/docs/category/zk-assembly/ |
57 | #[cfg (feature = "arch_zkasm" )] |
58 | ZkAsm, |
59 | } |
60 | |
61 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
62 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
63 | #[allow (missing_docs)] |
64 | pub enum ArmArchitecture { |
65 | Arm, // Generic arm |
66 | Armeb, |
67 | Armv4, |
68 | Armv4t, |
69 | Armv5t, |
70 | Armv5te, |
71 | Armv5tej, |
72 | Armv6, |
73 | Armv6j, |
74 | Armv6k, |
75 | Armv6z, |
76 | Armv6kz, |
77 | Armv6t2, |
78 | Armv6m, |
79 | Armv7, |
80 | Armv7a, |
81 | Armv7k, |
82 | Armv7ve, |
83 | Armv7m, |
84 | Armv7r, |
85 | Armv7s, |
86 | Armv8, |
87 | Armv8a, |
88 | Armv8_1a, |
89 | Armv8_2a, |
90 | Armv8_3a, |
91 | Armv8_4a, |
92 | Armv8_5a, |
93 | Armv8mBase, |
94 | Armv8mMain, |
95 | Armv8r, |
96 | |
97 | Armebv7r, |
98 | |
99 | Thumbeb, |
100 | Thumbv4t, |
101 | Thumbv5te, |
102 | Thumbv6m, |
103 | Thumbv7a, |
104 | Thumbv7em, |
105 | Thumbv7m, |
106 | Thumbv7neon, |
107 | Thumbv8mBase, |
108 | Thumbv8mMain, |
109 | } |
110 | |
111 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
112 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
113 | #[allow (missing_docs)] |
114 | pub enum Aarch64Architecture { |
115 | Aarch64, |
116 | Aarch64be, |
117 | } |
118 | |
119 | // #[cfg_attr(feature = "rust_1_40", non_exhaustive)] |
120 | // #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] |
121 | // #[allow(missing_docs)] |
122 | // pub enum ArmFpu { |
123 | // Vfp, |
124 | // Vfpv2, |
125 | // Vfpv3, |
126 | // Vfpv3Fp16, |
127 | // Vfpv3Xd, |
128 | // Vfpv3XdFp16, |
129 | // Neon, |
130 | // NeonVfpv3, |
131 | // NeonVfpv4, |
132 | // Vfpv4, |
133 | // Vfpv4D16, |
134 | // Fpv4SpD16, |
135 | // Fpv5SpD16, |
136 | // Fpv5D16, |
137 | // FpArmv8, |
138 | // NeonFpArmv8, |
139 | // CryptoNeonFpArmv8, |
140 | // } |
141 | |
142 | impl ArmArchitecture { |
143 | /// Test if this architecture uses the Thumb instruction set. |
144 | #[rustfmt::skip] |
145 | pub fn is_thumb(self) -> bool { |
146 | use ArmArchitecture::*; |
147 | |
148 | match self { |
149 | Arm |
150 | | Armeb |
151 | | Armv4 |
152 | | Armv4t |
153 | | Armv5t |
154 | | Armv5te |
155 | | Armv5tej |
156 | | Armv6 |
157 | | Armv6j |
158 | | Armv6k |
159 | | Armv6z |
160 | | Armv6kz |
161 | | Armv6t2 |
162 | | Armv6m |
163 | | Armv7 |
164 | | Armv7a |
165 | | Armv7k |
166 | | Armv7ve |
167 | | Armv7m |
168 | | Armv7r |
169 | | Armv7s |
170 | | Armv8 |
171 | | Armv8a |
172 | | Armv8_1a |
173 | | Armv8_2a |
174 | | Armv8_3a |
175 | | Armv8_4a |
176 | | Armv8_5a |
177 | | Armv8mBase |
178 | | Armv8mMain |
179 | | Armv8r |
180 | | Armebv7r => false, |
181 | Thumbeb |
182 | | Thumbv4t |
183 | | Thumbv5te |
184 | | Thumbv6m |
185 | | Thumbv7a |
186 | | Thumbv7em |
187 | | Thumbv7m |
188 | | Thumbv7neon |
189 | | Thumbv8mBase |
190 | | Thumbv8mMain => true, |
191 | } |
192 | } |
193 | |
194 | // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { |
195 | |
196 | // } |
197 | |
198 | /// Return the pointer bit width of this target's architecture. |
199 | #[rustfmt::skip] |
200 | pub fn pointer_width(self) -> PointerWidth { |
201 | use ArmArchitecture::*; |
202 | |
203 | match self { |
204 | Arm |
205 | | Armeb |
206 | | Armv4 |
207 | | Armv4t |
208 | | Armv5t |
209 | | Armv5te |
210 | | Armv5tej |
211 | | Armv6 |
212 | | Armv6j |
213 | | Armv6k |
214 | | Armv6z |
215 | | Armv6kz |
216 | | Armv6t2 |
217 | | Armv6m |
218 | | Armv7 |
219 | | Armv7a |
220 | | Armv7k |
221 | | Armv7ve |
222 | | Armv7m |
223 | | Armv7r |
224 | | Armv7s |
225 | | Armv8 |
226 | | Armv8a |
227 | | Armv8_1a |
228 | | Armv8_2a |
229 | | Armv8_3a |
230 | | Armv8_4a |
231 | | Armv8_5a |
232 | | Armv8mBase |
233 | | Armv8mMain |
234 | | Armv8r |
235 | | Armebv7r |
236 | | Thumbeb |
237 | | Thumbv4t |
238 | | Thumbv5te |
239 | | Thumbv6m |
240 | | Thumbv7a |
241 | | Thumbv7em |
242 | | Thumbv7m |
243 | | Thumbv7neon |
244 | | Thumbv8mBase |
245 | | Thumbv8mMain => PointerWidth::U32, |
246 | } |
247 | } |
248 | |
249 | /// Return the endianness of this architecture. |
250 | #[rustfmt::skip] |
251 | pub fn endianness(self) -> Endianness { |
252 | use ArmArchitecture::*; |
253 | |
254 | match self { |
255 | Arm |
256 | | Armv4 |
257 | | Armv4t |
258 | | Armv5t |
259 | | Armv5te |
260 | | Armv5tej |
261 | | Armv6 |
262 | | Armv6j |
263 | | Armv6k |
264 | | Armv6z |
265 | | Armv6kz |
266 | | Armv6t2 |
267 | | Armv6m |
268 | | Armv7 |
269 | | Armv7a |
270 | | Armv7k |
271 | | Armv7ve |
272 | | Armv7m |
273 | | Armv7r |
274 | | Armv7s |
275 | | Armv8 |
276 | | Armv8a |
277 | | Armv8_1a |
278 | | Armv8_2a |
279 | | Armv8_3a |
280 | | Armv8_4a |
281 | | Armv8_5a |
282 | | Armv8mBase |
283 | | Armv8mMain |
284 | | Armv8r |
285 | | Thumbv4t |
286 | | Thumbv5te |
287 | | Thumbv6m |
288 | | Thumbv7a |
289 | | Thumbv7em |
290 | | Thumbv7m |
291 | | Thumbv7neon |
292 | | Thumbv8mBase |
293 | | Thumbv8mMain => Endianness::Little, |
294 | Armeb | Armebv7r | Thumbeb => Endianness::Big, |
295 | } |
296 | } |
297 | |
298 | /// Convert into a string |
299 | pub fn into_str(self) -> Cow<'static, str> { |
300 | use ArmArchitecture::*; |
301 | |
302 | match self { |
303 | Arm => Cow::Borrowed("arm" ), |
304 | Armeb => Cow::Borrowed("armeb" ), |
305 | Armv4 => Cow::Borrowed("armv4" ), |
306 | Armv4t => Cow::Borrowed("armv4t" ), |
307 | Armv5t => Cow::Borrowed("armv5t" ), |
308 | Armv5te => Cow::Borrowed("armv5te" ), |
309 | Armv5tej => Cow::Borrowed("armv5tej" ), |
310 | Armv6 => Cow::Borrowed("armv6" ), |
311 | Armv6j => Cow::Borrowed("armv6j" ), |
312 | Armv6k => Cow::Borrowed("armv6k" ), |
313 | Armv6z => Cow::Borrowed("armv6z" ), |
314 | Armv6kz => Cow::Borrowed("armv6kz" ), |
315 | Armv6t2 => Cow::Borrowed("armv6t2" ), |
316 | Armv6m => Cow::Borrowed("armv6m" ), |
317 | Armv7 => Cow::Borrowed("armv7" ), |
318 | Armv7a => Cow::Borrowed("armv7a" ), |
319 | Armv7k => Cow::Borrowed("armv7k" ), |
320 | Armv7ve => Cow::Borrowed("armv7ve" ), |
321 | Armv7m => Cow::Borrowed("armv7m" ), |
322 | Armv7r => Cow::Borrowed("armv7r" ), |
323 | Armv7s => Cow::Borrowed("armv7s" ), |
324 | Armv8 => Cow::Borrowed("armv8" ), |
325 | Armv8a => Cow::Borrowed("armv8a" ), |
326 | Armv8_1a => Cow::Borrowed("armv8.1a" ), |
327 | Armv8_2a => Cow::Borrowed("armv8.2a" ), |
328 | Armv8_3a => Cow::Borrowed("armv8.3a" ), |
329 | Armv8_4a => Cow::Borrowed("armv8.4a" ), |
330 | Armv8_5a => Cow::Borrowed("armv8.5a" ), |
331 | Armv8mBase => Cow::Borrowed("armv8m.base" ), |
332 | Armv8mMain => Cow::Borrowed("armv8m.main" ), |
333 | Armv8r => Cow::Borrowed("armv8r" ), |
334 | Thumbeb => Cow::Borrowed("thumbeb" ), |
335 | Thumbv4t => Cow::Borrowed("thumbv4t" ), |
336 | Thumbv5te => Cow::Borrowed("thumbv5te" ), |
337 | Thumbv6m => Cow::Borrowed("thumbv6m" ), |
338 | Thumbv7a => Cow::Borrowed("thumbv7a" ), |
339 | Thumbv7em => Cow::Borrowed("thumbv7em" ), |
340 | Thumbv7m => Cow::Borrowed("thumbv7m" ), |
341 | Thumbv7neon => Cow::Borrowed("thumbv7neon" ), |
342 | Thumbv8mBase => Cow::Borrowed("thumbv8m.base" ), |
343 | Thumbv8mMain => Cow::Borrowed("thumbv8m.main" ), |
344 | Armebv7r => Cow::Borrowed("armebv7r" ), |
345 | } |
346 | } |
347 | } |
348 | |
349 | impl Aarch64Architecture { |
350 | /// Test if this architecture uses the Thumb instruction set. |
351 | pub fn is_thumb(self) -> bool { |
352 | match self { |
353 | Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => false, |
354 | } |
355 | } |
356 | |
357 | // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> { |
358 | |
359 | // } |
360 | |
361 | /// Return the pointer bit width of this target's architecture. |
362 | /// |
363 | /// This function is only aware of the CPU architecture so it is not aware |
364 | /// of ilp32 ABIs. |
365 | pub fn pointer_width(self) -> PointerWidth { |
366 | match self { |
367 | Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => PointerWidth::U64, |
368 | } |
369 | } |
370 | |
371 | /// Return the endianness of this architecture. |
372 | pub fn endianness(self) -> Endianness { |
373 | match self { |
374 | Aarch64Architecture::Aarch64 => Endianness::Little, |
375 | Aarch64Architecture::Aarch64be => Endianness::Big, |
376 | } |
377 | } |
378 | |
379 | /// Convert into a string |
380 | pub fn into_str(self) -> Cow<'static, str> { |
381 | use Aarch64Architecture::*; |
382 | |
383 | match self { |
384 | Aarch64 => Cow::Borrowed("aarch64" ), |
385 | Aarch64be => Cow::Borrowed("aarch64_be" ), |
386 | } |
387 | } |
388 | } |
389 | |
390 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
391 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
392 | #[allow (missing_docs)] |
393 | pub enum CleverArchitecture { |
394 | Clever, |
395 | Clever1_0, |
396 | } |
397 | |
398 | impl CleverArchitecture { |
399 | /// Convert into a string |
400 | pub fn into_str(self) -> Cow<'static, str> { |
401 | use CleverArchitecture::*; |
402 | |
403 | match self { |
404 | Clever => Cow::Borrowed("clever" ), |
405 | Clever1_0 => Cow::Borrowed("clever1.0" ), |
406 | } |
407 | } |
408 | } |
409 | |
410 | /// An enum for all 32-bit RISC-V architectures. |
411 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
412 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
413 | #[allow (missing_docs)] |
414 | pub enum Riscv32Architecture { |
415 | Riscv32, |
416 | Riscv32gc, |
417 | Riscv32i, |
418 | Riscv32im, |
419 | Riscv32ima, |
420 | Riscv32imac, |
421 | Riscv32imafc, |
422 | Riscv32imc, |
423 | } |
424 | |
425 | impl Riscv32Architecture { |
426 | /// Convert into a string |
427 | pub fn into_str(self) -> Cow<'static, str> { |
428 | use Riscv32Architecture::*; |
429 | |
430 | match self { |
431 | Riscv32 => Cow::Borrowed("riscv32" ), |
432 | Riscv32gc => Cow::Borrowed("riscv32gc" ), |
433 | Riscv32i => Cow::Borrowed("riscv32i" ), |
434 | Riscv32im => Cow::Borrowed("riscv32im" ), |
435 | Riscv32ima => Cow::Borrowed("riscv32ima" ), |
436 | Riscv32imac => Cow::Borrowed("riscv32imac" ), |
437 | Riscv32imafc => Cow::Borrowed("riscv32imafc" ), |
438 | Riscv32imc => Cow::Borrowed("riscv32imc" ), |
439 | } |
440 | } |
441 | } |
442 | |
443 | /// An enum for all 64-bit RISC-V architectures. |
444 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
445 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
446 | #[allow (missing_docs)] |
447 | pub enum Riscv64Architecture { |
448 | Riscv64, |
449 | Riscv64gc, |
450 | Riscv64imac, |
451 | } |
452 | |
453 | impl Riscv64Architecture { |
454 | /// Convert into a string |
455 | pub fn into_str(self) -> Cow<'static, str> { |
456 | use Riscv64Architecture::*; |
457 | |
458 | match self { |
459 | Riscv64 => Cow::Borrowed("riscv64" ), |
460 | Riscv64gc => Cow::Borrowed("riscv64gc" ), |
461 | Riscv64imac => Cow::Borrowed("riscv64imac" ), |
462 | } |
463 | } |
464 | } |
465 | |
466 | /// An enum for all 32-bit x86 architectures. |
467 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
468 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
469 | #[allow (missing_docs)] |
470 | pub enum X86_32Architecture { |
471 | I386, |
472 | I586, |
473 | I686, |
474 | } |
475 | |
476 | impl X86_32Architecture { |
477 | /// Convert into a string |
478 | pub fn into_str(self) -> Cow<'static, str> { |
479 | use X86_32Architecture::*; |
480 | |
481 | match self { |
482 | I386 => Cow::Borrowed("i386" ), |
483 | I586 => Cow::Borrowed("i586" ), |
484 | I686 => Cow::Borrowed("i686" ), |
485 | } |
486 | } |
487 | } |
488 | |
489 | /// An enum for all 32-bit MIPS architectures (not just "MIPS32"). |
490 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
491 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
492 | #[allow (missing_docs)] |
493 | pub enum Mips32Architecture { |
494 | Mips, |
495 | Mipsel, |
496 | Mipsisa32r6, |
497 | Mipsisa32r6el, |
498 | } |
499 | |
500 | impl Mips32Architecture { |
501 | /// Convert into a string |
502 | pub fn into_str(self) -> Cow<'static, str> { |
503 | use Mips32Architecture::*; |
504 | |
505 | match self { |
506 | Mips => Cow::Borrowed("mips" ), |
507 | Mipsel => Cow::Borrowed("mipsel" ), |
508 | Mipsisa32r6 => Cow::Borrowed("mipsisa32r6" ), |
509 | Mipsisa32r6el => Cow::Borrowed("mipsisa32r6el" ), |
510 | } |
511 | } |
512 | } |
513 | |
514 | /// An enum for all 64-bit MIPS architectures (not just "MIPS64"). |
515 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
516 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
517 | #[allow (missing_docs)] |
518 | pub enum Mips64Architecture { |
519 | Mips64, |
520 | Mips64el, |
521 | Mipsisa64r6, |
522 | Mipsisa64r6el, |
523 | } |
524 | |
525 | impl Mips64Architecture { |
526 | /// Convert into a string |
527 | pub fn into_str(self) -> Cow<'static, str> { |
528 | use Mips64Architecture::*; |
529 | |
530 | match self { |
531 | Mips64 => Cow::Borrowed("mips64" ), |
532 | Mips64el => Cow::Borrowed("mips64el" ), |
533 | Mipsisa64r6 => Cow::Borrowed("mipsisa64r6" ), |
534 | Mipsisa64r6el => Cow::Borrowed("mipsisa64r6el" ), |
535 | } |
536 | } |
537 | } |
538 | |
539 | /// A string for a `Vendor::Custom` that can either be used in `const` |
540 | /// contexts or hold dynamic strings. |
541 | #[derive (Clone, Debug, Eq)] |
542 | pub enum CustomVendor { |
543 | /// An owned `String`. This supports the general case. |
544 | Owned(Box<String>), |
545 | /// A static `str`, so that `CustomVendor` can be constructed in `const` |
546 | /// contexts. |
547 | Static(&'static str), |
548 | } |
549 | |
550 | impl CustomVendor { |
551 | /// Extracts a string slice. |
552 | pub fn as_str(&self) -> &str { |
553 | match self { |
554 | CustomVendor::Owned(s: &Box) => s, |
555 | CustomVendor::Static(s: &&'static str) => s, |
556 | } |
557 | } |
558 | } |
559 | |
560 | impl PartialEq for CustomVendor { |
561 | fn eq(&self, other: &Self) -> bool { |
562 | self.as_str() == other.as_str() |
563 | } |
564 | } |
565 | |
566 | impl Hash for CustomVendor { |
567 | fn hash<H: Hasher>(&self, state: &mut H) { |
568 | self.as_str().hash(state) |
569 | } |
570 | } |
571 | |
572 | /// The "vendor" field, which in practice is little more than an arbitrary |
573 | /// modifier. |
574 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
575 | #[derive (Clone, Debug, PartialEq, Eq, Hash)] |
576 | #[allow (missing_docs)] |
577 | pub enum Vendor { |
578 | Unknown, |
579 | Amd, |
580 | Apple, |
581 | Espressif, |
582 | Experimental, |
583 | Fortanix, |
584 | Ibm, |
585 | Kmc, |
586 | Nintendo, |
587 | Nvidia, |
588 | Pc, |
589 | Rumprun, |
590 | Sun, |
591 | Uwp, |
592 | Wrs, |
593 | |
594 | /// A custom vendor. "Custom" in this context means that the vendor is |
595 | /// not specifically recognized by upstream Autotools, LLVM, Rust, or other |
596 | /// relevant authorities on triple naming. It's useful for people building |
597 | /// and using locally patched toolchains. |
598 | /// |
599 | /// Outside of such patched environments, users of `target-lexicon` should |
600 | /// treat `Custom` the same as `Unknown` and ignore the string. |
601 | Custom(CustomVendor), |
602 | } |
603 | |
604 | impl Vendor { |
605 | /// Extracts a string slice. |
606 | pub fn as_str(&self) -> &str { |
607 | use Vendor::*; |
608 | |
609 | match self { |
610 | Unknown => "unknown" , |
611 | Amd => "amd" , |
612 | Apple => "apple" , |
613 | Espressif => "espressif" , |
614 | Experimental => "experimental" , |
615 | Fortanix => "fortanix" , |
616 | Ibm => "ibm" , |
617 | Kmc => "kmc" , |
618 | Nintendo => "nintendo" , |
619 | Nvidia => "nvidia" , |
620 | Pc => "pc" , |
621 | Rumprun => "rumprun" , |
622 | Sun => "sun" , |
623 | Uwp => "uwp" , |
624 | Wrs => "wrs" , |
625 | Custom(name) => name.as_str(), |
626 | } |
627 | } |
628 | } |
629 | |
630 | /// The minimum OS version that we're compiling for. |
631 | /// |
632 | /// This is formatted as `"major.minor.patch"`. |
633 | /// |
634 | /// The size of the parts here are limited by Mach-O's `LC_BUILD_VERSION`. |
635 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] |
636 | #[allow (missing_docs)] |
637 | pub struct DeploymentTarget { |
638 | pub major: u16, |
639 | pub minor: u8, |
640 | pub patch: u8, |
641 | } |
642 | |
643 | /// The "operating system" field, which sometimes implies an environment, and |
644 | /// sometimes isn't an actual operating system. |
645 | /// |
646 | /// LLVM's Apple triples may optionally include the [deployment target]. |
647 | /// |
648 | /// [deployment target]: DeploymentTarget |
649 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
650 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
651 | #[allow (missing_docs)] |
652 | pub enum OperatingSystem { |
653 | Unknown, |
654 | Aix, |
655 | AmdHsa, |
656 | Bitrig, |
657 | Cloudabi, |
658 | Cuda, |
659 | /// The general [Darwin][darwin-wiki] core OS. |
660 | /// |
661 | /// Generally, `-mmacosx-version-min=...` or similar flags are required by |
662 | /// Clang to determine the actual OS (either macOS, iOS, tvOS, watchOS or |
663 | /// visionOS). |
664 | /// |
665 | /// WARNING: When parsing `rustc` target triples, this matches the macOS |
666 | /// target triples as well. |
667 | /// |
668 | /// [darwin-wiki]: https://en.wikipedia.org/wiki/Darwin_(operating_system) |
669 | Darwin(Option<DeploymentTarget>), |
670 | Dragonfly, |
671 | Emscripten, |
672 | Espidf, |
673 | Freebsd, |
674 | Fuchsia, |
675 | Haiku, |
676 | Hermit, |
677 | Horizon, |
678 | Hurd, |
679 | Illumos, |
680 | IOS(Option<DeploymentTarget>), |
681 | L4re, |
682 | Linux, |
683 | /// macOS. |
684 | /// |
685 | /// WARNING: This does _not_ match the macOS triples when parsing `rustc` |
686 | /// target triples, for that see the [`darwin`](Self::Darwin) OS name. |
687 | MacOSX(Option<DeploymentTarget>), |
688 | Nebulet, |
689 | Netbsd, |
690 | None_, |
691 | Openbsd, |
692 | Psp, |
693 | Redox, |
694 | Solaris, |
695 | SolidAsp3, |
696 | TvOS(Option<DeploymentTarget>), |
697 | Uefi, |
698 | VisionOS(Option<DeploymentTarget>), |
699 | VxWorks, |
700 | Wasi, |
701 | WasiP1, |
702 | WasiP2, |
703 | WatchOS(Option<DeploymentTarget>), |
704 | Windows, |
705 | /// An alternate name for [visionOS][Self::VisionOS]. |
706 | XROS(Option<DeploymentTarget>), |
707 | } |
708 | |
709 | impl OperatingSystem { |
710 | /// Convert into a string |
711 | pub fn into_str(self) -> Cow<'static, str> { |
712 | use OperatingSystem::*; |
713 | |
714 | let darwin_version = |name, deployment_target| { |
715 | if let Some(DeploymentTarget { |
716 | major, |
717 | minor, |
718 | patch, |
719 | }) = deployment_target |
720 | { |
721 | Cow::Owned(format!(" {}{}. {}. {}" , name, major, minor, patch)) |
722 | } else { |
723 | Cow::Borrowed(name) |
724 | } |
725 | }; |
726 | |
727 | match self { |
728 | Unknown => Cow::Borrowed("unknown" ), |
729 | Aix => Cow::Borrowed("aix" ), |
730 | AmdHsa => Cow::Borrowed("amdhsa" ), |
731 | Bitrig => Cow::Borrowed("bitrig" ), |
732 | Cloudabi => Cow::Borrowed("cloudabi" ), |
733 | Cuda => Cow::Borrowed("cuda" ), |
734 | Darwin(deployment_target) => darwin_version("darwin" , deployment_target), |
735 | Dragonfly => Cow::Borrowed("dragonfly" ), |
736 | Emscripten => Cow::Borrowed("emscripten" ), |
737 | Espidf => Cow::Borrowed("espidf" ), |
738 | Freebsd => Cow::Borrowed("freebsd" ), |
739 | Fuchsia => Cow::Borrowed("fuchsia" ), |
740 | Haiku => Cow::Borrowed("haiku" ), |
741 | Hermit => Cow::Borrowed("hermit" ), |
742 | Horizon => Cow::Borrowed("horizon" ), |
743 | Hurd => Cow::Borrowed("hurd" ), |
744 | Illumos => Cow::Borrowed("illumos" ), |
745 | IOS(deployment_target) => darwin_version("ios" , deployment_target), |
746 | L4re => Cow::Borrowed("l4re" ), |
747 | Linux => Cow::Borrowed("linux" ), |
748 | MacOSX(deployment_target) => darwin_version("macosx" , deployment_target), |
749 | Nebulet => Cow::Borrowed("nebulet" ), |
750 | Netbsd => Cow::Borrowed("netbsd" ), |
751 | None_ => Cow::Borrowed("none" ), |
752 | Openbsd => Cow::Borrowed("openbsd" ), |
753 | Psp => Cow::Borrowed("psp" ), |
754 | Redox => Cow::Borrowed("redox" ), |
755 | Solaris => Cow::Borrowed("solaris" ), |
756 | SolidAsp3 => Cow::Borrowed("solid_asp3" ), |
757 | TvOS(deployment_target) => darwin_version("tvos" , deployment_target), |
758 | Uefi => Cow::Borrowed("uefi" ), |
759 | VxWorks => Cow::Borrowed("vxworks" ), |
760 | VisionOS(deployment_target) => darwin_version("visionos" , deployment_target), |
761 | Wasi => Cow::Borrowed("wasi" ), |
762 | WasiP1 => Cow::Borrowed("wasip1" ), |
763 | WasiP2 => Cow::Borrowed("wasip2" ), |
764 | WatchOS(deployment_target) => darwin_version("watchos" , deployment_target), |
765 | Windows => Cow::Borrowed("windows" ), |
766 | XROS(deployment_target) => darwin_version("xros" , deployment_target), |
767 | } |
768 | } |
769 | |
770 | /// Whether the OS is similar to Darwin. |
771 | /// |
772 | /// This matches on any of: |
773 | /// - [Darwin](Self::Darwin) |
774 | /// - [iOS](Self::IOS) |
775 | /// - [macOS](Self::MacOSX) |
776 | /// - [tvOS](Self::TvOS) |
777 | /// - [visionOS](Self::VisionOS) |
778 | /// - [watchOS](Self::WatchOS) |
779 | /// - [xrOS](Self::XROS) |
780 | pub fn is_like_darwin(&self) -> bool { |
781 | use OperatingSystem::*; |
782 | |
783 | match self { |
784 | Darwin(_) | IOS(_) | MacOSX(_) | TvOS(_) | VisionOS(_) | WatchOS(_) | XROS(_) => true, |
785 | _ => false, |
786 | } |
787 | } |
788 | } |
789 | |
790 | /// The "environment" field, which specifies an ABI environment on top of the |
791 | /// operating system. In many configurations, this field is omitted, and the |
792 | /// environment is implied by the operating system. |
793 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
794 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
795 | #[allow (missing_docs)] |
796 | pub enum Environment { |
797 | Unknown, |
798 | AmdGiz, |
799 | Android, |
800 | Androideabi, |
801 | Eabi, |
802 | Eabihf, |
803 | Gnu, |
804 | Gnuabi64, |
805 | Gnueabi, |
806 | Gnueabihf, |
807 | Gnuspe, |
808 | Gnux32, |
809 | GnuIlp32, |
810 | GnuLlvm, |
811 | HermitKernel, |
812 | HurdKernel, |
813 | LinuxKernel, |
814 | Macabi, |
815 | Musl, |
816 | Musleabi, |
817 | Musleabihf, |
818 | Muslabi64, |
819 | Msvc, |
820 | Newlib, |
821 | None, |
822 | Kernel, |
823 | Uclibc, |
824 | Uclibceabi, |
825 | Uclibceabihf, |
826 | Sgx, |
827 | Sim, |
828 | Softfloat, |
829 | Spe, |
830 | Threads, |
831 | Ohos, |
832 | } |
833 | |
834 | impl Environment { |
835 | /// Convert into a string |
836 | pub fn into_str(self) -> Cow<'static, str> { |
837 | use Environment::*; |
838 | |
839 | match self { |
840 | Unknown => Cow::Borrowed("unknown" ), |
841 | AmdGiz => Cow::Borrowed("amdgiz" ), |
842 | Android => Cow::Borrowed("android" ), |
843 | Androideabi => Cow::Borrowed("androideabi" ), |
844 | Eabi => Cow::Borrowed("eabi" ), |
845 | Eabihf => Cow::Borrowed("eabihf" ), |
846 | Gnu => Cow::Borrowed("gnu" ), |
847 | Gnuabi64 => Cow::Borrowed("gnuabi64" ), |
848 | Gnueabi => Cow::Borrowed("gnueabi" ), |
849 | Gnueabihf => Cow::Borrowed("gnueabihf" ), |
850 | Gnuspe => Cow::Borrowed("gnuspe" ), |
851 | Gnux32 => Cow::Borrowed("gnux32" ), |
852 | GnuIlp32 => Cow::Borrowed("gnu_ilp32" ), |
853 | GnuLlvm => Cow::Borrowed("gnullvm" ), |
854 | HermitKernel => Cow::Borrowed("hermitkernel" ), |
855 | HurdKernel => Cow::Borrowed("hurdkernel" ), |
856 | LinuxKernel => Cow::Borrowed("linuxkernel" ), |
857 | Macabi => Cow::Borrowed("macabi" ), |
858 | Musl => Cow::Borrowed("musl" ), |
859 | Musleabi => Cow::Borrowed("musleabi" ), |
860 | Musleabihf => Cow::Borrowed("musleabihf" ), |
861 | Muslabi64 => Cow::Borrowed("muslabi64" ), |
862 | Msvc => Cow::Borrowed("msvc" ), |
863 | Newlib => Cow::Borrowed("newlib" ), |
864 | None => Cow::Borrowed("none" ), |
865 | Kernel => Cow::Borrowed("kernel" ), |
866 | Uclibc => Cow::Borrowed("uclibc" ), |
867 | Uclibceabi => Cow::Borrowed("uclibceabi" ), |
868 | Uclibceabihf => Cow::Borrowed("uclibceabihf" ), |
869 | Sgx => Cow::Borrowed("sgx" ), |
870 | Sim => Cow::Borrowed("sim" ), |
871 | Softfloat => Cow::Borrowed("softfloat" ), |
872 | Spe => Cow::Borrowed("spe" ), |
873 | Threads => Cow::Borrowed("threads" ), |
874 | Ohos => Cow::Borrowed("ohos" ), |
875 | } |
876 | } |
877 | } |
878 | |
879 | /// The "binary format" field, which is usually omitted, and the binary format |
880 | /// is implied by the other fields. |
881 | #[cfg_attr (feature = "rust_1_40" , non_exhaustive)] |
882 | #[derive (Copy, Clone, Debug, PartialEq, Eq, Hash)] |
883 | #[allow (missing_docs)] |
884 | pub enum BinaryFormat { |
885 | Unknown, |
886 | Elf, |
887 | Coff, |
888 | Macho, |
889 | Wasm, |
890 | Xcoff, |
891 | } |
892 | |
893 | impl BinaryFormat { |
894 | /// Convert into a string |
895 | pub fn into_str(self) -> Cow<'static, str> { |
896 | use BinaryFormat::*; |
897 | |
898 | match self { |
899 | Unknown => Cow::Borrowed("unknown" ), |
900 | Elf => Cow::Borrowed("elf" ), |
901 | Coff => Cow::Borrowed("coff" ), |
902 | Macho => Cow::Borrowed("macho" ), |
903 | Wasm => Cow::Borrowed("wasm" ), |
904 | Xcoff => Cow::Borrowed("xcoff" ), |
905 | } |
906 | } |
907 | } |
908 | |
909 | impl Architecture { |
910 | /// Return the endianness of this architecture. |
911 | #[rustfmt::skip] |
912 | pub fn endianness(self) -> Result<Endianness, ()> { |
913 | use Architecture::*; |
914 | |
915 | match self { |
916 | Unknown => Err(()), |
917 | Arm(arm) => Ok(arm.endianness()), |
918 | Aarch64(aarch) => Ok(aarch.endianness()), |
919 | AmdGcn |
920 | | Asmjs |
921 | | Avr |
922 | | Bpfel |
923 | | Hexagon |
924 | | X86_32(_) |
925 | | LoongArch64 |
926 | | Mips64(Mips64Architecture::Mips64el) |
927 | | Mips32(Mips32Architecture::Mipsel) |
928 | | Mips32(Mips32Architecture::Mipsisa32r6el) |
929 | | Mips64(Mips64Architecture::Mipsisa64r6el) |
930 | | Msp430 |
931 | | Nvptx64 |
932 | | Pulley32 |
933 | | Pulley64 |
934 | | Powerpc64le |
935 | | Riscv32(_) |
936 | | Riscv64(_) |
937 | | Wasm32 |
938 | | Wasm64 |
939 | | X86_64 |
940 | | X86_64h |
941 | | XTensa |
942 | | Clever(_) => Ok(Endianness::Little), |
943 | Bpfeb |
944 | | M68k |
945 | | Mips32(Mips32Architecture::Mips) |
946 | | Mips64(Mips64Architecture::Mips64) |
947 | | Mips32(Mips32Architecture::Mipsisa32r6) |
948 | | Mips64(Mips64Architecture::Mipsisa64r6) |
949 | | Powerpc |
950 | | Powerpc64 |
951 | | Pulley32be |
952 | | Pulley64be |
953 | | S390x |
954 | | Sparc |
955 | | Sparc64 |
956 | | Sparcv9 => Ok(Endianness::Big), |
957 | #[cfg (feature="arch_zkasm" )] |
958 | ZkAsm => Ok(Endianness::Big), |
959 | } |
960 | } |
961 | |
962 | /// Return the pointer bit width of this target's architecture. |
963 | /// |
964 | /// This function is only aware of the CPU architecture so it is not aware |
965 | /// of ilp32 and x32 ABIs. |
966 | #[rustfmt::skip] |
967 | pub fn pointer_width(self) -> Result<PointerWidth, ()> { |
968 | use Architecture::*; |
969 | |
970 | match self { |
971 | Unknown => Err(()), |
972 | Avr | Msp430 => Ok(PointerWidth::U16), |
973 | Arm(arm) => Ok(arm.pointer_width()), |
974 | Aarch64(aarch) => Ok(aarch.pointer_width()), |
975 | Asmjs |
976 | | Hexagon |
977 | | X86_32(_) |
978 | | Riscv32(_) |
979 | | Sparc |
980 | | Wasm32 |
981 | | M68k |
982 | | Mips32(_) |
983 | | Pulley32 |
984 | | Pulley32be |
985 | | Powerpc |
986 | | XTensa => Ok(PointerWidth::U32), |
987 | AmdGcn |
988 | | Bpfeb |
989 | | Bpfel |
990 | | Powerpc64le |
991 | | Riscv64(_) |
992 | | X86_64 |
993 | | X86_64h |
994 | | Mips64(_) |
995 | | Nvptx64 |
996 | | Pulley64 |
997 | | Pulley64be |
998 | | Powerpc64 |
999 | | S390x |
1000 | | Sparc64 |
1001 | | Sparcv9 |
1002 | | LoongArch64 |
1003 | | Wasm64 |
1004 | | Clever(_) => Ok(PointerWidth::U64), |
1005 | #[cfg (feature="arch_zkasm" )] |
1006 | ZkAsm => Ok(PointerWidth::U64), |
1007 | } |
1008 | } |
1009 | |
1010 | /// Checks if this Architecture is some variant of Clever-ISA |
1011 | pub fn is_clever(&self) -> bool { |
1012 | match self { |
1013 | Architecture::Clever(_) => true, |
1014 | _ => false, |
1015 | } |
1016 | } |
1017 | |
1018 | /// Convert into a string |
1019 | pub fn into_str(self) -> Cow<'static, str> { |
1020 | use Architecture::*; |
1021 | |
1022 | match self { |
1023 | Arm(arm) => arm.into_str(), |
1024 | Aarch64(aarch) => aarch.into_str(), |
1025 | Unknown => Cow::Borrowed("unknown" ), |
1026 | AmdGcn => Cow::Borrowed("amdgcn" ), |
1027 | Asmjs => Cow::Borrowed("asmjs" ), |
1028 | Avr => Cow::Borrowed("avr" ), |
1029 | Bpfeb => Cow::Borrowed("bpfeb" ), |
1030 | Bpfel => Cow::Borrowed("bpfel" ), |
1031 | Hexagon => Cow::Borrowed("hexagon" ), |
1032 | X86_32(x86_32) => x86_32.into_str(), |
1033 | LoongArch64 => Cow::Borrowed("loongarch64" ), |
1034 | M68k => Cow::Borrowed("m68k" ), |
1035 | Mips32(mips32) => mips32.into_str(), |
1036 | Mips64(mips64) => mips64.into_str(), |
1037 | Msp430 => Cow::Borrowed("msp430" ), |
1038 | Nvptx64 => Cow::Borrowed("nvptx64" ), |
1039 | Pulley32 => Cow::Borrowed("pulley32" ), |
1040 | Pulley64 => Cow::Borrowed("pulley64" ), |
1041 | Pulley32be => Cow::Borrowed("pulley32be" ), |
1042 | Pulley64be => Cow::Borrowed("pulley64be" ), |
1043 | Powerpc => Cow::Borrowed("powerpc" ), |
1044 | Powerpc64 => Cow::Borrowed("powerpc64" ), |
1045 | Powerpc64le => Cow::Borrowed("powerpc64le" ), |
1046 | Riscv32(riscv32) => riscv32.into_str(), |
1047 | Riscv64(riscv64) => riscv64.into_str(), |
1048 | S390x => Cow::Borrowed("s390x" ), |
1049 | Sparc => Cow::Borrowed("sparc" ), |
1050 | Sparc64 => Cow::Borrowed("sparc64" ), |
1051 | Sparcv9 => Cow::Borrowed("sparcv9" ), |
1052 | Wasm32 => Cow::Borrowed("wasm32" ), |
1053 | Wasm64 => Cow::Borrowed("wasm64" ), |
1054 | X86_64 => Cow::Borrowed("x86_64" ), |
1055 | X86_64h => Cow::Borrowed("x86_64h" ), |
1056 | XTensa => Cow::Borrowed("xtensa" ), |
1057 | Clever(ver) => ver.into_str(), |
1058 | #[cfg (feature = "arch_zkasm" )] |
1059 | ZkAsm => Cow::Borrowed("zkasm" ), |
1060 | } |
1061 | } |
1062 | } |
1063 | |
1064 | /// Return the binary format implied by this target triple, ignoring its |
1065 | /// `binary_format` field. |
1066 | pub(crate) fn default_binary_format(triple: &Triple) -> BinaryFormat { |
1067 | match triple.operating_system { |
1068 | OperatingSystem::None_ => match triple.environment { |
1069 | Environment::Eabi | Environment::Eabihf => BinaryFormat::Elf, |
1070 | _ => BinaryFormat::Unknown, |
1071 | }, |
1072 | OperatingSystem::Aix => BinaryFormat::Xcoff, |
1073 | os: OperatingSystem if os.is_like_darwin() => BinaryFormat::Macho, |
1074 | OperatingSystem::Windows => BinaryFormat::Coff, |
1075 | OperatingSystem::Nebulet |
1076 | | OperatingSystem::Emscripten |
1077 | | OperatingSystem::VxWorks |
1078 | | OperatingSystem::Wasi |
1079 | | OperatingSystem::Unknown => match triple.architecture { |
1080 | Architecture::Wasm32 | Architecture::Wasm64 => BinaryFormat::Wasm, |
1081 | Architecture::Unknown => BinaryFormat::Unknown, |
1082 | // Default to ELF, following `getDefaultFormat` in LLVM. |
1083 | _ => BinaryFormat::Elf, |
1084 | }, |
1085 | _ => BinaryFormat::Elf, |
1086 | } |
1087 | } |
1088 | |
1089 | impl fmt::Display for ArmArchitecture { |
1090 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1091 | f.write_str(&self.into_str()) |
1092 | } |
1093 | } |
1094 | |
1095 | impl fmt::Display for Aarch64Architecture { |
1096 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1097 | f.write_str(&self.into_str()) |
1098 | } |
1099 | } |
1100 | |
1101 | impl fmt::Display for CleverArchitecture { |
1102 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1103 | f.write_str(&self.into_str()) |
1104 | } |
1105 | } |
1106 | |
1107 | impl fmt::Display for Riscv32Architecture { |
1108 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1109 | f.write_str(&self.into_str()) |
1110 | } |
1111 | } |
1112 | |
1113 | impl fmt::Display for Riscv64Architecture { |
1114 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1115 | f.write_str(&self.into_str()) |
1116 | } |
1117 | } |
1118 | |
1119 | impl fmt::Display for X86_32Architecture { |
1120 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1121 | f.write_str(&self.into_str()) |
1122 | } |
1123 | } |
1124 | |
1125 | impl fmt::Display for Mips32Architecture { |
1126 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1127 | f.write_str(&self.into_str()) |
1128 | } |
1129 | } |
1130 | |
1131 | impl fmt::Display for Mips64Architecture { |
1132 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1133 | f.write_str(&self.into_str()) |
1134 | } |
1135 | } |
1136 | |
1137 | impl fmt::Display for Architecture { |
1138 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1139 | f.write_str(&self.into_str()) |
1140 | } |
1141 | } |
1142 | |
1143 | impl FromStr for ArmArchitecture { |
1144 | type Err = (); |
1145 | |
1146 | fn from_str(s: &str) -> Result<Self, ()> { |
1147 | use ArmArchitecture::*; |
1148 | |
1149 | Ok(match s { |
1150 | "arm" => Arm, |
1151 | "armeb" => Armeb, |
1152 | "armv4" => Armv4, |
1153 | "armv4t" => Armv4t, |
1154 | "armv5t" => Armv5t, |
1155 | "armv5te" => Armv5te, |
1156 | "armv5tej" => Armv5tej, |
1157 | "armv6" => Armv6, |
1158 | "armv6j" => Armv6j, |
1159 | "armv6k" => Armv6k, |
1160 | "armv6z" => Armv6z, |
1161 | "armv6kz" => Armv6kz, |
1162 | "armv6t2" => Armv6t2, |
1163 | "armv6m" => Armv6m, |
1164 | "armv7" => Armv7, |
1165 | "armv7a" => Armv7a, |
1166 | "armv7k" => Armv7k, |
1167 | "armv7ve" => Armv7ve, |
1168 | "armv7m" => Armv7m, |
1169 | "armv7r" => Armv7r, |
1170 | "armv7s" => Armv7s, |
1171 | "armv8" => Armv8, |
1172 | "armv8a" => Armv8a, |
1173 | "armv8.1a" => Armv8_1a, |
1174 | "armv8.2a" => Armv8_2a, |
1175 | "armv8.3a" => Armv8_3a, |
1176 | "armv8.4a" => Armv8_4a, |
1177 | "armv8.5a" => Armv8_5a, |
1178 | "armv8m.base" => Armv8mBase, |
1179 | "armv8m.main" => Armv8mMain, |
1180 | "armv8r" => Armv8r, |
1181 | "thumbeb" => Thumbeb, |
1182 | "thumbv4t" => Thumbv4t, |
1183 | "thumbv5te" => Thumbv5te, |
1184 | "thumbv6m" => Thumbv6m, |
1185 | "thumbv7a" => Thumbv7a, |
1186 | "thumbv7em" => Thumbv7em, |
1187 | "thumbv7m" => Thumbv7m, |
1188 | "thumbv7neon" => Thumbv7neon, |
1189 | "thumbv8m.base" => Thumbv8mBase, |
1190 | "thumbv8m.main" => Thumbv8mMain, |
1191 | "armebv7r" => Armebv7r, |
1192 | _ => return Err(()), |
1193 | }) |
1194 | } |
1195 | } |
1196 | |
1197 | impl FromStr for Aarch64Architecture { |
1198 | type Err = (); |
1199 | |
1200 | fn from_str(s: &str) -> Result<Self, ()> { |
1201 | use Aarch64Architecture::*; |
1202 | |
1203 | Ok(match s { |
1204 | "aarch64" => Aarch64, |
1205 | "arm64" => Aarch64, |
1206 | "aarch64_be" => Aarch64be, |
1207 | _ => return Err(()), |
1208 | }) |
1209 | } |
1210 | } |
1211 | |
1212 | impl FromStr for CleverArchitecture { |
1213 | type Err = (); |
1214 | fn from_str(s: &str) -> Result<Self, ()> { |
1215 | match s { |
1216 | "clever" => Ok(CleverArchitecture::Clever), |
1217 | "clever1.0" => Ok(CleverArchitecture::Clever1_0), |
1218 | _ => Err(()), |
1219 | } |
1220 | } |
1221 | } |
1222 | |
1223 | impl FromStr for Riscv32Architecture { |
1224 | type Err = (); |
1225 | |
1226 | fn from_str(s: &str) -> Result<Self, ()> { |
1227 | use Riscv32Architecture::*; |
1228 | |
1229 | Ok(match s { |
1230 | "riscv32" => Riscv32, |
1231 | "riscv32gc" => Riscv32gc, |
1232 | "riscv32i" => Riscv32i, |
1233 | "riscv32im" => Riscv32im, |
1234 | "riscv32ima" => Riscv32ima, |
1235 | "riscv32imac" => Riscv32imac, |
1236 | "riscv32imafc" => Riscv32imafc, |
1237 | "riscv32imc" => Riscv32imc, |
1238 | _ => return Err(()), |
1239 | }) |
1240 | } |
1241 | } |
1242 | |
1243 | impl FromStr for Riscv64Architecture { |
1244 | type Err = (); |
1245 | |
1246 | fn from_str(s: &str) -> Result<Self, ()> { |
1247 | use Riscv64Architecture::*; |
1248 | |
1249 | Ok(match s { |
1250 | "riscv64" => Riscv64, |
1251 | "riscv64gc" => Riscv64gc, |
1252 | "riscv64imac" => Riscv64imac, |
1253 | _ => return Err(()), |
1254 | }) |
1255 | } |
1256 | } |
1257 | |
1258 | impl FromStr for X86_32Architecture { |
1259 | type Err = (); |
1260 | |
1261 | fn from_str(s: &str) -> Result<Self, ()> { |
1262 | use X86_32Architecture::*; |
1263 | |
1264 | Ok(match s { |
1265 | "i386" => I386, |
1266 | "i586" => I586, |
1267 | "i686" => I686, |
1268 | _ => return Err(()), |
1269 | }) |
1270 | } |
1271 | } |
1272 | |
1273 | impl FromStr for Mips32Architecture { |
1274 | type Err = (); |
1275 | |
1276 | fn from_str(s: &str) -> Result<Self, ()> { |
1277 | use Mips32Architecture::*; |
1278 | |
1279 | Ok(match s { |
1280 | "mips" => Mips, |
1281 | "mipsel" => Mipsel, |
1282 | "mipsisa32r6" => Mipsisa32r6, |
1283 | "mipsisa32r6el" => Mipsisa32r6el, |
1284 | _ => return Err(()), |
1285 | }) |
1286 | } |
1287 | } |
1288 | |
1289 | impl FromStr for Mips64Architecture { |
1290 | type Err = (); |
1291 | |
1292 | fn from_str(s: &str) -> Result<Self, ()> { |
1293 | use Mips64Architecture::*; |
1294 | |
1295 | Ok(match s { |
1296 | "mips64" => Mips64, |
1297 | "mips64el" => Mips64el, |
1298 | "mipsisa64r6" => Mipsisa64r6, |
1299 | "mipsisa64r6el" => Mipsisa64r6el, |
1300 | _ => return Err(()), |
1301 | }) |
1302 | } |
1303 | } |
1304 | |
1305 | impl FromStr for Architecture { |
1306 | type Err = (); |
1307 | |
1308 | fn from_str(s: &str) -> Result<Self, ()> { |
1309 | use Architecture::*; |
1310 | |
1311 | Ok(match s { |
1312 | "unknown" => Unknown, |
1313 | "amdgcn" => AmdGcn, |
1314 | "asmjs" => Asmjs, |
1315 | "avr" => Avr, |
1316 | "bpfeb" => Bpfeb, |
1317 | "bpfel" => Bpfel, |
1318 | "hexagon" => Hexagon, |
1319 | "loongarch64" => LoongArch64, |
1320 | "m68k" => M68k, |
1321 | "msp430" => Msp430, |
1322 | "nvptx64" => Nvptx64, |
1323 | "pulley32" => Pulley32, |
1324 | "pulley64" => Pulley64, |
1325 | "pulley32be" => Pulley32be, |
1326 | "pulley64be" => Pulley64be, |
1327 | "powerpc" => Powerpc, |
1328 | "powerpc64" => Powerpc64, |
1329 | "powerpc64le" => Powerpc64le, |
1330 | "s390x" => S390x, |
1331 | "sparc" => Sparc, |
1332 | "sparc64" => Sparc64, |
1333 | "sparcv9" => Sparcv9, |
1334 | "wasm32" => Wasm32, |
1335 | "wasm64" => Wasm64, |
1336 | "x86_64" => X86_64, |
1337 | "x86_64h" => X86_64h, |
1338 | "xtensa" => XTensa, |
1339 | #[cfg (feature = "arch_zkasm" )] |
1340 | "zkasm" => ZkAsm, |
1341 | _ => { |
1342 | if let Ok(arm) = ArmArchitecture::from_str(s) { |
1343 | Arm(arm) |
1344 | } else if let Ok(aarch64) = Aarch64Architecture::from_str(s) { |
1345 | Aarch64(aarch64) |
1346 | } else if let Ok(riscv32) = Riscv32Architecture::from_str(s) { |
1347 | Riscv32(riscv32) |
1348 | } else if let Ok(riscv64) = Riscv64Architecture::from_str(s) { |
1349 | Riscv64(riscv64) |
1350 | } else if let Ok(x86_32) = X86_32Architecture::from_str(s) { |
1351 | X86_32(x86_32) |
1352 | } else if let Ok(mips32) = Mips32Architecture::from_str(s) { |
1353 | Mips32(mips32) |
1354 | } else if let Ok(mips64) = Mips64Architecture::from_str(s) { |
1355 | Mips64(mips64) |
1356 | } else if let Ok(clever) = CleverArchitecture::from_str(s) { |
1357 | Clever(clever) |
1358 | } else { |
1359 | return Err(()); |
1360 | } |
1361 | } |
1362 | }) |
1363 | } |
1364 | } |
1365 | |
1366 | impl fmt::Display for Vendor { |
1367 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1368 | f.write_str(self.as_str()) |
1369 | } |
1370 | } |
1371 | |
1372 | impl FromStr for Vendor { |
1373 | type Err = (); |
1374 | |
1375 | fn from_str(s: &str) -> Result<Self, ()> { |
1376 | use Vendor::*; |
1377 | |
1378 | Ok(match s { |
1379 | "unknown" => Unknown, |
1380 | "amd" => Amd, |
1381 | "apple" => Apple, |
1382 | "espressif" => Espressif, |
1383 | "experimental" => Experimental, |
1384 | "fortanix" => Fortanix, |
1385 | "ibm" => Ibm, |
1386 | "kmc" => Kmc, |
1387 | "nintendo" => Nintendo, |
1388 | "nvidia" => Nvidia, |
1389 | "pc" => Pc, |
1390 | "rumprun" => Rumprun, |
1391 | "sun" => Sun, |
1392 | "uwp" => Uwp, |
1393 | "wrs" => Wrs, |
1394 | custom => { |
1395 | #[cfg (not(feature = "std" ))] |
1396 | use alloc::borrow::ToOwned; |
1397 | |
1398 | // A custom vendor. Since triple syntax is so loosely defined, |
1399 | // be as conservative as we can to avoid potential ambiguities. |
1400 | // We err on the side of being too strict here, as we can |
1401 | // always relax it if needed. |
1402 | |
1403 | // Don't allow empty string names. |
1404 | if custom.is_empty() { |
1405 | return Err(()); |
1406 | } |
1407 | |
1408 | // Don't allow any other recognized name as a custom vendor, |
1409 | // since vendors can be omitted in some contexts. |
1410 | if Architecture::from_str(custom).is_ok() |
1411 | || OperatingSystem::from_str(custom).is_ok() |
1412 | || Environment::from_str(custom).is_ok() |
1413 | || BinaryFormat::from_str(custom).is_ok() |
1414 | { |
1415 | return Err(()); |
1416 | } |
1417 | |
1418 | // Require the first character to be an ascii lowercase. |
1419 | if !custom.chars().next().unwrap().is_ascii_lowercase() { |
1420 | return Err(()); |
1421 | } |
1422 | |
1423 | // Restrict the set of characters permitted in a custom vendor. |
1424 | let has_restricted = custom.chars().any(|c: char| { |
1425 | !(c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_' || c == '.' ) |
1426 | }); |
1427 | |
1428 | if has_restricted { |
1429 | return Err(()); |
1430 | } |
1431 | |
1432 | Custom(CustomVendor::Owned(Box::new(custom.to_owned()))) |
1433 | } |
1434 | }) |
1435 | } |
1436 | } |
1437 | |
1438 | impl fmt::Display for OperatingSystem { |
1439 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1440 | use OperatingSystem::*; |
1441 | |
1442 | let mut with_version = |name, deployment_target| { |
1443 | if let Some(DeploymentTarget { |
1444 | major, |
1445 | minor, |
1446 | patch, |
1447 | }) = deployment_target |
1448 | { |
1449 | write!(f, " {}{}. {}. {}" , name, major, minor, patch) |
1450 | } else { |
1451 | write!(f, " {}" , name) |
1452 | } |
1453 | }; |
1454 | |
1455 | match *self { |
1456 | Darwin(deployment_target) => with_version("darwin" , deployment_target), |
1457 | IOS(deployment_target) => with_version("ios" , deployment_target), |
1458 | MacOSX(deployment_target) => with_version("macosx" , deployment_target), |
1459 | TvOS(deployment_target) => with_version("tvos" , deployment_target), |
1460 | VisionOS(deployment_target) => with_version("visionos" , deployment_target), |
1461 | WatchOS(deployment_target) => with_version("watchos" , deployment_target), |
1462 | XROS(deployment_target) => with_version("xros" , deployment_target), |
1463 | os => f.write_str(&os.into_str()), |
1464 | } |
1465 | } |
1466 | } |
1467 | |
1468 | impl FromStr for OperatingSystem { |
1469 | type Err = (); |
1470 | |
1471 | fn from_str(s: &str) -> Result<Self, ()> { |
1472 | use OperatingSystem::*; |
1473 | |
1474 | let parse_darwin = |name: &str| { |
1475 | let s = &s[name.len()..]; |
1476 | let mut parts = s.split('.' ); |
1477 | |
1478 | if s.is_empty() { |
1479 | // Not specifying a version is allowed! |
1480 | return Ok(None); |
1481 | } |
1482 | |
1483 | let major = if let Some(part) = parts.next() { |
1484 | part.parse().map_err(|_| ())? |
1485 | } else { |
1486 | // If the string was just `.`, with no major version, that's |
1487 | // clearly an error. |
1488 | return Err(()); |
1489 | }; |
1490 | let minor = if let Some(part) = parts.next() { |
1491 | part.parse().map_err(|_| ())? |
1492 | } else { |
1493 | // Fall back to 0 if no minor version was set |
1494 | 0 |
1495 | }; |
1496 | let patch = if let Some(part) = parts.next() { |
1497 | part.parse().map_err(|_| ())? |
1498 | } else { |
1499 | // Fall back to 0 if no patch version was set |
1500 | 0 |
1501 | }; |
1502 | |
1503 | if parts.next().is_some() { |
1504 | // Too many parts |
1505 | return Err(()); |
1506 | } |
1507 | |
1508 | Ok(Some(DeploymentTarget { |
1509 | major, |
1510 | minor, |
1511 | patch, |
1512 | })) |
1513 | }; |
1514 | |
1515 | // Parse operating system names that contain a version, like `macosx10.7.0`. |
1516 | if s.starts_with("darwin" ) { |
1517 | return Ok(Darwin(parse_darwin("darwin" )?)); |
1518 | } |
1519 | if s.starts_with("ios" ) { |
1520 | return Ok(IOS(parse_darwin("ios" )?)); |
1521 | } |
1522 | if s.starts_with("macosx" ) { |
1523 | return Ok(MacOSX(parse_darwin("macosx" )?)); |
1524 | } |
1525 | if s.starts_with("tvos" ) { |
1526 | return Ok(TvOS(parse_darwin("tvos" )?)); |
1527 | } |
1528 | if s.starts_with("visionos" ) { |
1529 | return Ok(VisionOS(parse_darwin("visionos" )?)); |
1530 | } |
1531 | if s.starts_with("watchos" ) { |
1532 | return Ok(WatchOS(parse_darwin("watchos" )?)); |
1533 | } |
1534 | if s.starts_with("xros" ) { |
1535 | return Ok(XROS(parse_darwin("xros" )?)); |
1536 | } |
1537 | |
1538 | Ok(match s { |
1539 | "unknown" => Unknown, |
1540 | "aix" => Aix, |
1541 | "amdhsa" => AmdHsa, |
1542 | "bitrig" => Bitrig, |
1543 | "cloudabi" => Cloudabi, |
1544 | "cuda" => Cuda, |
1545 | "dragonfly" => Dragonfly, |
1546 | "emscripten" => Emscripten, |
1547 | "freebsd" => Freebsd, |
1548 | "fuchsia" => Fuchsia, |
1549 | "haiku" => Haiku, |
1550 | "hermit" => Hermit, |
1551 | "horizon" => Horizon, |
1552 | "hurd" => Hurd, |
1553 | "illumos" => Illumos, |
1554 | "l4re" => L4re, |
1555 | "linux" => Linux, |
1556 | "nebulet" => Nebulet, |
1557 | "netbsd" => Netbsd, |
1558 | "none" => None_, |
1559 | "openbsd" => Openbsd, |
1560 | "psp" => Psp, |
1561 | "redox" => Redox, |
1562 | "solaris" => Solaris, |
1563 | "solid_asp3" => SolidAsp3, |
1564 | "uefi" => Uefi, |
1565 | "vxworks" => VxWorks, |
1566 | "wasi" => Wasi, |
1567 | "wasip1" => WasiP1, |
1568 | "wasip2" => WasiP2, |
1569 | "windows" => Windows, |
1570 | "espidf" => Espidf, |
1571 | _ => return Err(()), |
1572 | }) |
1573 | } |
1574 | } |
1575 | |
1576 | impl fmt::Display for Environment { |
1577 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1578 | f.write_str(&self.into_str()) |
1579 | } |
1580 | } |
1581 | |
1582 | impl FromStr for Environment { |
1583 | type Err = (); |
1584 | |
1585 | fn from_str(s: &str) -> Result<Self, ()> { |
1586 | use Environment::*; |
1587 | |
1588 | Ok(match s { |
1589 | "unknown" => Unknown, |
1590 | "amdgiz" => AmdGiz, |
1591 | "android" => Android, |
1592 | "androideabi" => Androideabi, |
1593 | "eabi" => Eabi, |
1594 | "eabihf" => Eabihf, |
1595 | "gnu" => Gnu, |
1596 | "gnuabi64" => Gnuabi64, |
1597 | "gnueabi" => Gnueabi, |
1598 | "gnueabihf" => Gnueabihf, |
1599 | "gnuspe" => Gnuspe, |
1600 | "gnux32" => Gnux32, |
1601 | "gnu_ilp32" => GnuIlp32, |
1602 | "gnullvm" => GnuLlvm, |
1603 | "hermitkernel" => HermitKernel, |
1604 | "hurdkernel" => HurdKernel, |
1605 | "linuxkernel" => LinuxKernel, |
1606 | "macabi" => Macabi, |
1607 | "musl" => Musl, |
1608 | "musleabi" => Musleabi, |
1609 | "musleabihf" => Musleabihf, |
1610 | "muslabi64" => Muslabi64, |
1611 | "msvc" => Msvc, |
1612 | "newlib" => Newlib, |
1613 | "none" => None, |
1614 | "kernel" => Kernel, |
1615 | "uclibc" => Uclibc, |
1616 | "uclibceabi" => Uclibceabi, |
1617 | "uclibceabihf" => Uclibceabihf, |
1618 | "sgx" => Sgx, |
1619 | "sim" => Sim, |
1620 | "softfloat" => Softfloat, |
1621 | "spe" => Spe, |
1622 | "threads" => Threads, |
1623 | "ohos" => Ohos, |
1624 | _ => return Err(()), |
1625 | }) |
1626 | } |
1627 | } |
1628 | |
1629 | impl fmt::Display for BinaryFormat { |
1630 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1631 | f.write_str(&self.into_str()) |
1632 | } |
1633 | } |
1634 | |
1635 | impl FromStr for BinaryFormat { |
1636 | type Err = (); |
1637 | |
1638 | fn from_str(s: &str) -> Result<Self, ()> { |
1639 | use BinaryFormat::*; |
1640 | |
1641 | Ok(match s { |
1642 | "unknown" => Unknown, |
1643 | "elf" => Elf, |
1644 | "coff" => Coff, |
1645 | "macho" => Macho, |
1646 | "wasm" => Wasm, |
1647 | "xcoff" => Xcoff, |
1648 | _ => return Err(()), |
1649 | }) |
1650 | } |
1651 | } |
1652 | |
1653 | #[cfg (test)] |
1654 | mod tests { |
1655 | use super::*; |
1656 | use alloc::string::ToString; |
1657 | |
1658 | #[test ] |
1659 | fn roundtrip_known_triples() { |
1660 | // This list is constructed from: |
1661 | // - targets emitted by "rustup target list" |
1662 | // - targets emitted by "rustc +nightly --print target-list" |
1663 | // - targets contributors have added |
1664 | let targets = [ |
1665 | "aarch64-apple-darwin" , |
1666 | "aarch64-apple-ios" , |
1667 | "aarch64-apple-ios-macabi" , |
1668 | "aarch64-apple-ios-sim" , |
1669 | "aarch64-apple-tvos" , |
1670 | "aarch64-apple-tvos-sim" , |
1671 | "aarch64-apple-visionos" , |
1672 | "aarch64-apple-visionos-sim" , |
1673 | "aarch64-apple-watchos" , |
1674 | "aarch64-apple-watchos-sim" , |
1675 | "aarch64_be-unknown-linux-gnu" , |
1676 | "aarch64_be-unknown-linux-gnu_ilp32" , |
1677 | "aarch64_be-unknown-netbsd" , |
1678 | "aarch64-kmc-solid_asp3" , |
1679 | "aarch64-linux-android" , |
1680 | //"aarch64-nintendo-switch-freestanding", // TODO |
1681 | "aarch64-pc-windows-gnullvm" , |
1682 | "aarch64-pc-windows-msvc" , |
1683 | "aarch64-unknown-cloudabi" , |
1684 | "aarch64-unknown-freebsd" , |
1685 | "aarch64-unknown-fuchsia" , |
1686 | "aarch64-unknown-hermit" , |
1687 | "aarch64-unknown-illumos" , |
1688 | "aarch64-unknown-linux-gnu" , |
1689 | "aarch64-unknown-linux-gnu_ilp32" , |
1690 | "aarch64-unknown-linux-musl" , |
1691 | "aarch64-unknown-linux-ohos" , |
1692 | "aarch64-unknown-netbsd" , |
1693 | "aarch64-unknown-none" , |
1694 | "aarch64-unknown-none-softfloat" , |
1695 | //"aarch64-unknown-nto-qnx710", // TODO |
1696 | "aarch64-unknown-openbsd" , |
1697 | "aarch64-unknown-redox" , |
1698 | //"aarch64-unknown-teeos", // TODO |
1699 | "aarch64-unknown-uefi" , |
1700 | "aarch64-uwp-windows-msvc" , |
1701 | "aarch64-wrs-vxworks" , |
1702 | //"arm64_32-apple-watchos", // TODO |
1703 | //"arm64e-apple-darwin", // TODO |
1704 | "amdgcn-amd-amdhsa" , |
1705 | "amdgcn-amd-amdhsa-amdgiz" , |
1706 | //"arm64e-apple-ios", // TODO |
1707 | //"arm64ec-pc-windows-msvc", // TODO |
1708 | "armeb-unknown-linux-gnueabi" , |
1709 | "armebv7r-none-eabi" , |
1710 | "armebv7r-none-eabihf" , |
1711 | "arm-linux-androideabi" , |
1712 | "arm-unknown-linux-gnueabi" , |
1713 | "arm-unknown-linux-gnueabihf" , |
1714 | "arm-unknown-linux-musleabi" , |
1715 | "arm-unknown-linux-musleabihf" , |
1716 | "armv4t-none-eabi" , |
1717 | "armv4t-unknown-linux-gnueabi" , |
1718 | "armv5te-none-eabi" , |
1719 | "armv5te-unknown-linux-gnueabi" , |
1720 | "armv5te-unknown-linux-musleabi" , |
1721 | "armv5te-unknown-linux-uclibceabi" , |
1722 | "armv6k-nintendo-3ds" , |
1723 | "armv6-unknown-freebsd" , |
1724 | "armv6-unknown-netbsd-eabihf" , |
1725 | "armv7a-kmc-solid_asp3-eabi" , |
1726 | "armv7a-kmc-solid_asp3-eabihf" , |
1727 | "armv7a-none-eabi" , |
1728 | "armv7a-none-eabihf" , |
1729 | "armv7-apple-ios" , |
1730 | "armv7k-apple-watchos" , |
1731 | "armv7-linux-androideabi" , |
1732 | "armv7r-none-eabi" , |
1733 | "armv7r-none-eabihf" , |
1734 | "armv7s-apple-ios" , |
1735 | "armv7-unknown-cloudabi-eabihf" , |
1736 | //"armv7-sony-vita-newlibeabihf", // TODO |
1737 | "armv7-unknown-freebsd" , |
1738 | "armv7-unknown-linux-gnueabi" , |
1739 | "armv7-unknown-linux-gnueabihf" , |
1740 | "armv7-unknown-linux-musleabi" , |
1741 | "armv7-unknown-linux-musleabihf" , |
1742 | "armv7-unknown-linux-ohos" , |
1743 | "armv7-unknown-linux-uclibceabi" , |
1744 | "armv7-unknown-linux-uclibceabihf" , |
1745 | "armv7-unknown-netbsd-eabihf" , |
1746 | "armv7-wrs-vxworks-eabihf" , |
1747 | "asmjs-unknown-emscripten" , |
1748 | "armv8r-none-eabihf" , |
1749 | //"avr-unknown-gnu-atmega328", // TODO |
1750 | "avr-unknown-unknown" , |
1751 | "bpfeb-unknown-none" , |
1752 | "bpfel-unknown-none" , |
1753 | //"csky-unknown-linux-gnuabiv2", // TODO |
1754 | //"csky-unknown-linux-gnuabiv2hf", // TODO |
1755 | "hexagon-unknown-linux-musl" , |
1756 | "hexagon-unknown-none-elf" , |
1757 | "i386-apple-ios" , |
1758 | //"i586-pc-nto-qnx700", // TODO |
1759 | "i586-pc-windows-msvc" , |
1760 | "i586-unknown-linux-gnu" , |
1761 | "i586-unknown-linux-musl" , |
1762 | "i586-unknown-netbsd" , |
1763 | "i686-apple-darwin" , |
1764 | "i686-linux-android" , |
1765 | "i686-apple-macosx10.7.0" , |
1766 | "i686-pc-windows-gnu" , |
1767 | "i686-pc-windows-gnullvm" , |
1768 | "i686-pc-windows-msvc" , |
1769 | "i686-unknown-cloudabi" , |
1770 | "i686-unknown-dragonfly" , |
1771 | "i686-unknown-freebsd" , |
1772 | "i686-unknown-haiku" , |
1773 | "i686-unknown-hurd-gnu" , |
1774 | "i686-unknown-linux-gnu" , |
1775 | "i686-unknown-linux-musl" , |
1776 | "i686-unknown-netbsd" , |
1777 | "i686-unknown-openbsd" , |
1778 | "i686-unknown-redox" , |
1779 | "i686-unknown-uefi" , |
1780 | "i686-uwp-windows-gnu" , |
1781 | "i686-uwp-windows-msvc" , |
1782 | "i686-win7-windows-msvc" , |
1783 | "i686-wrs-vxworks" , |
1784 | "loongarch64-unknown-linux-gnu" , |
1785 | "loongarch64-unknown-linux-musl" , |
1786 | "loongarch64-unknown-none" , |
1787 | "loongarch64-unknown-none-softfloat" , |
1788 | "m68k-unknown-linux-gnu" , |
1789 | "mips64el-unknown-linux-gnuabi64" , |
1790 | "mips64el-unknown-linux-muslabi64" , |
1791 | "mips64-openwrt-linux-musl" , |
1792 | "mips64-unknown-linux-gnuabi64" , |
1793 | "mips64-unknown-linux-muslabi64" , |
1794 | "mipsel-sony-psp" , |
1795 | //"mipsel-sony-psx", // TODO |
1796 | "mipsel-unknown-linux-gnu" , |
1797 | "mipsel-unknown-linux-musl" , |
1798 | "mipsel-unknown-linux-uclibc" , |
1799 | "mipsel-unknown-netbsd" , |
1800 | "mipsel-unknown-none" , |
1801 | "mipsisa32r6el-unknown-linux-gnu" , |
1802 | "mipsisa32r6-unknown-linux-gnu" , |
1803 | "mipsisa64r6el-unknown-linux-gnuabi64" , |
1804 | "mipsisa64r6-unknown-linux-gnuabi64" , |
1805 | "mips-unknown-linux-gnu" , |
1806 | "mips-unknown-linux-musl" , |
1807 | "mips-unknown-linux-uclibc" , |
1808 | "msp430-none-elf" , |
1809 | "nvptx64-nvidia-cuda" , |
1810 | "powerpc64-ibm-aix" , |
1811 | "powerpc64le-unknown-freebsd" , |
1812 | "powerpc64le-unknown-linux-gnu" , |
1813 | "powerpc64le-unknown-linux-musl" , |
1814 | "powerpc64-unknown-freebsd" , |
1815 | "powerpc64-unknown-linux-gnu" , |
1816 | "powerpc64-unknown-linux-musl" , |
1817 | "powerpc64-unknown-openbsd" , |
1818 | "powerpc64-wrs-vxworks" , |
1819 | "powerpc-ibm-aix" , |
1820 | "powerpc-unknown-freebsd" , |
1821 | "powerpc-unknown-linux-gnu" , |
1822 | "powerpc-unknown-linux-gnuspe" , |
1823 | "powerpc-unknown-linux-musl" , |
1824 | "powerpc-unknown-netbsd" , |
1825 | "powerpc-unknown-openbsd" , |
1826 | "powerpc-wrs-vxworks" , |
1827 | "powerpc-wrs-vxworks-spe" , |
1828 | "riscv32gc-unknown-linux-gnu" , |
1829 | "riscv32gc-unknown-linux-musl" , |
1830 | "riscv32imac-esp-espidf" , |
1831 | "riscv32imac-unknown-none-elf" , |
1832 | //"riscv32imac-unknown-xous-elf", // TODO |
1833 | "riscv32imafc-esp-espidf" , |
1834 | "riscv32imafc-unknown-none-elf" , |
1835 | "riscv32ima-unknown-none-elf" , |
1836 | "riscv32imc-esp-espidf" , |
1837 | "riscv32imc-unknown-none-elf" , |
1838 | //"riscv32im-risc0-zkvm-elf", // TODO |
1839 | "riscv32im-unknown-none-elf" , |
1840 | "riscv32i-unknown-none-elf" , |
1841 | "riscv64gc-unknown-freebsd" , |
1842 | "riscv64gc-unknown-fuchsia" , |
1843 | "riscv64gc-unknown-hermit" , |
1844 | "riscv64gc-unknown-linux-gnu" , |
1845 | "riscv64gc-unknown-linux-musl" , |
1846 | "riscv64gc-unknown-netbsd" , |
1847 | "riscv64gc-unknown-none-elf" , |
1848 | "riscv64gc-unknown-openbsd" , |
1849 | "riscv64imac-unknown-none-elf" , |
1850 | "riscv64-linux-android" , |
1851 | "s390x-unknown-linux-gnu" , |
1852 | "s390x-unknown-linux-musl" , |
1853 | "sparc64-unknown-linux-gnu" , |
1854 | "sparc64-unknown-netbsd" , |
1855 | "sparc64-unknown-openbsd" , |
1856 | "sparc-unknown-linux-gnu" , |
1857 | "sparc-unknown-none-elf" , |
1858 | "sparcv9-sun-solaris" , |
1859 | "thumbv4t-none-eabi" , |
1860 | "thumbv5te-none-eabi" , |
1861 | "thumbv6m-none-eabi" , |
1862 | "thumbv7a-pc-windows-msvc" , |
1863 | "thumbv7a-uwp-windows-msvc" , |
1864 | "thumbv7em-none-eabi" , |
1865 | "thumbv7em-none-eabihf" , |
1866 | "thumbv7m-none-eabi" , |
1867 | "thumbv7neon-linux-androideabi" , |
1868 | "thumbv7neon-unknown-linux-gnueabihf" , |
1869 | "thumbv7neon-unknown-linux-musleabihf" , |
1870 | "thumbv8m.base-none-eabi" , |
1871 | "thumbv8m.main-none-eabi" , |
1872 | "thumbv8m.main-none-eabihf" , |
1873 | "wasm32-experimental-emscripten" , |
1874 | "wasm32-unknown-emscripten" , |
1875 | "wasm32-unknown-unknown" , |
1876 | "wasm32-wasi" , |
1877 | "wasm32-wasip1" , |
1878 | "wasm32-wasip1-threads" , |
1879 | "wasm32-wasip2" , |
1880 | "wasm64-unknown-unknown" , |
1881 | "wasm64-wasi" , |
1882 | "x86_64-apple-darwin" , |
1883 | "x86_64-apple-darwin23.6.0" , |
1884 | "x86_64-apple-ios" , |
1885 | "x86_64-apple-ios-macabi" , |
1886 | "x86_64-apple-tvos" , |
1887 | "x86_64-apple-watchos-sim" , |
1888 | "x86_64-fortanix-unknown-sgx" , |
1889 | "x86_64h-apple-darwin" , |
1890 | "x86_64-linux-android" , |
1891 | //"x86_64-pc-nto-qnx710", // TODO |
1892 | "x86_64-linux-kernel" , // Changed to x86_64-unknown-none-linuxkernel in 1.53.0 |
1893 | "x86_64-apple-macosx" , |
1894 | "x86_64-apple-macosx10.7.0" , |
1895 | "x86_64-pc-solaris" , |
1896 | "x86_64-pc-windows-gnu" , |
1897 | "x86_64-pc-windows-gnullvm" , |
1898 | "x86_64-pc-windows-msvc" , |
1899 | "x86_64-rumprun-netbsd" , // Removed in 1.53.0 |
1900 | "x86_64-sun-solaris" , |
1901 | "x86_64-unknown-bitrig" , |
1902 | "x86_64-unknown-cloudabi" , |
1903 | "x86_64-unikraft-linux-musl" , |
1904 | "x86_64-unknown-dragonfly" , |
1905 | "x86_64-unknown-freebsd" , |
1906 | "x86_64-unknown-fuchsia" , |
1907 | "x86_64-unknown-haiku" , |
1908 | "x86_64-unknown-hermit-kernel" , // Changed to x86_64-unknown-none-hermitkernel in 1.53.0 |
1909 | "x86_64-unknown-hermit" , |
1910 | "x86_64-unknown-illumos" , |
1911 | "x86_64-unknown-l4re-uclibc" , |
1912 | "x86_64-unknown-linux-gnu" , |
1913 | "x86_64-unknown-linux-gnux32" , |
1914 | "x86_64-unknown-linux-musl" , |
1915 | "x86_64-unknown-linux-none" , |
1916 | "x86_64-unknown-linux-ohos" , |
1917 | "x86_64-unknown-netbsd" , |
1918 | "x86_64-unknown-none" , |
1919 | "x86_64-unknown-none-hermitkernel" , |
1920 | "x86_64-unknown-none-linuxkernel" , |
1921 | "x86_64-unknown-openbsd" , |
1922 | "x86_64-unknown-redox" , |
1923 | "x86_64-unknown-uefi" , |
1924 | "x86_64-uwp-windows-gnu" , |
1925 | "x86_64-uwp-windows-msvc" , |
1926 | "x86_64-win7-windows-msvc" , |
1927 | "x86_64-wrs-vxworks" , |
1928 | "xtensa-esp32-espidf" , |
1929 | "clever-unknown-elf" , |
1930 | "xtensa-esp32-none-elf" , |
1931 | "xtensa-esp32s2-espidf" , |
1932 | "xtensa-esp32s2-none-elf" , |
1933 | "xtensa-esp32s3-espidf" , |
1934 | "xtensa-esp32s3-none-elf" , |
1935 | #[cfg (feature = "arch_zkasm" )] |
1936 | "zkasm-unknown-unknown" , |
1937 | ]; |
1938 | |
1939 | for target in targets.iter() { |
1940 | let t = Triple::from_str(target).expect("can't parse target" ); |
1941 | assert_ne!(t.architecture, Architecture::Unknown); |
1942 | assert_eq!(t.to_string(), *target, "{:#?}" , t); |
1943 | } |
1944 | } |
1945 | |
1946 | #[test ] |
1947 | fn default_format_to_elf() { |
1948 | let t = Triple::from_str("riscv64" ).expect("can't parse target" ); |
1949 | assert_eq!( |
1950 | t.architecture, |
1951 | Architecture::Riscv64(Riscv64Architecture::Riscv64), |
1952 | ); |
1953 | assert_eq!(t.vendor, Vendor::Unknown); |
1954 | assert_eq!(t.operating_system, OperatingSystem::Unknown); |
1955 | assert_eq!(t.environment, Environment::Unknown); |
1956 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
1957 | } |
1958 | |
1959 | #[test ] |
1960 | fn thumbv7em_none_eabihf() { |
1961 | let t = Triple::from_str("thumbv7em-none-eabihf" ).expect("can't parse target" ); |
1962 | assert_eq!( |
1963 | t.architecture, |
1964 | Architecture::Arm(ArmArchitecture::Thumbv7em) |
1965 | ); |
1966 | assert_eq!(t.vendor, Vendor::Unknown); |
1967 | assert_eq!(t.operating_system, OperatingSystem::None_); |
1968 | assert_eq!(t.environment, Environment::Eabihf); |
1969 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
1970 | } |
1971 | |
1972 | #[test ] |
1973 | fn fuchsia_rename() { |
1974 | // Fuchsia targets were renamed to add the `unknown`. |
1975 | assert_eq!( |
1976 | Triple::from_str("aarch64-fuchsia" ), |
1977 | Triple::from_str("aarch64-unknown-fuchsia" ) |
1978 | ); |
1979 | assert_eq!( |
1980 | Triple::from_str("x86_64-fuchsia" ), |
1981 | Triple::from_str("x86_64-unknown-fuchsia" ) |
1982 | ); |
1983 | } |
1984 | |
1985 | #[test ] |
1986 | fn custom_vendors() { |
1987 | // Test various invalid cases. |
1988 | assert!(Triple::from_str("x86_64--linux" ).is_err()); |
1989 | assert!(Triple::from_str("x86_64-42-linux" ).is_err()); |
1990 | assert!(Triple::from_str("x86_64-__customvendor__-linux" ).is_err()); |
1991 | assert!(Triple::from_str("x86_64-^-linux" ).is_err()); |
1992 | assert!(Triple::from_str("x86_64- -linux" ).is_err()); |
1993 | assert!(Triple::from_str("x86_64-CustomVendor-linux" ).is_err()); |
1994 | assert!(Triple::from_str("x86_64-linux-linux" ).is_err()); |
1995 | assert!(Triple::from_str("x86_64-x86_64-linux" ).is_err()); |
1996 | assert!(Triple::from_str("x86_64-elf-linux" ).is_err()); |
1997 | assert!(Triple::from_str("x86_64-gnu-linux" ).is_err()); |
1998 | assert!(Triple::from_str("x86_64-linux-customvendor" ).is_err()); |
1999 | assert!(Triple::from_str("customvendor" ).is_err()); |
2000 | assert!(Triple::from_str("customvendor-x86_64" ).is_err()); |
2001 | assert!(Triple::from_str("x86_64-" ).is_err()); |
2002 | assert!(Triple::from_str("x86_64--" ).is_err()); |
2003 | |
2004 | // Test various Unicode things. |
2005 | assert!( |
2006 | Triple::from_str("x86_64-𝓬𝓾𝓼𝓽𝓸𝓶𝓿𝓮𝓷𝓭𝓸𝓻-linux" ).is_err(), |
2007 | "unicode font hazard" |
2008 | ); |
2009 | assert!( |
2010 | Triple::from_str("x86_64-ćúśtőḿvéńdőŕ-linux" ).is_err(), |
2011 | "diacritical mark stripping hazard" |
2012 | ); |
2013 | assert!( |
2014 | Triple::from_str("x86_64-customvendοr-linux" ).is_err(), |
2015 | "homoglyph hazard" |
2016 | ); |
2017 | assert!(Triple::from_str("x86_64-customvendor-linux" ).is_ok()); |
2018 | assert!( |
2019 | Triple::from_str("x86_64-ffi-linux" ).is_err(), |
2020 | "normalization hazard" |
2021 | ); |
2022 | assert!(Triple::from_str("x86_64-ffi-linux" ).is_ok()); |
2023 | assert!( |
2024 | Triple::from_str("x86_64-customvendor-linux" ).is_err(), |
2025 | "zero-width character hazard" |
2026 | ); |
2027 | assert!( |
2028 | Triple::from_str("x86_64-customvendor-linux" ).is_err(), |
2029 | "BOM hazard" |
2030 | ); |
2031 | |
2032 | // Test some valid cases. |
2033 | let t = Triple::from_str("x86_64-customvendor-linux" ) |
2034 | .expect("can't parse target with custom vendor" ); |
2035 | assert_eq!(t.architecture, Architecture::X86_64); |
2036 | assert_eq!( |
2037 | t.vendor, |
2038 | Vendor::Custom(CustomVendor::Static("customvendor" )) |
2039 | ); |
2040 | assert_eq!(t.operating_system, OperatingSystem::Linux); |
2041 | assert_eq!(t.environment, Environment::Unknown); |
2042 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
2043 | assert_eq!(t.to_string(), "x86_64-customvendor-linux" ); |
2044 | |
2045 | let t = |
2046 | Triple::from_str("x86_64-customvendor" ).expect("can't parse target with custom vendor" ); |
2047 | assert_eq!(t.architecture, Architecture::X86_64); |
2048 | assert_eq!( |
2049 | t.vendor, |
2050 | Vendor::Custom(CustomVendor::Static("customvendor" )) |
2051 | ); |
2052 | assert_eq!(t.operating_system, OperatingSystem::Unknown); |
2053 | assert_eq!(t.environment, Environment::Unknown); |
2054 | assert_eq!(t.binary_format, BinaryFormat::Elf); |
2055 | |
2056 | assert_eq!( |
2057 | Triple::from_str("unknown-foo" ), |
2058 | Ok(Triple { |
2059 | architecture: Architecture::Unknown, |
2060 | vendor: Vendor::Custom(CustomVendor::Static("foo" )), |
2061 | operating_system: OperatingSystem::Unknown, |
2062 | environment: Environment::Unknown, |
2063 | binary_format: BinaryFormat::Unknown, |
2064 | }) |
2065 | ); |
2066 | } |
2067 | |
2068 | #[test ] |
2069 | fn deployment_version_parsing() { |
2070 | assert_eq!( |
2071 | Triple::from_str("aarch64-apple-macosx" ), |
2072 | Ok(Triple { |
2073 | architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64), |
2074 | vendor: Vendor::Apple, |
2075 | operating_system: OperatingSystem::MacOSX(None), |
2076 | environment: Environment::Unknown, |
2077 | binary_format: BinaryFormat::Macho, |
2078 | }) |
2079 | ); |
2080 | |
2081 | assert_eq!( |
2082 | Triple::from_str("aarch64-apple-macosx10.14.6" ), |
2083 | Ok(Triple { |
2084 | architecture: Architecture::Aarch64(Aarch64Architecture::Aarch64), |
2085 | vendor: Vendor::Apple, |
2086 | operating_system: OperatingSystem::MacOSX(Some(DeploymentTarget { |
2087 | major: 10, |
2088 | minor: 14, |
2089 | patch: 6, |
2090 | })), |
2091 | environment: Environment::Unknown, |
2092 | binary_format: BinaryFormat::Macho, |
2093 | }) |
2094 | ); |
2095 | |
2096 | let expected = Triple { |
2097 | architecture: Architecture::X86_64, |
2098 | vendor: Vendor::Apple, |
2099 | operating_system: OperatingSystem::Darwin(Some(DeploymentTarget { |
2100 | major: 23, |
2101 | minor: 0, |
2102 | patch: 0, |
2103 | })), |
2104 | environment: Environment::Unknown, |
2105 | binary_format: BinaryFormat::Macho, |
2106 | }; |
2107 | assert_eq!( |
2108 | Triple::from_str("x86_64-apple-darwin23" ), |
2109 | Ok(expected.clone()) |
2110 | ); |
2111 | assert_eq!( |
2112 | Triple::from_str("x86_64-apple-darwin23.0" ), |
2113 | Ok(expected.clone()) |
2114 | ); |
2115 | assert_eq!(Triple::from_str("x86_64-apple-darwin23.0.0" ), Ok(expected)); |
2116 | |
2117 | assert!(Triple::from_str("x86_64-apple-darwin." ).is_err()); |
2118 | assert!(Triple::from_str("x86_64-apple-darwin23.0.0.0" ).is_err()); |
2119 | } |
2120 | } |
2121 | |