1 use crate::common::Config;
4 use std::path::PathBuf;
11 /// Conversion table from triple OS name to Rust SYSNAME
12 const OS_TABLE: &[(&str, &str)] = &[
13 ("android", "android"),
14 ("androideabi", "android"),
17 ("dragonfly", "dragonfly"),
18 ("emscripten", "emscripten"),
19 ("freebsd", "freebsd"),
20 ("fuchsia", "fuchsia"),
23 ("illumos", "illumos"),
27 ("mingw32", "windows"),
30 ("openbsd", "openbsd"),
33 ("solaris", "solaris"),
34 ("watchos", "watchos"),
36 ("windows", "windows"),
37 ("vxworks", "vxworks"),
40 const ARCH_TABLE: &[(&str, &str)] = &[
41 ("aarch64", "aarch64"),
42 ("aarch64_be", "aarch64"),
54 ("hexagon", "hexagon"),
61 ("mips64el", "mips64"),
62 ("mipsisa32r6", "mips"),
63 ("mipsisa32r6el", "mips"),
64 ("mipsisa64r6", "mips64"),
65 ("mipsisa64r6el", "mips64"),
67 ("mipsisa32r6", "mips"),
68 ("mipsisa32r6el", "mips"),
69 ("mipsisa64r6", "mips64"),
70 ("mipsisa64r6el", "mips64"),
72 ("nvptx64", "nvptx64"),
73 ("powerpc", "powerpc"),
74 ("powerpc64", "powerpc64"),
75 ("powerpc64le", "powerpc64"),
76 ("riscv64gc", "riscv64"),
79 ("sparc64", "sparc64"),
80 ("sparcv9", "sparc64"),
81 ("thumbv6m", "thumb"),
82 ("thumbv7em", "thumb"),
83 ("thumbv7m", "thumb"),
89 pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[
90 "aarch64-apple-darwin",
92 "aarch64-unknown-linux-gnu",
93 "x86_64-apple-darwin",
95 "x86_64-unknown-freebsd",
96 "x86_64-unknown-linux-gnu",
99 pub const LSAN_SUPPORTED_TARGETS: &[&str] = &[
100 // FIXME: currently broken, see #88132
101 // "aarch64-apple-darwin",
102 "aarch64-unknown-linux-gnu",
103 "x86_64-apple-darwin",
104 "x86_64-unknown-linux-gnu",
107 pub const MSAN_SUPPORTED_TARGETS: &[&str] =
108 &["aarch64-unknown-linux-gnu", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu"];
110 pub const TSAN_SUPPORTED_TARGETS: &[&str] = &[
111 "aarch64-apple-darwin",
112 "aarch64-unknown-linux-gnu",
113 "x86_64-apple-darwin",
114 "x86_64-unknown-freebsd",
115 "x86_64-unknown-linux-gnu",
118 pub const HWASAN_SUPPORTED_TARGETS: &[&str] =
119 &["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
121 pub const MEMTAG_SUPPORTED_TARGETS: &[&str] =
122 &["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
124 const BIG_ENDIAN: &[&str] = &[
139 static ASM_SUPPORTED_ARCHS: &[&str] = &[
140 "x86", "x86_64", "arm", "aarch64", "riscv32",
142 // These targets require an additional asm_experimental_arch feature.
143 // "nvptx64", "hexagon", "mips", "mips64", "spirv", "wasm32",
146 pub fn has_asm_support(triple: &str) -> bool {
147 ASM_SUPPORTED_ARCHS.contains(&get_arch(triple))
150 pub fn matches_os(triple: &str, name: &str) -> bool {
151 // For the wasm32 bare target we ignore anything also ignored on emscripten
152 // and then we also recognize `wasm32-bare` as the os for the target
153 if triple == "wasm32-unknown-unknown" {
154 return name == "emscripten" || name == "wasm32-bare";
156 let triple: Vec<_> = triple.split('-').collect();
157 for &(triple_os, os) in OS_TABLE {
158 if triple.contains(&triple_os) {
162 panic!("Cannot determine OS from triple");
165 /// Determine the architecture from `triple`
166 pub fn get_arch(triple: &str) -> &'static str {
167 let triple: Vec<_> = triple.split('-').collect();
168 for &(triple_arch, arch) in ARCH_TABLE {
169 if triple.contains(&triple_arch) {
173 panic!("Cannot determine Architecture from triple");
176 /// Determine the endianness from `triple`
177 pub fn is_big_endian(triple: &str) -> bool {
178 let triple_arch = triple.split('-').next().unwrap();
179 BIG_ENDIAN.contains(&triple_arch)
182 pub fn matches_env(triple: &str, name: &str) -> bool {
183 if let Some(env) = triple.split('-').nth(3) { env.starts_with(name) } else { false }
186 pub fn get_pointer_width(triple: &str) -> &'static str {
187 if (triple.contains("64") && !triple.ends_with("gnux32") && !triple.ends_with("gnu_ilp32"))
188 || triple.starts_with("s390x")
191 } else if triple.starts_with("avr") {
198 pub fn make_new_path(path: &str) -> String {
199 assert!(cfg!(windows));
200 // Windows just uses PATH as the library search path, so we have to
201 // maintain the current value while adding our own
202 match env::var(lib_path_env_var()) {
203 Ok(curr) => format!("{}{}{}", path, path_div(), curr),
204 Err(..) => path.to_owned(),
208 pub fn lib_path_env_var() -> &'static str {
211 fn path_div() -> &'static str {
215 pub fn logv(config: &Config, s: String) {
222 pub trait PathBufExt {
223 /// Append an extension to the path, even if it already has one.
224 fn with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf;
227 impl PathBufExt for PathBuf {
228 fn with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
229 if extension.as_ref().is_empty() {
232 let mut fname = self.file_name().unwrap().to_os_string();
233 if !extension.as_ref().to_str().unwrap().starts_with('.') {
236 fname.push(extension);
237 self.with_file_name(fname)