1use which::which;
2
3#[macro_export]
4macro_rules! exists_return {
5 ($cmd: expr) => {
6 if command_exists($cmd) {
7 return $cmd;
8 }
9 };
10}
11
12pub fn command_exists<T>(cmd: T) -> bool
13where
14 T: AsRef<str>,
15{
16 which(cmd.as_ref()).is_ok()
17}
18
19pub fn get_default_linker() -> &'static str {
20 exists_return!("mold");
21 exists_return!("lld");
22 exists_return!("gold");
23 exists_return!("ld");
24 exists_return!("clang");
25 exists_return!("gcc");
26
27 "cc"
28}
29
30#[cfg(any(target_os = "linux", target_os = "android"))]
31pub fn get_dynamic_linker(
32 prefix: String,
33 target_arch: Option<String>,
34 target_env: Option<String>,
35) -> String {
36 use std::env::consts::ARCH;
37
38 use crate::target::ENV;
39
40 let env = target_env.unwrap_or(ENV.to_string());
41
42 if env == "android" {
43 return "/system/lib/ld-android.so".to_string();
44 }
45
46 format!(
47 "{}/lib/ld-linux-{}.so.1",
48 prefix,
49 target_arch.unwrap_or(ARCH.to_string())
50 )
51}
52
53#[cfg(any(target_os = "linux", target_os = "android"))]
54pub fn get_library_dir(
55 prefix_dir: Option<String>,
56 target_arch: Option<String>,
57 target_os: Option<String>,
58 target_env: Option<String>,
59) -> Vec<String> {
60 use std::env::consts::{ARCH, OS};
61
62 use crate::target::ENV;
63
64 let prefix = prefix_dir.unwrap_or(std::env::var("PREFIX").unwrap_or(String::from("/usr")));
65
66 vec![
69 format!("-L{}/lib", prefix),
70 format!(
71 "-L{}/lib/{}-{}-{}",
72 prefix,
73 target_arch.clone().unwrap_or(ARCH.to_string()),
74 target_os.clone().unwrap_or(OS.to_string()),
75 target_env.clone().unwrap_or(ENV.to_string())
76 ),
77 format!(
78 "-L{}/{}-{}-{}/lib",
79 prefix,
80 target_arch.clone().unwrap_or(ARCH.to_string()),
81 target_os.unwrap_or(OS.to_string()),
82 target_env.clone().unwrap_or(ENV.to_string())
83 ),
84 "--dynamic-linker".to_string(),
85 get_dynamic_linker(prefix, target_arch, target_env),
86 ]
87}
88
89#[cfg(target_os = "windows")]
90pub fn get_library_dir(_target_arch: String, _target_c: String) -> Vec<String> {
91 todo!("get_library_dir is not supported on Windows yet!")
92}
93
94#[cfg(target_os = "windows")]
95pub fn get_dynamic_linker(
96 _prefix: String,
97 _target_arch: Option<String>,
98 _target_env: Option<String>,
99) -> String {
100 todo!("get_dynamic_linker is not supported on Windows yet!")
101}