c2rust_build_paths/
lib.rs1use std::{
2 env,
3 ffi::OsStr,
4 path::{Path, PathBuf},
5 process::{Command, Stdio},
6 str,
7};
8
9use print_bytes::println_lossy;
10
11fn print_cargo_path(name: &str, path: &Path) {
12 print!("cargo:{name}");
13 println_lossy(path);
14}
15
16pub struct SysRoot {
17 path: PathBuf,
18}
19
20impl SysRoot {
21 pub fn resolve() -> Self {
22 let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
23 let output = Command::new(rustc)
24 .args(&["--print", "sysroot"])
25 .output()
26 .expect("could not invoke `rustc` to find rust sysroot");
27 let path = output
29 .stdout
30 .as_slice()
31 .split(|c| c.is_ascii_whitespace())
32 .next()
33 .unwrap_or_default();
34 #[cfg(unix)]
35 let path = {
36 use std::os::unix::ffi::OsStrExt;
37
38 OsStr::from_bytes(path)
39 };
40 #[cfg(not(unix))]
41 let path = {
42 let path = str::from_utf8(path).expect("`rustc --print sysroot` is not UTF-8");
44 OsStr::new(path)
45 };
46 let path = Path::new(path).to_owned();
47 Self { path }
48 }
49
50 pub fn sysroot(&self) -> &Path {
51 self.path.as_path()
52 }
53
54 pub fn lib(&self) -> PathBuf {
55 self.sysroot().join("lib")
56 }
57
58 pub fn rustlib(&self) -> PathBuf {
59 let target = env::var_os("TARGET").expect("cargo should set $TARGET");
60 [
61 self.sysroot(),
62 Path::new("lib"),
63 Path::new("rustlib"),
64 Path::new(&target),
65 Path::new("lib"),
66 ]
67 .iter()
68 .collect()
69 }
70
71 pub fn link_rustc_private(&self) {
72 let lib = self.lib();
73 print_cargo_path("rustc-link-search=native=", &lib);
74 print_cargo_path("rustc-link-arg=-Wl,-rpath,", &lib);
75 }
76}
77
78pub fn find_llvm_config() -> Option<PathBuf> {
79 env::var_os("LLVM_CONFIG_PATH")
81 .map(PathBuf::from)
82 .or_else(|| {
83 env::var_os("LLVM_LIB_DIR")
85 .map(PathBuf::from)
86 .map(|mut lib_dir| {
87 lib_dir.push("../bin/llvm-config");
88 lib_dir.canonicalize().unwrap()
89 })
90 })
91 .or_else(|| {
92 [
94 "llvm-config-18",
95 "llvm-config-17",
96 "llvm-config-16",
97 "llvm-config-15",
98 "llvm-config-14",
99 "llvm-config-13",
100 "llvm-config-12",
101 "llvm-config-11",
102 "llvm-config-10",
103 "llvm-config-9",
104 "llvm-config-8",
105 "llvm-config-7",
106 "llvm-config-7.0",
107 "llvm-config",
108 "/usr/local/opt/llvm@18/bin/llvm-config",
110 "/usr/local/opt/llvm@17/bin/llvm-config",
111 "/usr/local/opt/llvm@16/bin/llvm-config",
112 "/usr/local/opt/llvm@15/bin/llvm-config",
113 "/usr/local/opt/llvm@14/bin/llvm-config",
114 "/usr/local/opt/llvm@13/bin/llvm-config",
115 "/usr/local/opt/llvm@12/bin/llvm-config",
116 "/usr/local/opt/llvm@11/bin/llvm-config",
117 "/usr/local/opt/llvm@10/bin/llvm-config",
118 "/usr/local/opt/llvm@9/bin/llvm-config",
119 "/usr/local/opt/llvm@8/bin/llvm-config",
120 "/usr/local/opt/llvm/bin/llvm-config",
121 "/opt/homebrew/opt/llvm@18/bin/llvm-config",
123 "/opt/homebrew/opt/llvm@17/bin/llvm-config",
124 "/opt/homebrew/opt/llvm@16/bin/llvm-config",
125 "/opt/homebrew/opt/llvm@15/bin/llvm-config",
126 "/opt/homebrew/opt/llvm@14/bin/llvm-config",
127 "/opt/homebrew/opt/llvm@13/bin/llvm-config",
128 "/opt/homebrew/opt/llvm@12/bin/llvm-config",
129 "/opt/homebrew/opt/llvm@11/bin/llvm-config",
130 "/opt/homebrew/opt/llvm@10/bin/llvm-config",
131 "/opt/homebrew/opt/llvm@9/bin/llvm-config",
132 "/opt/homebrew/opt/llvm@8/bin/llvm-config",
133 "/opt/homebrew/opt/llvm/bin/llvm-config",
134 ]
135 .iter()
136 .map(Path::new)
137 .filter(|c| {
138 Command::new(c)
139 .stdout(Stdio::null())
140 .stderr(Stdio::null())
141 .spawn()
142 .is_ok()
143 })
144 .map(PathBuf::from)
145 .next()
146 })
147}