cc/target/
llvm.rs

1use std::borrow::Cow;
2
3use super::TargetInfo;
4
5impl<'a> TargetInfo<'a> {
6    /// The versioned LLVM/Clang target triple.
7    pub(crate) fn versioned_llvm_target(&self, version: Option<&str>) -> Cow<'a, str> {
8        if let Some(version) = version {
9            // Only support versioned Apple targets for now.
10            assert_eq!(self.vendor, "apple");
11
12            let mut components = self.unversioned_llvm_target.split("-");
13            let arch = components.next().expect("llvm_target should have arch");
14            let vendor = components.next().expect("llvm_target should have vendor");
15            let os = components.next().expect("LLVM target should have os");
16            let environment = components.next();
17            assert_eq!(components.next(), None, "too many LLVM target components");
18
19            Cow::Owned(if let Some(env) = environment {
20                format!("{arch}-{vendor}-{os}{version}-{env}")
21            } else {
22                format!("{arch}-{vendor}-{os}{version}")
23            })
24        } else {
25            Cow::Borrowed(self.unversioned_llvm_target)
26        }
27    }
28}
29
30/// Rust and Clang don't really agree on naming, so do a best-effort
31/// conversion to support out-of-tree / custom target-spec targets.
32pub(crate) fn guess_llvm_target_triple(
33    full_arch: &str,
34    vendor: &str,
35    os: &str,
36    env: &str,
37    abi: &str,
38) -> String {
39    let arch = match full_arch {
40        riscv32 if riscv32.starts_with("riscv32") => "riscv32",
41        riscv64 if riscv64.starts_with("riscv64") => "riscv64",
42        arch => arch,
43    };
44    let os = match os {
45        "darwin" => "macosx",
46        "visionos" => "xros",
47        "uefi" => "windows",
48        os => os,
49    };
50    let env = match env {
51        "newlib" | "nto70" | "nto71" | "ohos" | "p1" | "p2" | "relibc" | "sgx" | "uclibc" => "",
52        env => env,
53    };
54    let abi = match abi {
55        "sim" => "simulator",
56        "llvm" | "softfloat" | "uwp" | "vec-extabi" => "",
57        "ilp32" => "_ilp32",
58        abi => abi,
59    };
60    match (env, abi) {
61        ("", "") => format!("{arch}-{vendor}-{os}"),
62        (env, abi) => format!("{arch}-{vendor}-{os}-{env}{abi}"),
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_basic_llvm_triple_guessing() {
72        assert_eq!(
73            guess_llvm_target_triple("aarch64", "unknown", "linux", "", ""),
74            "aarch64-unknown-linux"
75        );
76        assert_eq!(
77            guess_llvm_target_triple("x86_64", "unknown", "linux", "gnu", ""),
78            "x86_64-unknown-linux-gnu"
79        );
80        assert_eq!(
81            guess_llvm_target_triple("x86_64", "unknown", "linux", "gnu", "eabi"),
82            "x86_64-unknown-linux-gnueabi"
83        );
84        assert_eq!(
85            guess_llvm_target_triple("x86_64", "apple", "darwin", "", ""),
86            "x86_64-apple-macosx"
87        );
88    }
89}