Dominik Maier 5a4e5b0a93
MacOS Build (#197)
* macos build

* more fix

* fixed clang pass build

* fixes for libfuzzer link

* more explanation links
2021-06-30 21:20:24 +02:00

93 lines
3.2 KiB
Rust

use std::{env, fs::File, io::Write, path::Path, process::Command, str};
fn dll_extension<'a>() -> &'a str {
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
"windwos" => "dll",
"macos" | "ios" => "dylib",
_ => "so",
}
}
fn main() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let out_dir = Path::new(&out_dir);
let src_dir = Path::new("src");
let dest_path = Path::new(&out_dir).join("clang_constants.rs");
let mut clang_constants_file = File::create(&dest_path).expect("Could not create file");
let llvm_config = env::var("LLVM_CONFIG").unwrap_or_else(|_| "llvm-config".into());
if let Ok(output) = Command::new(&llvm_config).args(&["--bindir"]).output() {
let llvm_bindir = Path::new(
str::from_utf8(&output.stdout)
.expect("Invalid llvm-config output")
.trim(),
);
write!(
&mut clang_constants_file,
"// These constants are autogenerated by build.rs
pub const CLANG_PATH: &str = {:?};
pub const CLANGXX_PATH: &str = {:?};
",
llvm_bindir.join("clang"),
llvm_bindir.join("clang++")
)
.expect("Could not write file");
println!("cargo:rerun-if-changed=src/cmplog-routines-pass.cc");
let output = Command::new(&llvm_config)
.args(&["--cxxflags"])
.output()
.expect("Failed to execute llvm-config");
let cxxflags = str::from_utf8(&output.stdout).expect("Invalid llvm-config output");
let output = Command::new(&llvm_config)
.args(&["--ldflags"])
.output()
.expect("Failed to execute llvm-config");
let ldflags = str::from_utf8(&output.stdout).expect("Invalid llvm-config output");
let cxxflags: Vec<&str> = cxxflags.trim().split_whitespace().collect();
let mut ldflags: Vec<&str> = ldflags.trim().split_whitespace().collect();
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
// Needed on macos.
// Explanation at https://github.com/banach-space/llvm-tutor/blob/787b09ed31ff7f0e7bdd42ae20547d27e2991512/lib/CMakeLists.txt#L59
"macos" | "ios" => {
ldflags.push("-undefined");
ldflags.push("dynamic_lookup");
}
_ => (),
};
let _ = Command::new(llvm_bindir.join("clang++"))
.args(&cxxflags)
.arg(src_dir.join("cmplog-routines-pass.cc"))
.args(&ldflags)
.args(&["-fPIC", "-shared", "-o"])
.arg(out_dir.join(format!("cmplog-routines-pass.{}", dll_extension())))
.status()
.expect("Failed to compile cmplog-routines-pass.cc");
} else {
write!(
&mut clang_constants_file,
"// These constants are autogenerated by build.rs
pub const CLANG_PATH: &str = \"clang\";
pub const CLANGXX_PATH: &str = \"clang++\";
"
)
.expect("Could not write file");
println!(
"cargo:warning=Failed to locate the LLVM path using {}, we will not build LLVM passes",
llvm_config
);
}
println!("cargo:rerun-if-changed=build.rs");
}