-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathbuild.rs
127 lines (109 loc) · 3.38 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use std::{
env,
error::Error,
ffi::OsStr,
fs::read_dir,
path::Path,
process::{exit, Command},
str,
};
const LLVM_MAJOR_VERSION: usize = 19;
fn main() {
if let Err(error) = run() {
eprintln!("{}", error);
exit(1);
}
}
fn run() -> Result<(), Box<dyn Error>> {
let version = llvm_config("--version")?;
if !version.starts_with(&format!("{LLVM_MAJOR_VERSION}.",)) {
return Err(format!(
"failed to find correct version ({LLVM_MAJOR_VERSION}.x.x) of llvm-config (found {version})"
)
.into());
}
println!("cargo:rerun-if-changed=wrapper.h");
println!("cargo:rustc-link-search={}", llvm_config("--libdir")?);
for entry in read_dir(llvm_config("--libdir")?)? {
if let Some(name) = entry?.path().file_name().and_then(OsStr::to_str) {
if name.starts_with("libMLIR") {
if let Some(name) = parse_archive_name(name) {
println!("cargo:rustc-link-lib=static={name}");
}
}
}
}
println!("cargo:rustc-link-lib=MLIR");
for name in llvm_config("--libnames")?.trim().split(' ') {
if let Some(name) = parse_archive_name(name) {
println!("cargo:rustc-link-lib={name}");
}
}
for flag in llvm_config("--system-libs")?.trim().split(' ') {
let flag = flag.trim_start_matches("-l");
if flag.starts_with('/') {
// llvm-config returns absolute paths for dynamically linked libraries.
let path = Path::new(flag);
println!(
"cargo:rustc-link-search={}",
path.parent().unwrap().display()
);
println!(
"cargo:rustc-link-lib={}",
path.file_stem()
.unwrap()
.to_str()
.unwrap()
.trim_start_matches("lib")
);
} else {
println!("cargo:rustc-link-lib={flag}");
}
}
if let Some(name) = get_system_libcpp() {
println!("cargo:rustc-link-lib={name}");
}
bindgen::builder()
.header("wrapper.h")
.clang_arg(format!("-I{}", llvm_config("--includedir")?))
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.unwrap()
.write_to_file(Path::new(&env::var("OUT_DIR")?).join("bindings.rs"))?;
Ok(())
}
fn get_system_libcpp() -> Option<&'static str> {
if cfg!(target_env = "msvc") {
None
} else if cfg!(target_os = "macos") {
Some("c++")
} else {
Some("stdc++")
}
}
fn llvm_config(argument: &str) -> Result<String, Box<dyn Error>> {
let prefix = env::var(format!("MLIR_SYS_{LLVM_MAJOR_VERSION}0_PREFIX"))
.map(|path| Path::new(&path).join("bin"))
.unwrap_or_default();
let call = format!(
"{} --link-static {argument}",
prefix.join("llvm-config").display(),
);
Ok(str::from_utf8(
&if cfg!(target_os = "windows") {
Command::new("cmd").args(["/C", &call]).output()?
} else {
Command::new("sh").arg("-c").arg(&call).output()?
}
.stdout,
)?
.trim()
.to_string())
}
fn parse_archive_name(name: &str) -> Option<&str> {
if let Some(name) = name.strip_prefix("lib") {
name.strip_suffix(".a")
} else {
None
}
}