turbopack_core/
target.rs

1use std::fmt::Display;
2
3use bincode::{Decode, Encode};
4use turbo_tasks::{NonLocalValue, Vc, trace::TraceRawVcs};
5
6#[turbo_tasks::value(shared)]
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(PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, Encode, Decode)]
177#[repr(u8)]
178#[non_exhaustive]
179pub enum Arch {
180    Arm,
181    Arm64,
182    Ia32,
183    Mips,
184    Mipsel,
185    Ppc,
186    Ppc64,
187    S390,
188    S390x,
189    X64,
190    Unknown,
191}
192
193impl Arch {
194    pub fn as_str(&self) -> &'static str {
195        match self {
196            Self::Arm => "arm",
197            Self::Arm64 => "arm64",
198            Self::Ia32 => "ia32",
199            Self::Mips => "mips",
200            Self::Mipsel => "mipsel",
201            Self::Ppc => "ppc",
202            Self::Ppc64 => "ppc64",
203            Self::S390 => "s390",
204            Self::S390x => "s390x",
205            Self::X64 => "x64",
206            Self::Unknown => "unknown",
207        }
208    }
209}
210
211impl Display for Arch {
212    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
213        f.write_str(self.as_str())
214    }
215}
216
217#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, Encode, Decode)]
218#[repr(u8)]
219#[non_exhaustive]
220pub enum Platform {
221    Aix,
222    Android,
223    Darwin,
224    Freebsd,
225    Linux,
226    Openbsd,
227    Sunos,
228    Win32,
229    Unknown,
230}
231
232impl Platform {
233    pub fn as_str(&self) -> &'static str {
234        match self {
235            Self::Aix => "aix",
236            Self::Android => "android",
237            Self::Darwin => "darwin",
238            Self::Freebsd => "freebsd",
239            Self::Linux => "linux",
240            Self::Openbsd => "openbsd",
241            Self::Sunos => "sunos",
242            Self::Win32 => "win32",
243            Self::Unknown => "unknown",
244        }
245    }
246}
247
248impl Display for Platform {
249    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
250        f.write_str(self.as_str())
251    }
252}
253
254#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, Encode, Decode)]
255#[repr(u8)]
256pub enum Endianness {
257    Big,
258    Little,
259}
260
261impl Endianness {
262    pub fn as_str(&self) -> &'static str {
263        match self {
264            Self::Big => "BE",
265            Self::Little => "LE",
266        }
267    }
268}
269
270impl Display for Endianness {
271    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
272        f.write_str(self.as_str())
273    }
274}
275
276#[derive(PartialEq, Eq, Hash, Debug, Copy, Clone, TraceRawVcs, NonLocalValue, Encode, Decode)]
277#[repr(u8)]
278pub enum Libc {
279    Glibc,
280    Musl,
281    Msvc,
282    Unknown,
283}
284
285impl Libc {
286    pub fn as_str(&self) -> &'static str {
287        match self {
288            Self::Glibc => "glibc",
289            Self::Musl => "musl",
290            Self::Msvc => "msvc",
291            Self::Unknown => "unknown",
292        }
293    }
294}
295
296impl Display for Libc {
297    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
298        f.write_str(self.as_str())
299    }
300}