/
build.rs
93 lines (84 loc) · 2.69 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
extern crate gcc;
use std::env;
use std::ffi::{OsStr, OsString};
use std::os::unix::ffi::OsStringExt;
use std::path::{Path, PathBuf};
use std::process;
fn llvm_config<S: AsRef<OsStr>>(args: &[S]) -> Vec<u8> {
let output = process::Command::new("llvm-config")
.args(args)
.output()
.expect("llvm-config could not be run");
if !output.status.success() {
panic!("llvm-config failed:\n\n{}",
String::from_utf8_lossy(&output.stderr));
}
output.stdout
}
fn llvm_config_path<S: AsRef<OsStr>>(args: &[S]) -> PathBuf {
let mut vec = llvm_config(args);
while vec.last() == Some(&b'\n') {
vec.pop();
}
Path::new(&OsString::from_vec(vec)).to_path_buf()
}
fn llvm_config_str<S: AsRef<OsStr>>(args: &[S]) -> String {
let mut vec = llvm_config(args);
while vec.last() == Some(&b'\n') {
vec.pop();
}
String::from_utf8(vec).expect("llvm-config returned invalid UTF-8")
}
fn with_components<S: AsRef<OsStr>>(args: &[S]) -> Vec<OsString> {
let targets = llvm_config_str(&["--targets-built"]);
let mut components = vec!["core"];
for target in targets.split(" ") {
components.push(target);
}
args.iter()
.map(|s| s.as_ref())
.chain(components.iter().map(|s| s.as_ref()))
.map(|s| s.to_owned())
.collect()
}
fn build_cpp_files() {
let version = llvm_config_str(&["--version"]);
if !version.starts_with("3.9.") && !version.starts_with("4.0.") && version != "5.0.0svn" {
panic!("unsupported LLVM version: {}", version);
}
let libkind = llvm_config_str(&with_components(&["--shared-mode"]));
let includedir = llvm_config_path(&["--includedir"]);
let libdir = llvm_config_str(&["--libdir"]);
let libs = llvm_config_str(&with_components(&["--libs"]));
let system_libs = llvm_config_str(&with_components(&["--system-libs"]));
let libkind = match libkind.as_ref() {
"shared" => "dylib",
"static" => "static",
x => panic!("llvm-config --shared-mode returned invalid value {}", x),
};
println!("cargo:rustc-link-search=native={}", libdir);
for lib in libs.split_whitespace() {
let lib = lib.trim_left_matches("-l");
println!("cargo:rustc-link-lib={}={}", libkind, lib);
}
if libkind == "static" {
for lib in system_libs.split_whitespace() {
let lib = lib.trim_left_matches("-l");
println!("cargo:rustc-link-lib=dylib={}", lib);
}
}
println!("cargo:rerun-if-changed={}", "cpp/PrintMcsema.cpp");
gcc::Config::new()
.cpp(true)
.include(&includedir)
.include(env::var("CARGO_MANIFEST_DIR").unwrap())
.flag("-std=c++14")
.flag("-Wall")
.flag("-fkeep-inline-functions")
.flag("-fno-rtti")
.file("cpp/PrintMcsema.cpp")
.compile("libstrata-cpp.a");
}
fn main() {
build_cpp_files();
}