mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-04-20 08:24:44 +00:00
This is very incomplete. Just enough code to emit LLVM bitcode and continue further development
129 lines
4.2 KiB
Rust
129 lines
4.2 KiB
Rust
use cmake::Config;
|
|
use std::io;
|
|
use std::path::PathBuf;
|
|
use std::process::Command;
|
|
|
|
const COMPONENTS: &[&'static str] = &[
|
|
"LLVMCore",
|
|
"LLVMBitWriter",
|
|
#[cfg(debug_assertions)]
|
|
"LLVMAnalysis", // for module verify
|
|
#[cfg(debug_assertions)]
|
|
"LLVMBitReader",
|
|
];
|
|
|
|
fn main() {
|
|
let mut cmake = Config::new(r"../ext/llvm-project/llvm");
|
|
try_use_ninja(&mut cmake);
|
|
cmake
|
|
// For some reason Rust always links to release MSVCRT
|
|
.define("CMAKE_MSVC_RUNTIME_LIBRARY", "MultiThreadedDLL")
|
|
.define("LLVM_ENABLE_TERMINFO", "OFF")
|
|
.define("LLVM_ENABLE_LIBXML2", "OFF")
|
|
.define("LLVM_ENABLE_LIBEDIT", "OFF")
|
|
.define("LLVM_ENABLE_LIBPFM", "OFF")
|
|
.define("LLVM_ENABLE_ZLIB", "OFF")
|
|
.define("LLVM_ENABLE_ZSTD", "OFF")
|
|
.define("LLVM_INCLUDE_BENCHMARKS", "OFF")
|
|
.define("LLVM_INCLUDE_EXAMPLES", "OFF")
|
|
.define("LLVM_INCLUDE_TESTS", "OFF")
|
|
.define("LLVM_BUILD_TOOLS", "OFF")
|
|
.define("LLVM_TARGETS_TO_BUILD", "")
|
|
.define("LLVM_ENABLE_PROJECTS", "");
|
|
cmake.build_target("llvm-config");
|
|
let llvm_dir = cmake.build();
|
|
for c in COMPONENTS {
|
|
cmake.build_target(c);
|
|
cmake.build();
|
|
}
|
|
let cmake_profile = cmake.get_profile();
|
|
let (cxxflags, ldflags, libdir, lib_names, system_libs) =
|
|
llvm_config(&llvm_dir, &["build", "bin", "llvm-config"])
|
|
.or_else(|_| llvm_config(&llvm_dir, &["build", cmake_profile, "bin", "llvm-config"]))
|
|
.unwrap();
|
|
println!("cargo:rustc-link-arg={ldflags}");
|
|
println!("cargo:rustc-link-search=native={libdir}");
|
|
for lib in system_libs.split_ascii_whitespace() {
|
|
println!("cargo:rustc-link-arg={lib}");
|
|
}
|
|
link_llvm_components(lib_names);
|
|
compile_cxx_lib(cxxflags);
|
|
}
|
|
|
|
fn try_use_ninja(cmake: &mut Config) {
|
|
let mut cmd = Command::new("ninja");
|
|
cmd.arg("--version");
|
|
if let Ok(status) = cmd.status() {
|
|
if status.success() {
|
|
cmake.generator("Ninja");
|
|
}
|
|
}
|
|
}
|
|
|
|
fn llvm_config(
|
|
llvm_build_dir: &PathBuf,
|
|
path_to_llvm_config: &[&str],
|
|
) -> io::Result<(String, String, String, String, String)> {
|
|
let mut llvm_build_path = llvm_build_dir.clone();
|
|
llvm_build_path.extend(path_to_llvm_config);
|
|
let mut cmd = Command::new(llvm_build_path);
|
|
cmd.args([
|
|
"--link-static",
|
|
"--cxxflags",
|
|
"--ldflags",
|
|
"--libdir",
|
|
"--libnames",
|
|
"--system-libs",
|
|
]);
|
|
for c in COMPONENTS {
|
|
cmd.arg(c[4..].to_lowercase());
|
|
}
|
|
let output = cmd.output()?;
|
|
if !output.status.success() {
|
|
return Err(io::Error::from(io::ErrorKind::Other));
|
|
}
|
|
let output = unsafe { String::from_utf8_unchecked(output.stdout) };
|
|
let mut lines = output.lines();
|
|
let cxxflags = lines.next().unwrap();
|
|
let ldflags = lines.next().unwrap();
|
|
let libdir = lines.next().unwrap();
|
|
let lib_names = lines.next().unwrap();
|
|
let system_libs = lines.next().unwrap();
|
|
Ok((
|
|
cxxflags.to_string(),
|
|
ldflags.to_string(),
|
|
libdir.to_string(),
|
|
lib_names.to_string(),
|
|
system_libs.to_string(),
|
|
))
|
|
}
|
|
|
|
fn compile_cxx_lib(cxxflags: String) {
|
|
let mut cc = cc::Build::new();
|
|
for flag in cxxflags.split_whitespace() {
|
|
cc.flag(flag);
|
|
}
|
|
cc.cpp(true).file("src/lib.cpp").compile("llvm_zluda_cpp");
|
|
println!("cargo:rerun-if-changed=src/lib.cpp");
|
|
println!("cargo:rerun-if-changed=src/lib.rs");
|
|
}
|
|
|
|
fn link_llvm_components(components: String) {
|
|
for component in components.split_whitespace() {
|
|
let component = if let Some(component) = component
|
|
.strip_prefix("lib")
|
|
.and_then(|component| component.strip_suffix(".a"))
|
|
{
|
|
// Unix (Linux/Mac)
|
|
// libLLVMfoo.a
|
|
component
|
|
} else if let Some(component) = component.strip_suffix(".lib") {
|
|
// Windows
|
|
// LLVMfoo.lib
|
|
component
|
|
} else {
|
|
panic!("'{}' does not look like a static library name", component)
|
|
};
|
|
println!("cargo:rustc-link-lib={component}");
|
|
}
|
|
}
|