use std::{
env,
ffi::OsStr,
path::{Path, PathBuf},
process::{Command, Stdio},
str,
};
use print_bytes::println_lossy;
fn print_cargo_path(name: &str, path: &Path) {
print!("cargo:{name}");
println_lossy(path);
}
pub struct SysRoot {
path: PathBuf,
}
impl SysRoot {
pub fn resolve() -> Self {
let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into());
let output = Command::new(rustc)
.args(&["--print", "sysroot"])
.output()
.expect("could not invoke `rustc` to find rust sysroot");
let path = output
.stdout
.as_slice()
.split(|c| c.is_ascii_whitespace())
.next()
.unwrap_or_default();
let path = if cfg!(unix) {
use std::os::unix::ffi::OsStrExt;
OsStr::from_bytes(path)
} else {
let path = str::from_utf8(path).expect("`rustc --print sysroot` is not UTF-8");
OsStr::new(path)
};
let path = Path::new(path).to_owned();
Self { path }
}
pub fn sysroot(&self) -> &Path {
self.path.as_path()
}
pub fn lib(&self) -> PathBuf {
self.sysroot().join("lib")
}
pub fn rustlib(&self) -> PathBuf {
let target = env::var_os("TARGET").expect("cargo should set $TARGET");
[
self.sysroot(),
Path::new("lib"),
Path::new("rustlib"),
Path::new(&target),
Path::new("lib"),
]
.iter()
.collect()
}
pub fn link_rustc_private(&self) {
let lib = self.lib();
print_cargo_path("rustc-link-search=native=", &lib);
print_cargo_path("rustc-link-arg=-Wl,-rpath,", &lib);
}
}
pub fn find_llvm_config() -> Option<PathBuf> {
env::var_os("LLVM_CONFIG_PATH")
.map(PathBuf::from)
.or_else(|| {
env::var_os("LLVM_LIB_DIR")
.map(PathBuf::from)
.map(|mut lib_dir| {
lib_dir.push("../bin/llvm-config");
lib_dir.canonicalize().unwrap()
})
})
.or_else(|| {
[
"llvm-config-14",
"llvm-config-13",
"llvm-config-12",
"llvm-config-11",
"llvm-config-10",
"llvm-config-9",
"llvm-config-8",
"llvm-config-7",
"llvm-config-7.0",
"llvm-config",
"/usr/local/opt/llvm@13/bin/llvm-config",
"/usr/local/opt/llvm@12/bin/llvm-config",
"/usr/local/opt/llvm@11/bin/llvm-config",
"/usr/local/opt/llvm@10/bin/llvm-config",
"/usr/local/opt/llvm@9/bin/llvm-config",
"/usr/local/opt/llvm@8/bin/llvm-config",
"/usr/local/opt/llvm/bin/llvm-config",
"/opt/homebrew/opt/llvm@13/bin/llvm-config",
"/opt/homebrew/opt/llvm@12/bin/llvm-config",
"/opt/homebrew/opt/llvm@11/bin/llvm-config",
"/opt/homebrew/opt/llvm@10/bin/llvm-config",
"/opt/homebrew/opt/llvm@9/bin/llvm-config",
"/opt/homebrew/opt/llvm@8/bin/llvm-config",
"/opt/homebrew/opt/llvm/bin/llvm-config",
]
.iter()
.map(Path::new)
.filter(|c| {
Command::new(c)
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.is_ok()
})
.map(PathBuf::from)
.next()
})
}