Skip to main content

turbopack_core/
target.rs

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