mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
repl_test: update build.rs to work with Zig 0.9 (like test_gen)
This commit is contained in:
parent
249925cb23
commit
a663d335fc
3 changed files with 91 additions and 27 deletions
|
@ -115,7 +115,7 @@ fn section_size(bytes: &[u8]) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_section<'a>(id: SectionId, module_bytes: &'a [u8], cursor: &mut usize) -> (u32, &'a [u8]) {
|
fn parse_section<'a>(id: SectionId, module_bytes: &'a [u8], cursor: &mut usize) -> (u32, &'a [u8]) {
|
||||||
if module_bytes[*cursor] != id as u8 {
|
if (*cursor >= module_bytes.len()) || (module_bytes[*cursor] != id as u8) {
|
||||||
return (0, &[]);
|
return (0, &[]);
|
||||||
}
|
}
|
||||||
*cursor += 1;
|
*cursor += 1;
|
||||||
|
|
|
@ -39,13 +39,13 @@ fn build_wasm() {
|
||||||
&platform_path,
|
&platform_path,
|
||||||
&compiler_rt_path,
|
&compiler_rt_path,
|
||||||
"-L",
|
"-L",
|
||||||
&libc_dir,
|
libc_dir,
|
||||||
"-lc",
|
"-lc",
|
||||||
"-o",
|
"-o",
|
||||||
&format!("{}/{}.o", out_dir, PLATFORM_FILENAME),
|
&format!("{}/{}.o", out_dir, PLATFORM_FILENAME),
|
||||||
"--export-all",
|
"--export-all",
|
||||||
"--no-entry",
|
"--no-entry",
|
||||||
// "--emit-relocs", // TODO: resize stack by relocating __heap_base (issue #2480)
|
// "--emit-relocs", // TODO: resize stack by relocating __heap_base (issue #2480) here and in repl_test build
|
||||||
];
|
];
|
||||||
|
|
||||||
let zig = zig_executable();
|
let zig = zig_executable();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
use roc_builtins::bitcode;
|
use roc_builtins::bitcode;
|
||||||
|
@ -10,7 +10,8 @@ const PRE_LINKED_BINARY: &str = "data/pre_linked_binary.o";
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
println!("cargo:rerun-if-changed=src/{}.c", PLATFORM_FILENAME);
|
let source_path = format!("src/{}.c", PLATFORM_FILENAME);
|
||||||
|
println!("cargo:rerun-if-changed={}", source_path);
|
||||||
|
|
||||||
// When we build on Netlify, zig is not installed (but also not used,
|
// When we build on Netlify, zig is not installed (but also not used,
|
||||||
// since all we're doing is generating docs), so we can skip the steps
|
// since all we're doing is generating docs), so we can skip the steps
|
||||||
|
@ -23,26 +24,38 @@ fn main() {
|
||||||
|
|
||||||
std::fs::create_dir_all("./data").unwrap();
|
std::fs::create_dir_all("./data").unwrap();
|
||||||
|
|
||||||
// Build a pre-linked binary with platform, builtins and all their libc dependencies
|
// Zig can produce *either* an object containing relocations OR an object containing libc code
|
||||||
// This builds a library file that exports all symbols. It has no linker data but we don't need it.
|
// But we want both, so we have to compile twice with different flags, then link them
|
||||||
// See discussion with Luuk de Gram (Zig contributor)
|
|
||||||
// https://github.com/rtfeldman/roc/pull/2181#pullrequestreview-839608063
|
// Create an object file with relocations
|
||||||
let args = [
|
let out_dir = env::var("OUT_DIR").unwrap();
|
||||||
"build-lib",
|
let platform_obj = build_wasm_platform(&out_dir, &source_path);
|
||||||
"-target",
|
|
||||||
"wasm32-wasi",
|
// Compile again to get libc path
|
||||||
"-lc",
|
let (libc_archive, compiler_rt_obj) = build_wasm_libc_compilerrt(&out_dir, &source_path);
|
||||||
"-dynamic", // -dynamic ensures libc code goes into the binary
|
let mut libc_pathbuf = PathBuf::from(&libc_archive);
|
||||||
|
libc_pathbuf.pop();
|
||||||
|
let libc_dir = libc_pathbuf.to_str().unwrap();
|
||||||
|
|
||||||
|
let args = &[
|
||||||
|
"wasm-ld",
|
||||||
bitcode::BUILTINS_WASM32_OBJ_PATH,
|
bitcode::BUILTINS_WASM32_OBJ_PATH,
|
||||||
&format!("src/{}.c", PLATFORM_FILENAME),
|
&platform_obj,
|
||||||
&format!("-femit-bin={}", PRE_LINKED_BINARY),
|
&compiler_rt_obj,
|
||||||
|
"-L",
|
||||||
|
libc_dir,
|
||||||
|
"-lc",
|
||||||
|
"-o",
|
||||||
|
PRE_LINKED_BINARY,
|
||||||
|
"--export-all",
|
||||||
|
"--no-entry",
|
||||||
];
|
];
|
||||||
|
|
||||||
let zig = zig_executable();
|
let zig = zig_executable();
|
||||||
|
|
||||||
// println!("{} {}", zig, args.join(" "));
|
// println!("{} {}", zig, args.join(" "));
|
||||||
|
|
||||||
run_command(Path::new("."), &zig, args);
|
run_command(&zig, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zig_executable() -> String {
|
fn zig_executable() -> String {
|
||||||
|
@ -52,26 +65,77 @@ fn zig_executable() -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command<S, I, P: AsRef<Path>>(path: P, command_str: &str, args: I) -> String
|
fn build_wasm_platform(out_dir: &str, source_path: &str) -> String {
|
||||||
where
|
let platform_obj = format!("{}/{}.o", out_dir, PLATFORM_FILENAME);
|
||||||
I: IntoIterator<Item = S>,
|
|
||||||
S: AsRef<OsStr>,
|
run_command(
|
||||||
{
|
&zig_executable(),
|
||||||
|
&[
|
||||||
|
"build-lib",
|
||||||
|
"-target",
|
||||||
|
"wasm32-wasi",
|
||||||
|
"-lc",
|
||||||
|
source_path,
|
||||||
|
&format!("-femit-bin={}", &platform_obj),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
platform_obj
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_wasm_libc_compilerrt(out_dir: &str, source_path: &str) -> (String, String) {
|
||||||
|
let zig_cache_dir = format!("{}/zig-cache-wasm32", out_dir);
|
||||||
|
|
||||||
|
run_command(
|
||||||
|
&zig_executable(),
|
||||||
|
&[
|
||||||
|
"build-lib",
|
||||||
|
"-dynamic", // ensure libc code is actually generated (not just linked against header)
|
||||||
|
"-target",
|
||||||
|
"wasm32-wasi",
|
||||||
|
"-lc",
|
||||||
|
source_path,
|
||||||
|
"-femit-bin=/dev/null",
|
||||||
|
"--global-cache-dir",
|
||||||
|
&zig_cache_dir,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
|
(
|
||||||
|
run_command("find", &[&zig_cache_dir, "-name", "libc.a"]),
|
||||||
|
run_command("find", &[&zig_cache_dir, "-name", "compiler_rt.o"]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_command(command_str: &str, args: &[&str]) -> String {
|
||||||
let output_result = Command::new(OsStr::new(&command_str))
|
let output_result = Command::new(OsStr::new(&command_str))
|
||||||
.current_dir(path)
|
.current_dir(Path::new("."))
|
||||||
.args(args)
|
.args(args)
|
||||||
.output();
|
.output();
|
||||||
|
|
||||||
|
let fail = |err: String| {
|
||||||
|
panic!(
|
||||||
|
"\n\nFailed command:\n\t{} {}\n\n{}",
|
||||||
|
command_str,
|
||||||
|
args.join(" "),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
match output_result {
|
match output_result {
|
||||||
Ok(output) => match output.status.success() {
|
Ok(output) => match output.status.success() {
|
||||||
true => std::str::from_utf8(&output.stdout).unwrap().to_string(),
|
true => std::str::from_utf8(&output.stdout)
|
||||||
|
.unwrap()
|
||||||
|
.trim()
|
||||||
|
.to_string(),
|
||||||
false => {
|
false => {
|
||||||
let error_str = match std::str::from_utf8(&output.stderr) {
|
let error_str = match std::str::from_utf8(&output.stderr) {
|
||||||
Ok(stderr) => stderr.to_string(),
|
Ok(stderr) => stderr.to_string(),
|
||||||
Err(_) => format!("Failed to run \"{}\"", command_str),
|
Err(_) => format!("Failed to run \"{}\"", command_str),
|
||||||
};
|
};
|
||||||
panic!("{} failed: {}", command_str, error_str);
|
fail(error_str)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(reason) => panic!("{} failed: {}", command_str, reason),
|
Err(reason) => fail(reason.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue