Skip to main content

uv_configuration/
target_triple.rs

1use tracing::debug;
2
3use uv_pep508::MarkerEnvironment;
4use uv_platform_tags::{Arch, Os, Platform};
5use uv_static::EnvVars;
6
7/// The supported target triples. Each triple consists of an architecture, vendor, and operating
8/// system.
9///
10/// See: <https://doc.rust-lang.org/nightly/rustc/platform-support.html>
11#[derive(Debug, Clone, Copy, Eq, PartialEq, serde::Deserialize)]
12#[serde(deny_unknown_fields, rename_all = "kebab-case")]
13#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
14#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
15pub enum TargetTriple {
16    /// An alias for `x86_64-pc-windows-msvc`, the default target for Windows.
17    Windows,
18
19    /// An alias for `x86_64-unknown-linux-gnu`, the default target for Linux.
20    Linux,
21
22    /// An alias for `aarch64-apple-darwin`, the default target for macOS.
23    Macos,
24
25    /// A 64-bit x86 Windows target.
26    #[cfg_attr(feature = "clap", value(name = "x86_64-pc-windows-msvc"))]
27    #[serde(rename = "x86_64-pc-windows-msvc")]
28    #[serde(alias = "x8664-pc-windows-msvc")]
29    X8664PcWindowsMsvc,
30
31    /// An ARM64 Windows target.
32    #[cfg_attr(feature = "clap", value(name = "aarch64-pc-windows-msvc"))]
33    #[serde(rename = "aarch64-pc-windows-msvc")]
34    #[serde(alias = "arm64-pc-windows-msvc")]
35    Aarch64PcWindowsMsvc,
36
37    /// A 32-bit x86 Windows target.
38    #[cfg_attr(feature = "clap", value(name = "i686-pc-windows-msvc"))]
39    #[serde(rename = "i686-pc-windows-msvc")]
40    I686PcWindowsMsvc,
41
42    /// An x86 Linux target. Equivalent to `x86_64-manylinux_2_28`.
43    #[cfg_attr(feature = "clap", value(name = "x86_64-unknown-linux-gnu"))]
44    #[serde(rename = "x86_64-unknown-linux-gnu")]
45    #[serde(alias = "x8664-unknown-linux-gnu")]
46    X8664UnknownLinuxGnu,
47
48    /// An ARM-based macOS target, as seen on Apple Silicon devices
49    ///
50    /// By default, assumes the least-recent, non-EOL macOS version (13.0), but respects
51    /// the `MACOSX_DEPLOYMENT_TARGET` environment variable if set.
52    #[cfg_attr(feature = "clap", value(name = "aarch64-apple-darwin"))]
53    #[serde(rename = "aarch64-apple-darwin")]
54    Aarch64AppleDarwin,
55
56    /// An x86 macOS target.
57    ///
58    /// By default, assumes the least-recent, non-EOL macOS version (13.0), but respects
59    /// the `MACOSX_DEPLOYMENT_TARGET` environment variable if set.
60    #[cfg_attr(feature = "clap", value(name = "x86_64-apple-darwin"))]
61    #[serde(rename = "x86_64-apple-darwin")]
62    #[serde(alias = "x8664-apple-darwin")]
63    X8664AppleDarwin,
64
65    /// An ARM64 Linux target. Equivalent to `aarch64-manylinux_2_28`.
66    #[cfg_attr(feature = "clap", value(name = "aarch64-unknown-linux-gnu"))]
67    #[serde(rename = "aarch64-unknown-linux-gnu")]
68    Aarch64UnknownLinuxGnu,
69
70    /// An ARM64 Linux target.
71    #[cfg_attr(feature = "clap", value(name = "aarch64-unknown-linux-musl"))]
72    #[serde(rename = "aarch64-unknown-linux-musl")]
73    Aarch64UnknownLinuxMusl,
74
75    /// An `x86_64` Linux target.
76    #[cfg_attr(feature = "clap", value(name = "x86_64-unknown-linux-musl"))]
77    #[serde(rename = "x86_64-unknown-linux-musl")]
78    #[serde(alias = "x8664-unknown-linux-musl")]
79    X8664UnknownLinuxMusl,
80
81    /// A RISCV64 Linux target.
82    #[cfg_attr(feature = "clap", value(name = "riscv64-unknown-linux"))]
83    #[serde(rename = "riscv64-unknown-linux")]
84    Riscv64UnknownLinuxGnu,
85
86    /// An `x86_64` target for the `manylinux2014` platform. Equivalent to `x86_64-manylinux_2_17`.
87    #[cfg_attr(
88        feature = "clap",
89        value(name = "x86_64-manylinux2014", alias = "manylinux2014_x86_64")
90    )]
91    #[serde(rename = "x86_64-manylinux2014")]
92    #[serde(alias = "x8664-manylinux2014")]
93    #[serde(alias = "manylinux2014_x86_64")]
94    X8664Manylinux2014,
95
96    /// An `x86_64` target for the `manylinux_2_17` platform.
97    #[cfg_attr(
98        feature = "clap",
99        value(name = "x86_64-manylinux_2_17", alias = "manylinux_2_17_x86_64")
100    )]
101    #[serde(rename = "x86_64-manylinux_2_17")]
102    #[serde(alias = "x8664-manylinux217")]
103    #[serde(alias = "manylinux_2_17_x86_64")]
104    X8664Manylinux217,
105
106    /// An `x86_64` target for the `manylinux_2_28` platform.
107    #[cfg_attr(
108        feature = "clap",
109        value(name = "x86_64-manylinux_2_28", alias = "manylinux_2_28_x86_64")
110    )]
111    #[serde(rename = "x86_64-manylinux_2_28")]
112    #[serde(alias = "x8664-manylinux228")]
113    #[serde(alias = "manylinux_2_28_x86_64")]
114    X8664Manylinux228,
115
116    /// An `x86_64` target for the `manylinux_2_31` platform.
117    #[cfg_attr(
118        feature = "clap",
119        value(name = "x86_64-manylinux_2_31", alias = "manylinux_2_31_x86_64")
120    )]
121    #[serde(rename = "x86_64-manylinux_2_31")]
122    #[serde(alias = "x8664-manylinux231")]
123    #[serde(alias = "manylinux_2_31_x86_64")]
124    X8664Manylinux231,
125
126    /// An `x86_64` target for the `manylinux_2_32` platform.
127    #[cfg_attr(
128        feature = "clap",
129        value(name = "x86_64-manylinux_2_32", alias = "manylinux_2_32_x86_64")
130    )]
131    #[serde(rename = "x86_64-manylinux_2_32")]
132    #[serde(alias = "x8664-manylinux232")]
133    #[serde(alias = "manylinux_2_32_x86_64")]
134    X8664Manylinux232,
135
136    /// An `x86_64` target for the `manylinux_2_33` platform.
137    #[cfg_attr(
138        feature = "clap",
139        value(name = "x86_64-manylinux_2_33", alias = "manylinux_2_33_x86_64")
140    )]
141    #[serde(rename = "x86_64-manylinux_2_33")]
142    #[serde(alias = "x8664-manylinux233")]
143    #[serde(alias = "manylinux_2_33_x86_64")]
144    X8664Manylinux233,
145
146    /// An `x86_64` target for the `manylinux_2_34` platform.
147    #[cfg_attr(
148        feature = "clap",
149        value(name = "x86_64-manylinux_2_34", alias = "manylinux_2_34_x86_64")
150    )]
151    #[serde(rename = "x86_64-manylinux_2_34")]
152    #[serde(alias = "x8664-manylinux234")]
153    #[serde(alias = "manylinux_2_34_x86_64")]
154    X8664Manylinux234,
155
156    /// An `x86_64` target for the `manylinux_2_35` platform.
157    #[cfg_attr(
158        feature = "clap",
159        value(name = "x86_64-manylinux_2_35", alias = "manylinux_2_35_x86_64")
160    )]
161    #[serde(rename = "x86_64-manylinux_2_35")]
162    #[serde(alias = "x8664-manylinux235")]
163    #[serde(alias = "manylinux_2_35_x86_64")]
164    X8664Manylinux235,
165
166    /// An `x86_64` target for the `manylinux_2_36` platform.
167    #[cfg_attr(
168        feature = "clap",
169        value(name = "x86_64-manylinux_2_36", alias = "manylinux_2_36_x86_64")
170    )]
171    #[serde(rename = "x86_64-manylinux_2_36")]
172    #[serde(alias = "x8664-manylinux236")]
173    #[serde(alias = "manylinux_2_36_x86_64")]
174    X8664Manylinux236,
175
176    /// An `x86_64` target for the `manylinux_2_37` platform.
177    #[cfg_attr(
178        feature = "clap",
179        value(name = "x86_64-manylinux_2_37", alias = "manylinux_2_37_x86_64")
180    )]
181    #[serde(rename = "x86_64-manylinux_2_37")]
182    #[serde(alias = "x8664-manylinux237")]
183    #[serde(alias = "manylinux_2_37_x86_64")]
184    X8664Manylinux237,
185
186    /// An `x86_64` target for the `manylinux_2_38` platform.
187    #[cfg_attr(
188        feature = "clap",
189        value(name = "x86_64-manylinux_2_38", alias = "manylinux_2_38_x86_64")
190    )]
191    #[serde(rename = "x86_64-manylinux_2_38")]
192    #[serde(alias = "x8664-manylinux238")]
193    #[serde(alias = "manylinux_2_38_x86_64")]
194    X8664Manylinux238,
195
196    /// An `x86_64` target for the `manylinux_2_39` platform.
197    #[cfg_attr(
198        feature = "clap",
199        value(name = "x86_64-manylinux_2_39", alias = "manylinux_2_39_x86_64")
200    )]
201    #[serde(rename = "x86_64-manylinux_2_39")]
202    #[serde(alias = "x8664-manylinux239")]
203    #[serde(alias = "manylinux_2_39_x86_64")]
204    X8664Manylinux239,
205
206    /// An `x86_64` target for the `manylinux_2_40` platform.
207    #[cfg_attr(
208        feature = "clap",
209        value(name = "x86_64-manylinux_2_40", alias = "manylinux_2_40_x86_64")
210    )]
211    #[serde(rename = "x86_64-manylinux_2_40")]
212    #[serde(alias = "x8664-manylinux240")]
213    #[serde(alias = "manylinux_2_40_x86_64")]
214    X8664Manylinux240,
215
216    /// An ARM64 target for the `manylinux2014` platform. Equivalent to `aarch64-manylinux_2_17`.
217    #[cfg_attr(
218        feature = "clap",
219        value(name = "aarch64-manylinux2014", alias = "manylinux2014_aarch64")
220    )]
221    #[serde(rename = "aarch64-manylinux2014")]
222    #[serde(alias = "manylinux2014_aarch64")]
223    Aarch64Manylinux2014,
224
225    /// An ARM64 target for the `manylinux_2_17` platform.
226    #[cfg_attr(
227        feature = "clap",
228        value(name = "aarch64-manylinux_2_17", alias = "manylinux_2_17_aarch64")
229    )]
230    #[serde(rename = "aarch64-manylinux_2_17")]
231    #[serde(alias = "aarch64-manylinux217")]
232    #[serde(alias = "manylinux_2_17_aarch64")]
233    Aarch64Manylinux217,
234
235    /// An ARM64 target for the `manylinux_2_28` platform.
236    #[cfg_attr(
237        feature = "clap",
238        value(name = "aarch64-manylinux_2_28", alias = "manylinux_2_28_aarch64")
239    )]
240    #[serde(rename = "aarch64-manylinux_2_28")]
241    #[serde(alias = "aarch64-manylinux228")]
242    #[serde(alias = "manylinux_2_28_aarch64")]
243    Aarch64Manylinux228,
244
245    /// An ARM64 target for the `manylinux_2_31` platform.
246    #[cfg_attr(
247        feature = "clap",
248        value(name = "aarch64-manylinux_2_31", alias = "manylinux_2_31_aarch64")
249    )]
250    #[serde(rename = "aarch64-manylinux_2_31")]
251    #[serde(alias = "aarch64-manylinux231")]
252    #[serde(alias = "manylinux_2_31_aarch64")]
253    Aarch64Manylinux231,
254
255    /// An ARM64 target for the `manylinux_2_32` platform.
256    #[cfg_attr(
257        feature = "clap",
258        value(name = "aarch64-manylinux_2_32", alias = "manylinux_2_32_aarch64")
259    )]
260    #[serde(rename = "aarch64-manylinux_2_32")]
261    #[serde(alias = "aarch64-manylinux232")]
262    #[serde(alias = "manylinux_2_32_aarch64")]
263    Aarch64Manylinux232,
264
265    /// An ARM64 target for the `manylinux_2_33` platform.
266    #[cfg_attr(
267        feature = "clap",
268        value(name = "aarch64-manylinux_2_33", alias = "manylinux_2_33_aarch64")
269    )]
270    #[serde(rename = "aarch64-manylinux_2_33")]
271    #[serde(alias = "aarch64-manylinux233")]
272    #[serde(alias = "manylinux_2_33_aarch64")]
273    Aarch64Manylinux233,
274
275    /// An ARM64 target for the `manylinux_2_34` platform.
276    #[cfg_attr(
277        feature = "clap",
278        value(name = "aarch64-manylinux_2_34", alias = "manylinux_2_34_aarch64")
279    )]
280    #[serde(rename = "aarch64-manylinux_2_34")]
281    #[serde(alias = "aarch64-manylinux234")]
282    #[serde(alias = "manylinux_2_34_aarch64")]
283    Aarch64Manylinux234,
284
285    /// An ARM64 target for the `manylinux_2_35` platform.
286    #[cfg_attr(
287        feature = "clap",
288        value(name = "aarch64-manylinux_2_35", alias = "manylinux_2_35_aarch64")
289    )]
290    #[serde(rename = "aarch64-manylinux_2_35")]
291    #[serde(alias = "aarch64-manylinux235")]
292    #[serde(alias = "manylinux_2_35_aarch64")]
293    Aarch64Manylinux235,
294
295    /// An ARM64 target for the `manylinux_2_36` platform.
296    #[cfg_attr(
297        feature = "clap",
298        value(name = "aarch64-manylinux_2_36", alias = "manylinux_2_36_aarch64")
299    )]
300    #[serde(rename = "aarch64-manylinux_2_36")]
301    #[serde(alias = "aarch64-manylinux236")]
302    #[serde(alias = "manylinux_2_36_aarch64")]
303    Aarch64Manylinux236,
304
305    /// An ARM64 target for the `manylinux_2_37` platform.
306    #[cfg_attr(
307        feature = "clap",
308        value(name = "aarch64-manylinux_2_37", alias = "manylinux_2_37_aarch64")
309    )]
310    #[serde(rename = "aarch64-manylinux_2_37")]
311    #[serde(alias = "aarch64-manylinux237")]
312    #[serde(alias = "manylinux_2_37_aarch64")]
313    Aarch64Manylinux237,
314
315    /// An ARM64 target for the `manylinux_2_38` platform.
316    #[cfg_attr(
317        feature = "clap",
318        value(name = "aarch64-manylinux_2_38", alias = "manylinux_2_38_aarch64")
319    )]
320    #[serde(rename = "aarch64-manylinux_2_38")]
321    #[serde(alias = "aarch64-manylinux238")]
322    #[serde(alias = "manylinux_2_38_aarch64")]
323    Aarch64Manylinux238,
324
325    /// An ARM64 target for the `manylinux_2_39` platform.
326    #[cfg_attr(
327        feature = "clap",
328        value(name = "aarch64-manylinux_2_39", alias = "manylinux_2_39_aarch64")
329    )]
330    #[serde(rename = "aarch64-manylinux_2_39")]
331    #[serde(alias = "aarch64-manylinux239")]
332    #[serde(alias = "manylinux_2_39_aarch64")]
333    Aarch64Manylinux239,
334
335    /// An ARM64 target for the `manylinux_2_40` platform.
336    #[cfg_attr(
337        feature = "clap",
338        value(name = "aarch64-manylinux_2_40", alias = "manylinux_2_40_aarch64")
339    )]
340    #[serde(rename = "aarch64-manylinux_2_40")]
341    #[serde(alias = "aarch64-manylinux240")]
342    #[serde(alias = "manylinux_2_40_aarch64")]
343    Aarch64Manylinux240,
344
345    /// An ARM64 Android target.
346    ///
347    /// By default uses Android API level 24, but respects
348    /// the `ANDROID_API_LEVEL` environment variable if set.
349    #[cfg_attr(feature = "clap", value(name = "aarch64-linux-android"))]
350    #[serde(rename = "aarch64-linux-android")]
351    Aarch64LinuxAndroid,
352
353    /// An `x86_64` Android target.
354    ///
355    /// By default uses Android API level 24, but respects
356    /// the `ANDROID_API_LEVEL` environment variable if set.
357    #[cfg_attr(feature = "clap", value(name = "x86_64-linux-android"))]
358    #[serde(rename = "x86_64-linux-android")]
359    X8664LinuxAndroid,
360
361    /// A wasm32 target using the Pyodide 2024 platform. Meant for use with Python 3.12.
362    /// See <https://pyodide.org/en/stable/development/abi/312.html>
363    #[cfg_attr(feature = "clap", value(name = "wasm32-pyodide2024"))]
364    Wasm32Pyodide2024,
365
366    /// A wasm32 target using the Pyodide 2025 platform. Meant for use with Python 3.13.
367    /// See <https://pyodide.org/en/stable/development/abi/313.html>
368    #[cfg_attr(feature = "clap", value(name = "wasm32-pyodide2025"))]
369    Wasm32Pyodide2025,
370
371    /// An ARM64 target for iOS device
372    ///
373    /// By default, iOS 13.0 is used, but respects the `IPHONEOS_DEPLOYMENT_TARGET`
374    /// environment variable if set.
375    #[cfg_attr(feature = "clap", value(name = "arm64-apple-ios"))]
376    #[serde(rename = "arm64-apple-ios")]
377    Arm64Ios,
378
379    /// An ARM64 target for iOS simulator
380    ///
381    /// By default, iOS 13.0 is used, but respects the `IPHONEOS_DEPLOYMENT_TARGET`
382    /// environment variable if set.
383    #[cfg_attr(feature = "clap", value(name = "arm64-apple-ios-simulator"))]
384    #[serde(rename = "arm64-apple-ios-simulator")]
385    Arm64IosSimulator,
386
387    /// An `x86_64` target for iOS simulator
388    ///
389    /// By default, iOS 13.0 is used, but respects the `IPHONEOS_DEPLOYMENT_TARGET`
390    /// environment variable if set.
391    #[cfg_attr(feature = "clap", value(name = "x86_64-apple-ios-simulator"))]
392    #[serde(rename = "x86_64-apple-ios-simulator")]
393    X8664IosSimulator,
394}
395
396impl TargetTriple {
397    /// Return the [`Platform`] for the target.
398    pub fn platform(self) -> Platform {
399        match self {
400            Self::Windows | Self::X8664PcWindowsMsvc => Platform::new(Os::Windows, Arch::X86_64),
401            Self::Aarch64PcWindowsMsvc => Platform::new(Os::Windows, Arch::Aarch64),
402            Self::Linux | Self::X8664UnknownLinuxGnu => Platform::new(
403                Os::Manylinux {
404                    major: 2,
405                    minor: 28,
406                },
407                Arch::X86_64,
408            ),
409            Self::Macos | Self::Aarch64AppleDarwin => {
410                let (major, minor) = macos_deployment_target().map_or((13, 0), |(major, minor)| {
411                    debug!("Found macOS deployment target: {}.{}", major, minor);
412                    (major, minor)
413                });
414                Platform::new(Os::Macos { major, minor }, Arch::Aarch64)
415            }
416            Self::I686PcWindowsMsvc => Platform::new(Os::Windows, Arch::X86),
417            Self::X8664AppleDarwin => {
418                let (major, minor) = macos_deployment_target().map_or((13, 0), |(major, minor)| {
419                    debug!("Found macOS deployment target: {}.{}", major, minor);
420                    (major, minor)
421                });
422                Platform::new(Os::Macos { major, minor }, Arch::X86_64)
423            }
424            Self::Aarch64UnknownLinuxGnu => Platform::new(
425                Os::Manylinux {
426                    major: 2,
427                    minor: 28,
428                },
429                Arch::Aarch64,
430            ),
431            Self::Riscv64UnknownLinuxGnu => Platform::new(
432                Os::Manylinux {
433                    major: 2,
434                    minor: 39,
435                },
436                Arch::Riscv64,
437            ),
438            Self::Aarch64UnknownLinuxMusl => {
439                Platform::new(Os::Musllinux { major: 1, minor: 2 }, Arch::Aarch64)
440            }
441            Self::X8664UnknownLinuxMusl => {
442                Platform::new(Os::Musllinux { major: 1, minor: 2 }, Arch::X86_64)
443            }
444            Self::X8664Manylinux2014 => Platform::new(
445                Os::Manylinux {
446                    major: 2,
447                    minor: 17,
448                },
449                Arch::X86_64,
450            ),
451            Self::X8664Manylinux217 => Platform::new(
452                Os::Manylinux {
453                    major: 2,
454                    minor: 17,
455                },
456                Arch::X86_64,
457            ),
458            Self::X8664Manylinux228 => Platform::new(
459                Os::Manylinux {
460                    major: 2,
461                    minor: 28,
462                },
463                Arch::X86_64,
464            ),
465            Self::X8664Manylinux231 => Platform::new(
466                Os::Manylinux {
467                    major: 2,
468                    minor: 31,
469                },
470                Arch::X86_64,
471            ),
472            Self::X8664Manylinux232 => Platform::new(
473                Os::Manylinux {
474                    major: 2,
475                    minor: 32,
476                },
477                Arch::X86_64,
478            ),
479            Self::X8664Manylinux233 => Platform::new(
480                Os::Manylinux {
481                    major: 2,
482                    minor: 33,
483                },
484                Arch::X86_64,
485            ),
486            Self::X8664Manylinux234 => Platform::new(
487                Os::Manylinux {
488                    major: 2,
489                    minor: 34,
490                },
491                Arch::X86_64,
492            ),
493            Self::X8664Manylinux235 => Platform::new(
494                Os::Manylinux {
495                    major: 2,
496                    minor: 35,
497                },
498                Arch::X86_64,
499            ),
500            Self::X8664Manylinux236 => Platform::new(
501                Os::Manylinux {
502                    major: 2,
503                    minor: 36,
504                },
505                Arch::X86_64,
506            ),
507            Self::X8664Manylinux237 => Platform::new(
508                Os::Manylinux {
509                    major: 2,
510                    minor: 37,
511                },
512                Arch::X86_64,
513            ),
514            Self::X8664Manylinux238 => Platform::new(
515                Os::Manylinux {
516                    major: 2,
517                    minor: 38,
518                },
519                Arch::X86_64,
520            ),
521            Self::X8664Manylinux239 => Platform::new(
522                Os::Manylinux {
523                    major: 2,
524                    minor: 39,
525                },
526                Arch::X86_64,
527            ),
528            Self::X8664Manylinux240 => Platform::new(
529                Os::Manylinux {
530                    major: 2,
531                    minor: 40,
532                },
533                Arch::X86_64,
534            ),
535            Self::Aarch64Manylinux2014 => Platform::new(
536                Os::Manylinux {
537                    major: 2,
538                    minor: 17,
539                },
540                Arch::Aarch64,
541            ),
542            Self::Aarch64Manylinux217 => Platform::new(
543                Os::Manylinux {
544                    major: 2,
545                    minor: 17,
546                },
547                Arch::Aarch64,
548            ),
549            Self::Aarch64Manylinux228 => Platform::new(
550                Os::Manylinux {
551                    major: 2,
552                    minor: 28,
553                },
554                Arch::Aarch64,
555            ),
556            Self::Aarch64Manylinux231 => Platform::new(
557                Os::Manylinux {
558                    major: 2,
559                    minor: 31,
560                },
561                Arch::Aarch64,
562            ),
563            Self::Aarch64Manylinux232 => Platform::new(
564                Os::Manylinux {
565                    major: 2,
566                    minor: 32,
567                },
568                Arch::Aarch64,
569            ),
570            Self::Aarch64Manylinux233 => Platform::new(
571                Os::Manylinux {
572                    major: 2,
573                    minor: 33,
574                },
575                Arch::Aarch64,
576            ),
577            Self::Aarch64Manylinux234 => Platform::new(
578                Os::Manylinux {
579                    major: 2,
580                    minor: 34,
581                },
582                Arch::Aarch64,
583            ),
584            Self::Aarch64Manylinux235 => Platform::new(
585                Os::Manylinux {
586                    major: 2,
587                    minor: 35,
588                },
589                Arch::Aarch64,
590            ),
591            Self::Aarch64Manylinux236 => Platform::new(
592                Os::Manylinux {
593                    major: 2,
594                    minor: 36,
595                },
596                Arch::Aarch64,
597            ),
598            Self::Aarch64Manylinux237 => Platform::new(
599                Os::Manylinux {
600                    major: 2,
601                    minor: 37,
602                },
603                Arch::Aarch64,
604            ),
605            Self::Aarch64Manylinux238 => Platform::new(
606                Os::Manylinux {
607                    major: 2,
608                    minor: 38,
609                },
610                Arch::Aarch64,
611            ),
612            Self::Aarch64Manylinux239 => Platform::new(
613                Os::Manylinux {
614                    major: 2,
615                    minor: 39,
616                },
617                Arch::Aarch64,
618            ),
619            Self::Aarch64Manylinux240 => Platform::new(
620                Os::Manylinux {
621                    major: 2,
622                    minor: 40,
623                },
624                Arch::Aarch64,
625            ),
626            Self::Wasm32Pyodide2024 => Platform::new(
627                Os::Pyodide {
628                    major: 2024,
629                    minor: 0,
630                },
631                Arch::Wasm32,
632            ),
633            Self::Wasm32Pyodide2025 => Platform::new(
634                Os::Pyodide {
635                    major: 2025,
636                    minor: 0,
637                },
638                Arch::Wasm32,
639            ),
640            Self::Aarch64LinuxAndroid => {
641                let api_level = android_api_level().map_or(24, |api_level| {
642                    debug!("Found Android API level: {}", api_level);
643                    api_level
644                });
645                Platform::new(Os::Android { api_level }, Arch::Aarch64)
646            }
647            Self::X8664LinuxAndroid => {
648                let api_level = android_api_level().map_or(24, |api_level| {
649                    debug!("Found Android API level: {}", api_level);
650                    api_level
651                });
652                Platform::new(Os::Android { api_level }, Arch::X86_64)
653            }
654            Self::Arm64Ios => {
655                let (major, minor) = ios_deployment_target().map_or((13, 0), |(major, minor)| {
656                    debug!("Found iOS deployment target: {}.{}", major, minor);
657                    (major, minor)
658                });
659                Platform::new(
660                    Os::Ios {
661                        major,
662                        minor,
663                        simulator: false,
664                    },
665                    Arch::Aarch64,
666                )
667            }
668            Self::Arm64IosSimulator => {
669                let (major, minor) = ios_deployment_target().map_or((13, 0), |(major, minor)| {
670                    debug!("Found iOS deployment target: {}.{}", major, minor);
671                    (major, minor)
672                });
673                Platform::new(
674                    Os::Ios {
675                        major,
676                        minor,
677                        simulator: true,
678                    },
679                    Arch::Aarch64,
680                )
681            }
682            Self::X8664IosSimulator => {
683                let (major, minor) = ios_deployment_target().map_or((13, 0), |(major, minor)| {
684                    debug!("Found iOS deployment target: {}.{}", major, minor);
685                    (major, minor)
686                });
687                Platform::new(
688                    Os::Ios {
689                        major,
690                        minor,
691                        simulator: true,
692                    },
693                    Arch::X86_64,
694                )
695            }
696        }
697    }
698
699    /// Return the `platform_machine` value for the target.
700    fn platform_machine(self) -> &'static str {
701        match self {
702            Self::Windows | Self::X8664PcWindowsMsvc => "x86_64",
703            Self::Aarch64PcWindowsMsvc => "ARM64",
704            Self::Linux | Self::X8664UnknownLinuxGnu => "x86_64",
705            Self::Macos | Self::Aarch64AppleDarwin => "arm64",
706            Self::I686PcWindowsMsvc => "x86",
707            Self::X8664AppleDarwin => "x86_64",
708            Self::Aarch64UnknownLinuxGnu => "aarch64",
709            Self::Aarch64UnknownLinuxMusl => "aarch64",
710            Self::X8664UnknownLinuxMusl => "x86_64",
711            Self::Riscv64UnknownLinuxGnu => "riscv64",
712            Self::X8664Manylinux2014 => "x86_64",
713            Self::X8664Manylinux217 => "x86_64",
714            Self::X8664Manylinux228 => "x86_64",
715            Self::X8664Manylinux231 => "x86_64",
716            Self::X8664Manylinux232 => "x86_64",
717            Self::X8664Manylinux233 => "x86_64",
718            Self::X8664Manylinux234 => "x86_64",
719            Self::X8664Manylinux235 => "x86_64",
720            Self::X8664Manylinux236 => "x86_64",
721            Self::X8664Manylinux237 => "x86_64",
722            Self::X8664Manylinux238 => "x86_64",
723            Self::X8664Manylinux239 => "x86_64",
724            Self::X8664Manylinux240 => "x86_64",
725            Self::Aarch64Manylinux2014 => "aarch64",
726            Self::Aarch64Manylinux217 => "aarch64",
727            Self::Aarch64Manylinux228 => "aarch64",
728            Self::Aarch64Manylinux231 => "aarch64",
729            Self::Aarch64Manylinux232 => "aarch64",
730            Self::Aarch64Manylinux233 => "aarch64",
731            Self::Aarch64Manylinux234 => "aarch64",
732            Self::Aarch64Manylinux235 => "aarch64",
733            Self::Aarch64Manylinux236 => "aarch64",
734            Self::Aarch64Manylinux237 => "aarch64",
735            Self::Aarch64Manylinux238 => "aarch64",
736            Self::Aarch64Manylinux239 => "aarch64",
737            Self::Aarch64Manylinux240 => "aarch64",
738            Self::Aarch64LinuxAndroid => "aarch64",
739            Self::X8664LinuxAndroid => "x86_64",
740            Self::Wasm32Pyodide2024 => "wasm32",
741            Self::Wasm32Pyodide2025 => "wasm32",
742            Self::Arm64Ios => "arm64",
743            Self::Arm64IosSimulator => "arm64",
744            Self::X8664IosSimulator => "x86_64",
745        }
746    }
747
748    /// Return the `platform_system` value for the target.
749    fn platform_system(self) -> &'static str {
750        match self {
751            Self::Windows | Self::X8664PcWindowsMsvc => "Windows",
752            Self::Aarch64PcWindowsMsvc => "Windows",
753            Self::Linux | Self::X8664UnknownLinuxGnu => "Linux",
754            Self::Macos | Self::Aarch64AppleDarwin => "Darwin",
755            Self::I686PcWindowsMsvc => "Windows",
756            Self::X8664AppleDarwin => "Darwin",
757            Self::Aarch64UnknownLinuxGnu => "Linux",
758            Self::Aarch64UnknownLinuxMusl => "Linux",
759            Self::X8664UnknownLinuxMusl => "Linux",
760            Self::Riscv64UnknownLinuxGnu => "Linux",
761            Self::X8664Manylinux2014 => "Linux",
762            Self::X8664Manylinux217 => "Linux",
763            Self::X8664Manylinux228 => "Linux",
764            Self::X8664Manylinux231 => "Linux",
765            Self::X8664Manylinux232 => "Linux",
766            Self::X8664Manylinux233 => "Linux",
767            Self::X8664Manylinux234 => "Linux",
768            Self::X8664Manylinux235 => "Linux",
769            Self::X8664Manylinux236 => "Linux",
770            Self::X8664Manylinux237 => "Linux",
771            Self::X8664Manylinux238 => "Linux",
772            Self::X8664Manylinux239 => "Linux",
773            Self::X8664Manylinux240 => "Linux",
774            Self::Aarch64Manylinux2014 => "Linux",
775            Self::Aarch64Manylinux217 => "Linux",
776            Self::Aarch64Manylinux228 => "Linux",
777            Self::Aarch64Manylinux231 => "Linux",
778            Self::Aarch64Manylinux232 => "Linux",
779            Self::Aarch64Manylinux233 => "Linux",
780            Self::Aarch64Manylinux234 => "Linux",
781            Self::Aarch64Manylinux235 => "Linux",
782            Self::Aarch64Manylinux236 => "Linux",
783            Self::Aarch64Manylinux237 => "Linux",
784            Self::Aarch64Manylinux238 => "Linux",
785            Self::Aarch64Manylinux239 => "Linux",
786            Self::Aarch64Manylinux240 => "Linux",
787            Self::Aarch64LinuxAndroid => "Android",
788            Self::X8664LinuxAndroid => "Android",
789            Self::Wasm32Pyodide2024 => "Emscripten",
790            Self::Wasm32Pyodide2025 => "Emscripten",
791            Self::Arm64Ios => "iOS",
792            Self::Arm64IosSimulator => "iOS",
793            Self::X8664IosSimulator => "iOS",
794        }
795    }
796
797    /// Return the `platform_version` value for the target.
798    fn platform_version(self) -> &'static str {
799        match self {
800            Self::Windows | Self::X8664PcWindowsMsvc => "",
801            Self::Aarch64PcWindowsMsvc => "",
802            Self::Linux | Self::X8664UnknownLinuxGnu => "",
803            Self::Macos | Self::Aarch64AppleDarwin => "",
804            Self::I686PcWindowsMsvc => "",
805            Self::X8664AppleDarwin => "",
806            Self::Aarch64UnknownLinuxGnu => "",
807            Self::Aarch64UnknownLinuxMusl => "",
808            Self::X8664UnknownLinuxMusl => "",
809            Self::Riscv64UnknownLinuxGnu => "",
810            Self::X8664Manylinux2014 => "",
811            Self::X8664Manylinux217 => "",
812            Self::X8664Manylinux228 => "",
813            Self::X8664Manylinux231 => "",
814            Self::X8664Manylinux232 => "",
815            Self::X8664Manylinux233 => "",
816            Self::X8664Manylinux234 => "",
817            Self::X8664Manylinux235 => "",
818            Self::X8664Manylinux236 => "",
819            Self::X8664Manylinux237 => "",
820            Self::X8664Manylinux238 => "",
821            Self::X8664Manylinux239 => "",
822            Self::X8664Manylinux240 => "",
823            Self::Aarch64Manylinux2014 => "",
824            Self::Aarch64Manylinux217 => "",
825            Self::Aarch64Manylinux228 => "",
826            Self::Aarch64Manylinux231 => "",
827            Self::Aarch64Manylinux232 => "",
828            Self::Aarch64Manylinux233 => "",
829            Self::Aarch64Manylinux234 => "",
830            Self::Aarch64Manylinux235 => "",
831            Self::Aarch64Manylinux236 => "",
832            Self::Aarch64Manylinux237 => "",
833            Self::Aarch64Manylinux238 => "",
834            Self::Aarch64Manylinux239 => "",
835            Self::Aarch64Manylinux240 => "",
836            Self::Aarch64LinuxAndroid => "",
837            Self::X8664LinuxAndroid => "",
838            // This is the value Emscripten gives for its version:
839            // https://github.com/emscripten-core/emscripten/blob/4.0.8/system/lib/libc/emscripten_syscall_stubs.c#L63
840            // It doesn't really seem to mean anything? But for completeness we include it here.
841            Self::Wasm32Pyodide2024 => "#1",
842            Self::Wasm32Pyodide2025 => "#1",
843            Self::Arm64Ios => "",
844            Self::Arm64IosSimulator => "",
845            Self::X8664IosSimulator => "",
846        }
847    }
848
849    /// Return the `platform_release` value for the target.
850    fn platform_release(self) -> &'static str {
851        match self {
852            Self::Windows | Self::X8664PcWindowsMsvc => "",
853            Self::Aarch64PcWindowsMsvc => "",
854            Self::Linux | Self::X8664UnknownLinuxGnu => "",
855            Self::Macos | Self::Aarch64AppleDarwin => "",
856            Self::I686PcWindowsMsvc => "",
857            Self::X8664AppleDarwin => "",
858            Self::Aarch64UnknownLinuxGnu => "",
859            Self::Aarch64UnknownLinuxMusl => "",
860            Self::X8664UnknownLinuxMusl => "",
861            Self::Riscv64UnknownLinuxGnu => "",
862            Self::X8664Manylinux2014 => "",
863            Self::X8664Manylinux217 => "",
864            Self::X8664Manylinux228 => "",
865            Self::X8664Manylinux231 => "",
866            Self::X8664Manylinux232 => "",
867            Self::X8664Manylinux233 => "",
868            Self::X8664Manylinux234 => "",
869            Self::X8664Manylinux235 => "",
870            Self::X8664Manylinux236 => "",
871            Self::X8664Manylinux237 => "",
872            Self::X8664Manylinux238 => "",
873            Self::X8664Manylinux239 => "",
874            Self::X8664Manylinux240 => "",
875            Self::Aarch64Manylinux2014 => "",
876            Self::Aarch64Manylinux217 => "",
877            Self::Aarch64Manylinux228 => "",
878            Self::Aarch64Manylinux231 => "",
879            Self::Aarch64Manylinux232 => "",
880            Self::Aarch64Manylinux233 => "",
881            Self::Aarch64Manylinux234 => "",
882            Self::Aarch64Manylinux235 => "",
883            Self::Aarch64Manylinux236 => "",
884            Self::Aarch64Manylinux237 => "",
885            Self::Aarch64Manylinux238 => "",
886            Self::Aarch64Manylinux239 => "",
887            Self::Aarch64Manylinux240 => "",
888            Self::Aarch64LinuxAndroid => "",
889            Self::X8664LinuxAndroid => "",
890            // This is the Emscripten compiler version for Pyodide 2024.
891            // See https://pyodide.org/en/stable/development/abi/312.html
892            Self::Wasm32Pyodide2024 => "3.1.58",
893            // See https://pyodide.org/en/stable/development/abi/313.html
894            Self::Wasm32Pyodide2025 => "4.0.9",
895            Self::Arm64Ios => "",
896            Self::Arm64IosSimulator => "",
897            Self::X8664IosSimulator => "",
898        }
899    }
900
901    /// Return the `os_name` value for the target.
902    fn os_name(self) -> &'static str {
903        match self {
904            Self::Windows | Self::X8664PcWindowsMsvc => "nt",
905            Self::Aarch64PcWindowsMsvc => "nt",
906            Self::Linux | Self::X8664UnknownLinuxGnu => "posix",
907            Self::Macos | Self::Aarch64AppleDarwin => "posix",
908            Self::I686PcWindowsMsvc => "nt",
909            Self::X8664AppleDarwin => "posix",
910            Self::Aarch64UnknownLinuxGnu => "posix",
911            Self::Aarch64UnknownLinuxMusl => "posix",
912            Self::X8664UnknownLinuxMusl => "posix",
913            Self::Riscv64UnknownLinuxGnu => "posix",
914            Self::X8664Manylinux2014 => "posix",
915            Self::X8664Manylinux217 => "posix",
916            Self::X8664Manylinux228 => "posix",
917            Self::X8664Manylinux231 => "posix",
918            Self::X8664Manylinux232 => "posix",
919            Self::X8664Manylinux233 => "posix",
920            Self::X8664Manylinux234 => "posix",
921            Self::X8664Manylinux235 => "posix",
922            Self::X8664Manylinux236 => "posix",
923            Self::X8664Manylinux237 => "posix",
924            Self::X8664Manylinux238 => "posix",
925            Self::X8664Manylinux239 => "posix",
926            Self::X8664Manylinux240 => "posix",
927            Self::Aarch64Manylinux2014 => "posix",
928            Self::Aarch64Manylinux217 => "posix",
929            Self::Aarch64Manylinux228 => "posix",
930            Self::Aarch64Manylinux231 => "posix",
931            Self::Aarch64Manylinux232 => "posix",
932            Self::Aarch64Manylinux233 => "posix",
933            Self::Aarch64Manylinux234 => "posix",
934            Self::Aarch64Manylinux235 => "posix",
935            Self::Aarch64Manylinux236 => "posix",
936            Self::Aarch64Manylinux237 => "posix",
937            Self::Aarch64Manylinux238 => "posix",
938            Self::Aarch64Manylinux239 => "posix",
939            Self::Aarch64Manylinux240 => "posix",
940            Self::Aarch64LinuxAndroid => "posix",
941            Self::X8664LinuxAndroid => "posix",
942            Self::Wasm32Pyodide2024 => "posix",
943            Self::Wasm32Pyodide2025 => "posix",
944            Self::Arm64Ios => "posix",
945            Self::Arm64IosSimulator => "posix",
946            Self::X8664IosSimulator => "posix",
947        }
948    }
949
950    /// Return the `sys_platform` value for the target.
951    fn sys_platform(self) -> &'static str {
952        match self {
953            Self::Windows | Self::X8664PcWindowsMsvc => "win32",
954            Self::Aarch64PcWindowsMsvc => "win32",
955            Self::Linux | Self::X8664UnknownLinuxGnu => "linux",
956            Self::Macos | Self::Aarch64AppleDarwin => "darwin",
957            Self::I686PcWindowsMsvc => "win32",
958            Self::X8664AppleDarwin => "darwin",
959            Self::Aarch64UnknownLinuxGnu => "linux",
960            Self::Aarch64UnknownLinuxMusl => "linux",
961            Self::X8664UnknownLinuxMusl => "linux",
962            Self::Riscv64UnknownLinuxGnu => "linux",
963            Self::X8664Manylinux2014 => "linux",
964            Self::X8664Manylinux217 => "linux",
965            Self::X8664Manylinux228 => "linux",
966            Self::X8664Manylinux231 => "linux",
967            Self::X8664Manylinux232 => "linux",
968            Self::X8664Manylinux233 => "linux",
969            Self::X8664Manylinux234 => "linux",
970            Self::X8664Manylinux235 => "linux",
971            Self::X8664Manylinux236 => "linux",
972            Self::X8664Manylinux237 => "linux",
973            Self::X8664Manylinux238 => "linux",
974            Self::X8664Manylinux239 => "linux",
975            Self::X8664Manylinux240 => "linux",
976            Self::Aarch64Manylinux2014 => "linux",
977            Self::Aarch64Manylinux217 => "linux",
978            Self::Aarch64Manylinux228 => "linux",
979            Self::Aarch64Manylinux231 => "linux",
980            Self::Aarch64Manylinux232 => "linux",
981            Self::Aarch64Manylinux233 => "linux",
982            Self::Aarch64Manylinux234 => "linux",
983            Self::Aarch64Manylinux235 => "linux",
984            Self::Aarch64Manylinux236 => "linux",
985            Self::Aarch64Manylinux237 => "linux",
986            Self::Aarch64Manylinux238 => "linux",
987            Self::Aarch64Manylinux239 => "linux",
988            Self::Aarch64Manylinux240 => "linux",
989            Self::Aarch64LinuxAndroid => "android",
990            Self::X8664LinuxAndroid => "android",
991            Self::Wasm32Pyodide2024 => "emscripten",
992            Self::Wasm32Pyodide2025 => "emscripten",
993            Self::Arm64Ios => "ios",
994            Self::Arm64IosSimulator => "ios",
995            Self::X8664IosSimulator => "ios",
996        }
997    }
998
999    /// Return `true` if the platform is compatible with manylinux.
1000    pub fn manylinux_compatible(self) -> bool {
1001        match self {
1002            Self::Windows | Self::X8664PcWindowsMsvc => false,
1003            Self::Aarch64PcWindowsMsvc => false,
1004            Self::Linux | Self::X8664UnknownLinuxGnu => true,
1005            Self::Macos | Self::Aarch64AppleDarwin => false,
1006            Self::I686PcWindowsMsvc => false,
1007            Self::X8664AppleDarwin => false,
1008            Self::Aarch64UnknownLinuxGnu => true,
1009            Self::Aarch64UnknownLinuxMusl => true,
1010            Self::X8664UnknownLinuxMusl => true,
1011            Self::Riscv64UnknownLinuxGnu => true,
1012            Self::X8664Manylinux2014 => true,
1013            Self::X8664Manylinux217 => true,
1014            Self::X8664Manylinux228 => true,
1015            Self::X8664Manylinux231 => true,
1016            Self::X8664Manylinux232 => true,
1017            Self::X8664Manylinux233 => true,
1018            Self::X8664Manylinux234 => true,
1019            Self::X8664Manylinux235 => true,
1020            Self::X8664Manylinux236 => true,
1021            Self::X8664Manylinux237 => true,
1022            Self::X8664Manylinux238 => true,
1023            Self::X8664Manylinux239 => true,
1024            Self::X8664Manylinux240 => true,
1025            Self::Aarch64Manylinux2014 => true,
1026            Self::Aarch64Manylinux217 => true,
1027            Self::Aarch64Manylinux228 => true,
1028            Self::Aarch64Manylinux231 => true,
1029            Self::Aarch64Manylinux232 => true,
1030            Self::Aarch64Manylinux233 => true,
1031            Self::Aarch64Manylinux234 => true,
1032            Self::Aarch64Manylinux235 => true,
1033            Self::Aarch64Manylinux236 => true,
1034            Self::Aarch64Manylinux237 => true,
1035            Self::Aarch64Manylinux238 => true,
1036            Self::Aarch64Manylinux239 => true,
1037            Self::Aarch64Manylinux240 => true,
1038            Self::Aarch64LinuxAndroid => false,
1039            Self::X8664LinuxAndroid => false,
1040            Self::Wasm32Pyodide2024 => false,
1041            Self::Wasm32Pyodide2025 => false,
1042            Self::Arm64Ios => false,
1043            Self::Arm64IosSimulator => false,
1044            Self::X8664IosSimulator => false,
1045        }
1046    }
1047
1048    /// Return a [`MarkerEnvironment`] compatible with the given [`TargetTriple`], based on
1049    /// a base [`MarkerEnvironment`].
1050    ///
1051    /// The returned [`MarkerEnvironment`] will preserve the base environment's Python version
1052    /// markers, but override its platform markers.
1053    pub fn markers(self, base: MarkerEnvironment) -> MarkerEnvironment {
1054        base.with_os_name(self.os_name())
1055            .with_platform_machine(self.platform_machine())
1056            .with_platform_system(self.platform_system())
1057            .with_sys_platform(self.sys_platform())
1058            .with_platform_release(self.platform_release())
1059            .with_platform_version(self.platform_version())
1060    }
1061}
1062
1063/// Return the macOS deployment target as parsed from the environment.
1064fn macos_deployment_target() -> Option<(u16, u16)> {
1065    let version = std::env::var(EnvVars::MACOSX_DEPLOYMENT_TARGET).ok()?;
1066    let mut parts = version.split('.');
1067
1068    // Parse the major version (e.g., `12` in `12.0`).
1069    let major = parts.next()?.parse::<u16>().ok()?;
1070
1071    // Parse the minor version (e.g., `0` in `12.0`), with a default of `0`.
1072    let minor = parts.next().unwrap_or("0").parse::<u16>().ok()?;
1073
1074    Some((major, minor))
1075}
1076
1077/// Return the iOS deployment target as parsed from the environment.
1078fn ios_deployment_target() -> Option<(u16, u16)> {
1079    let version = std::env::var(EnvVars::IPHONEOS_DEPLOYMENT_TARGET).ok()?;
1080    let mut parts = version.split('.');
1081
1082    // Parse the major version (e.g., `12` in `12.0`).
1083    let major = parts.next()?.parse::<u16>().ok()?;
1084
1085    // Parse the minor version (e.g., `0` in `12.0`), with a default of `0`.
1086    let minor = parts.next().unwrap_or("0").parse::<u16>().ok()?;
1087
1088    Some((major, minor))
1089}
1090
1091/// Return the Android API level as parsed from the environment.
1092fn android_api_level() -> Option<u16> {
1093    let api_level_str = std::env::var(EnvVars::ANDROID_API_LEVEL).ok()?;
1094
1095    // Parse the api level.
1096    let api_level = api_level_str.parse::<u16>().ok()?;
1097
1098    Some(api_level)
1099}