turbopack_core/
target.rs

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