mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
75 lines
2.4 KiB
Rust
75 lines
2.4 KiB
Rust
use std::convert::AsRef;
|
|
use std::env;
|
|
use std::ffi::OsStr;
|
|
use std::path::Path;
|
|
use std::process::Command;
|
|
use std::str;
|
|
|
|
// TODO: Use zig build system command instead
|
|
|
|
fn main() {
|
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
|
|
|
// "." is relative to where "build.rs" is
|
|
let src_path = Path::new(".").join("bitcode").join("src");
|
|
let main_zig_path = src_path.join("main.zig");
|
|
|
|
let src_path_str = src_path.to_str().expect("Invalid src path");
|
|
println!("Building main.zig from: {}", src_path_str);
|
|
|
|
let zig_cache_dir = Path::new(&out_dir).join("zig-cache");
|
|
let zig_cache_dir_str = zig_cache_dir.to_str().expect("Invalid zig cache dir");
|
|
println!("Setting zig cache to: {}", zig_cache_dir_str);
|
|
|
|
let dest_ll_path = Path::new(&out_dir).join("builtins.ll");
|
|
let dest_ll = dest_ll_path.to_str().expect("Invalid dest ir path");
|
|
let emit_ir_arg = "-femit-llvm-ir=".to_owned() + dest_ll;
|
|
println!("Compiling zig llvm-ir to: {}", dest_ll);
|
|
|
|
run_command(
|
|
"zig",
|
|
&[
|
|
"build-obj",
|
|
main_zig_path.to_str().unwrap(),
|
|
&emit_ir_arg,
|
|
"-fno-emit-bin",
|
|
"--strip",
|
|
"-O",
|
|
"ReleaseFast",
|
|
"--cache-dir",
|
|
zig_cache_dir_str,
|
|
],
|
|
);
|
|
|
|
let dest_bc_path = Path::new(&out_dir).join("builtins.bc");
|
|
let dest_bc = dest_bc_path.to_str().expect("Invalid dest bc path");
|
|
println!("Compiling bitcode to: {}", dest_bc);
|
|
|
|
run_command("llvm-as-10", &[dest_ll, "-o", dest_bc]);
|
|
|
|
// TODO: Recursivly search zig src dir to watch for each file
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
println!("cargo:rerun-if-changed={}", src_path_str);
|
|
println!("cargo:rustc-env=BUILTINS_BC={}", dest_bc);
|
|
}
|
|
|
|
fn run_command<S, I>(command: &str, args: I)
|
|
where
|
|
I: IntoIterator<Item = S>,
|
|
S: AsRef<OsStr>,
|
|
{
|
|
let output_result = Command::new(OsStr::new(&command)).args(args).output();
|
|
match output_result {
|
|
Ok(output) => match output.status.success() {
|
|
true => (),
|
|
false => {
|
|
let error_str = match str::from_utf8(&output.stderr) {
|
|
Ok(stderr) => stderr.to_string(),
|
|
Err(_) => format!("Failed to run \"{}\"", command),
|
|
};
|
|
panic!("{} failed: {}", command, error_str);
|
|
}
|
|
},
|
|
Err(reason) => panic!("{} failed: {}", command, reason),
|
|
}
|
|
}
|