mun_target/
spec.rs

1mod apple_base;
2mod apple_sdk_base;
3mod linux_base;
4mod windows_msvc_base;
5
6use crate::{abi::Endian, host_triple};
7
8#[derive(Debug, Clone, Copy, Eq, Ord, PartialOrd, PartialEq, Hash)]
9pub enum LinkerFlavor {
10    Ld,
11    Ld64,
12    Msvc,
13}
14
15/// Everything Mun knows about a target.
16/// Every field must be specified, there are no default values.
17#[derive(Clone, Debug, Eq, PartialEq)]
18pub struct Target {
19    /// Target triple to pass to LLVM
20    pub llvm_target: String,
21
22    /// String to use as the `target_pointer_width` `cfg` variable.
23    pub pointer_width: u32,
24
25    /// The name of the architecture. For example "x86" or "x86_64", "arm", "aarch64"
26    pub arch: String,
27
28    /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM.
29    pub data_layout: String,
30
31    /// Optional settings
32    pub options: TargetOptions,
33}
34
35/// Optional aspects of target specification.
36#[derive(Clone, Debug, Eq, PartialEq)]
37pub struct TargetOptions {
38    /// True if this is a built-in target
39    pub is_builtin: bool,
40
41    /// Used as the `target_endian` `cfg` variable. Defaults to little endian.
42    pub endian: Endian,
43
44    /// Width of c_int type
45    pub c_int_width: String,
46
47    /// The name of the OS
48    pub os: String,
49
50    /// Minimum version of the OS to target
51    pub min_os_version: Option<(u32, u32, u32)>,
52
53    /// The name of the environment
54    pub env: String,
55
56    /// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"`
57    /// or `"eabihf"`. Defaults to "".
58    pub abi: String,
59
60    /// The name of the vendor
61    pub vendor: String,
62
63    /// Linker flavor
64    pub linker_flavor: LinkerFlavor,
65
66    /// Linker arguments that are passed *before* any user-defined libraries.
67    pub pre_link_args: Vec<String>,
68
69    /// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults to "generic".
70    pub cpu: String,
71
72    /// Default target features to pass to LLVM. These features will *always* be passed, and cannot
73    /// be disabled even via `-C`. Corresponds to `llc -mattr=$features`.
74    pub features: String,
75
76    /// String to prepend to the name of every dynamic library. Defaults to "lib".
77    pub dll_prefix: String,
78
79    /// Whether the target toolchain is like Windows
80    pub is_like_windows: bool,
81    pub is_like_msvc: bool,
82
83    /// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS,
84    /// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
85    pub is_like_osx: bool,
86}
87
88impl Default for TargetOptions {
89    fn default() -> Self {
90        TargetOptions {
91            is_builtin: false,
92            endian: Endian::Little,
93            c_int_width: "32".into(),
94            os: "none".into(),
95            min_os_version: None,
96            env: "".into(),
97            abi: "".into(),
98            vendor: "unknown".into(),
99            linker_flavor: LinkerFlavor::Ld,
100            pre_link_args: vec![],
101            cpu: "generic".to_string(),
102            features: "".to_string(),
103            dll_prefix: "lib".to_string(),
104            is_like_windows: false,
105            is_like_msvc: false,
106            is_like_osx: false,
107        }
108    }
109}
110
111macro_rules! supported_targets {
112    ( $(($( $triple:literal, )+ $module:ident ),)+ ) => {
113        $ ( mod $ module; ) +
114
115        /// List of supported targets
116        const TARGETS: &[&str] = &[$($($triple),+),+];
117
118        fn load_specific(target: &str) -> Option<Target> {
119            let mut t = match target {
120                $( $($triple)|+ => $module::target(), )+
121                _ => return None,
122            };
123            t.options.is_builtin = true;
124            log::debug!("got builtin target: {:?}", t);
125            Some(t)
126        }
127
128        pub fn get_targets() -> impl Iterator<Item = &'static str> {
129            TARGETS.iter().copied()
130        }
131    }
132}
133
134supported_targets!(
135    ("x86_64-apple-darwin", x86_64_apple_darwin),
136    ("x86_64-apple-ios", x86_64_apple_ios),
137    ("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc),
138    ("x86_64-unknown-linux-gnu", x86_64_unknown_linux_gnu),
139    ("aarch64-apple-darwin", aarch64_apple_darwin),
140    ("aarch64-apple-ios", aarch64_apple_ios),
141    ("aarch64-apple-ios-sim", aarch64_apple_ios_sim),
142);
143
144impl Target {
145    pub fn search(target_triple: &str) -> Option<Target> {
146        load_specific(target_triple)
147    }
148
149    pub fn host_target() -> Option<Target> {
150        Self::search(host_triple())
151    }
152}