cc/target/
llvm.rs

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