mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge pull request #4442 from roc-lang/better_errors
centralized commands, better errors, link build command refactoring
This commit is contained in:
commit
b143183ba8
17 changed files with 268 additions and 208 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -496,6 +496,7 @@ dependencies = [
|
||||||
"roc_load",
|
"roc_load",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_reporting",
|
"roc_reporting",
|
||||||
|
"roc_utils",
|
||||||
"serde",
|
"serde",
|
||||||
"serde-xml-rs",
|
"serde-xml-rs",
|
||||||
"strip-ansi-escapes",
|
"strip-ansi-escapes",
|
||||||
|
@ -3572,6 +3573,7 @@ dependencies = [
|
||||||
"roc_solve",
|
"roc_solve",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
"roc_unify",
|
"roc_unify",
|
||||||
|
"roc_utils",
|
||||||
"rodio",
|
"rodio",
|
||||||
"serde",
|
"serde",
|
||||||
"snafu",
|
"snafu",
|
||||||
|
@ -3991,6 +3993,7 @@ dependencies = [
|
||||||
"roc_reporting",
|
"roc_reporting",
|
||||||
"roc_target",
|
"roc_target",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
|
"roc_utils",
|
||||||
"wasi_libc_sys",
|
"wasi_libc_sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
|
@ -4858,6 +4861,7 @@ dependencies = [
|
||||||
"roc_target",
|
"roc_target",
|
||||||
"roc_types",
|
"roc_types",
|
||||||
"roc_unify",
|
"roc_unify",
|
||||||
|
"roc_utils",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"wasi_libc_sys",
|
"wasi_libc_sys",
|
||||||
|
@ -5260,6 +5264,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi_libc_sys"
|
name = "wasi_libc_sys"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"roc_utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
|
|
|
@ -252,7 +252,9 @@ pub fn build_file<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let rebuild_timing = if linking_strategy == LinkingStrategy::Additive {
|
let rebuild_timing = if linking_strategy == LinkingStrategy::Additive {
|
||||||
let rebuild_duration = rebuild_thread.join().unwrap();
|
let rebuild_duration = rebuild_thread
|
||||||
|
.join()
|
||||||
|
.expect("Failed to (re)build platform.");
|
||||||
if emit_timings && !prebuilt {
|
if emit_timings && !prebuilt {
|
||||||
println!(
|
println!(
|
||||||
"Finished rebuilding the platform in {} ms\n",
|
"Finished rebuilding the platform in {} ms\n",
|
||||||
|
@ -304,7 +306,7 @@ pub fn build_file<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let HostRebuildTiming::ConcurrentWithApp(thread) = rebuild_timing {
|
if let HostRebuildTiming::ConcurrentWithApp(thread) = rebuild_timing {
|
||||||
let rebuild_duration = thread.join().unwrap();
|
let rebuild_duration = thread.join().expect("Failed to (re)build platform.");
|
||||||
if emit_timings && !prebuilt {
|
if emit_timings && !prebuilt {
|
||||||
println!(
|
println!(
|
||||||
"Finished rebuilding the platform in {} ms\n",
|
"Finished rebuilding the platform in {} ms\n",
|
||||||
|
|
|
@ -14,6 +14,7 @@ roc_collections = { path = "../compiler/collections" }
|
||||||
roc_reporting = { path = "../reporting" }
|
roc_reporting = { path = "../reporting" }
|
||||||
roc_load = { path = "../compiler/load" }
|
roc_load = { path = "../compiler/load" }
|
||||||
roc_module = { path = "../compiler/module" }
|
roc_module = { path = "../compiler/module" }
|
||||||
|
roc_utils = { path = "../utils" }
|
||||||
bumpalo = { version = "3.8.0", features = ["collections"] }
|
bumpalo = { version = "3.8.0", features = ["collections"] }
|
||||||
criterion = { git = "https://github.com/Anton-4/criterion.rs"}
|
criterion = { git = "https://github.com/Anton-4/criterion.rs"}
|
||||||
serde = { version = "1.0.130", features = ["derive"] }
|
serde = { version = "1.0.130", features = ["derive"] }
|
||||||
|
|
|
@ -4,6 +4,7 @@ extern crate roc_load;
|
||||||
extern crate roc_module;
|
extern crate roc_module;
|
||||||
extern crate tempfile;
|
extern crate tempfile;
|
||||||
|
|
||||||
|
use roc_utils::cargo;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_xml_rs::from_str;
|
use serde_xml_rs::from_str;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -48,7 +49,7 @@ where
|
||||||
vec!["build", "--release", "--bin", "roc"]
|
vec!["build", "--release", "--bin", "roc"]
|
||||||
};
|
};
|
||||||
|
|
||||||
let output = Command::new("cargo")
|
let output = cargo()
|
||||||
.current_dir(root_project_dir)
|
.current_dir(root_project_dir)
|
||||||
.args(args)
|
.args(args)
|
||||||
.output()
|
.output()
|
||||||
|
|
|
@ -4,21 +4,15 @@ use roc_builtins::bitcode;
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
use roc_mono::ir::OptLevel;
|
use roc_mono::ir::OptLevel;
|
||||||
use roc_utils::get_lib_path;
|
use roc_utils::get_lib_path;
|
||||||
|
use roc_utils::{cargo, clang, zig};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{self, Child, Command, Output};
|
use std::process::{self, Child, Command};
|
||||||
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
use target_lexicon::{Architecture, OperatingSystem, Triple};
|
||||||
use wasi_libc_sys::{WASI_COMPILER_RT_PATH, WASI_LIBC_PATH};
|
use wasi_libc_sys::{WASI_COMPILER_RT_PATH, WASI_LIBC_PATH};
|
||||||
|
|
||||||
fn zig_executable() -> String {
|
|
||||||
match std::env::var("ROC_ZIG") {
|
|
||||||
Ok(path) => path,
|
|
||||||
Err(_) => "zig".into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum LinkType {
|
pub enum LinkType {
|
||||||
// These numbers correspond to the --lib and --no-link flags
|
// These numbers correspond to the --lib and --no-link flags
|
||||||
|
@ -113,9 +107,9 @@ pub fn build_zig_host_native(
|
||||||
target: &str,
|
target: &str,
|
||||||
opt_level: OptLevel,
|
opt_level: OptLevel,
|
||||||
shared_lib_path: Option<&Path>,
|
shared_lib_path: Option<&Path>,
|
||||||
) -> Output {
|
) -> Command {
|
||||||
let mut command = Command::new(&zig_executable());
|
let mut zig_cmd = zig();
|
||||||
command
|
zig_cmd
|
||||||
.env_clear()
|
.env_clear()
|
||||||
.env("PATH", env_path)
|
.env("PATH", env_path)
|
||||||
.env("HOME", env_home);
|
.env("HOME", env_home);
|
||||||
|
@ -130,7 +124,7 @@ pub fn build_zig_host_native(
|
||||||
bitcode::get_builtins_host_obj_path()
|
bitcode::get_builtins_host_obj_path()
|
||||||
};
|
};
|
||||||
|
|
||||||
command.args(&[
|
zig_cmd.args(&[
|
||||||
"build-exe",
|
"build-exe",
|
||||||
"-fPIE",
|
"-fPIE",
|
||||||
"-rdynamic", // make sure roc_alloc and friends are exposed
|
"-rdynamic", // make sure roc_alloc and friends are exposed
|
||||||
|
@ -138,10 +132,10 @@ pub fn build_zig_host_native(
|
||||||
&builtins_obj,
|
&builtins_obj,
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
command.args(&["build-obj", "-fPIC"]);
|
zig_cmd.args(&["build-obj", "-fPIC"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
command.args(&[
|
zig_cmd.args(&[
|
||||||
zig_host_src,
|
zig_host_src,
|
||||||
emit_bin,
|
emit_bin,
|
||||||
"--pkg-begin",
|
"--pkg-begin",
|
||||||
|
@ -160,7 +154,7 @@ pub fn build_zig_host_native(
|
||||||
// when we use zig 0.9. It looks like zig 0.10 is going to fix
|
// when we use zig 0.9. It looks like zig 0.10 is going to fix
|
||||||
// this problem for us, so this is a temporary workaround
|
// this problem for us, so this is a temporary workaround
|
||||||
if !target.contains("windows") {
|
if !target.contains("windows") {
|
||||||
command.args(&[
|
zig_cmd.args(&[
|
||||||
// include the zig runtime
|
// include the zig runtime
|
||||||
"-fcompiler-rt",
|
"-fcompiler-rt",
|
||||||
]);
|
]);
|
||||||
|
@ -168,16 +162,16 @@ pub fn build_zig_host_native(
|
||||||
|
|
||||||
// valgrind does not yet support avx512 instructions, see #1963.
|
// valgrind does not yet support avx512 instructions, see #1963.
|
||||||
if env::var("NO_AVX512").is_ok() {
|
if env::var("NO_AVX512").is_ok() {
|
||||||
command.args(&["-mcpu", "x86_64"]);
|
zig_cmd.args(&["-mcpu", "x86_64"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(opt_level, OptLevel::Optimize) {
|
if matches!(opt_level, OptLevel::Optimize) {
|
||||||
command.args(&["-O", "ReleaseSafe"]);
|
zig_cmd.args(&["-O", "ReleaseSafe"]);
|
||||||
} else if matches!(opt_level, OptLevel::Size) {
|
} else if matches!(opt_level, OptLevel::Size) {
|
||||||
command.args(&["-O", "ReleaseSmall"]);
|
zig_cmd.args(&["-O", "ReleaseSmall"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
command.output().unwrap()
|
zig_cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -191,25 +185,25 @@ pub fn build_zig_host_native(
|
||||||
target: &str,
|
target: &str,
|
||||||
opt_level: OptLevel,
|
opt_level: OptLevel,
|
||||||
shared_lib_path: Option<&Path>,
|
shared_lib_path: Option<&Path>,
|
||||||
) -> Output {
|
) -> Command {
|
||||||
let mut command = Command::new(&zig_executable());
|
let mut zig_cmd = zig();
|
||||||
command
|
zig_cmd
|
||||||
.env_clear()
|
.env_clear()
|
||||||
.env("PATH", env_path)
|
.env("PATH", env_path)
|
||||||
.env("HOME", env_home);
|
.env("HOME", env_home);
|
||||||
|
|
||||||
if let Some(shared_lib_path) = shared_lib_path {
|
if let Some(shared_lib_path) = shared_lib_path {
|
||||||
command.args(&[
|
zig_cmd.args(&[
|
||||||
"build-exe",
|
"build-exe",
|
||||||
// "-fPIE", PIE seems to fail on windows
|
// "-fPIE", PIE seems to fail on windows
|
||||||
shared_lib_path.to_str().unwrap(),
|
shared_lib_path.to_str().unwrap(),
|
||||||
&bitcode::get_builtins_windows_obj_path(),
|
&bitcode::get_builtins_windows_obj_path(),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
command.args(&["build-obj", "-fPIC"]);
|
zig_cmd.args(&["build-obj", "-fPIC"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
command.args(&[
|
zig_cmd.args(&[
|
||||||
zig_host_src,
|
zig_host_src,
|
||||||
emit_bin,
|
emit_bin,
|
||||||
"--pkg-begin",
|
"--pkg-begin",
|
||||||
|
@ -227,12 +221,12 @@ pub fn build_zig_host_native(
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if matches!(opt_level, OptLevel::Optimize) {
|
if matches!(opt_level, OptLevel::Optimize) {
|
||||||
command.args(&["-O", "ReleaseSafe"]);
|
zig_cmd.args(&["-O", "ReleaseSafe"]);
|
||||||
} else if matches!(opt_level, OptLevel::Size) {
|
} else if matches!(opt_level, OptLevel::Size) {
|
||||||
command.args(&["-O", "ReleaseSmall"]);
|
zig_cmd.args(&["-O", "ReleaseSmall"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
command.output().unwrap()
|
zig_cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
@ -247,14 +241,11 @@ pub fn build_zig_host_native(
|
||||||
opt_level: OptLevel,
|
opt_level: OptLevel,
|
||||||
shared_lib_path: Option<&Path>,
|
shared_lib_path: Option<&Path>,
|
||||||
// For compatibility with the non-macOS def above. Keep these in sync.
|
// For compatibility with the non-macOS def above. Keep these in sync.
|
||||||
) -> Output {
|
) -> Command {
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
// Run `zig env` to find the location of zig's std/ directory
|
// Run `zig env` to find the location of zig's std/ directory
|
||||||
let zig_env_output = Command::new(&zig_executable())
|
let zig_env_output = zig().args(&["env"]).output().unwrap();
|
||||||
.args(&["env"])
|
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let zig_env_json = if zig_env_output.status.success() {
|
let zig_env_json = if zig_env_output.status.success() {
|
||||||
std::str::from_utf8(&zig_env_output.stdout).unwrap_or_else(|utf8_err| {
|
std::str::from_utf8(&zig_env_output.stdout).unwrap_or_else(|utf8_err| {
|
||||||
|
@ -291,22 +282,22 @@ pub fn build_zig_host_native(
|
||||||
zig_compiler_rt_path.push("special");
|
zig_compiler_rt_path.push("special");
|
||||||
zig_compiler_rt_path.push("compiler_rt.zig");
|
zig_compiler_rt_path.push("compiler_rt.zig");
|
||||||
|
|
||||||
let mut command = Command::new(&zig_executable());
|
let mut zig_cmd = zig();
|
||||||
command
|
zig_cmd
|
||||||
.env_clear()
|
.env_clear()
|
||||||
.env("PATH", &env_path)
|
.env("PATH", &env_path)
|
||||||
.env("HOME", &env_home);
|
.env("HOME", &env_home);
|
||||||
if let Some(shared_lib_path) = shared_lib_path {
|
if let Some(shared_lib_path) = shared_lib_path {
|
||||||
command.args(&[
|
zig_cmd.args(&[
|
||||||
"build-exe",
|
"build-exe",
|
||||||
"-fPIE",
|
"-fPIE",
|
||||||
shared_lib_path.to_str().unwrap(),
|
shared_lib_path.to_str().unwrap(),
|
||||||
&bitcode::get_builtins_host_obj_path(),
|
&bitcode::get_builtins_host_obj_path(),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
command.args(&["build-obj", "-fPIC"]);
|
zig_cmd.args(&["build-obj", "-fPIC"]);
|
||||||
}
|
}
|
||||||
command.args(&[
|
zig_cmd.args(&[
|
||||||
zig_host_src,
|
zig_host_src,
|
||||||
emit_bin,
|
emit_bin,
|
||||||
"--pkg-begin",
|
"--pkg-begin",
|
||||||
|
@ -323,11 +314,12 @@ pub fn build_zig_host_native(
|
||||||
"c",
|
"c",
|
||||||
]);
|
]);
|
||||||
if matches!(opt_level, OptLevel::Optimize) {
|
if matches!(opt_level, OptLevel::Optimize) {
|
||||||
command.args(&["-O", "ReleaseSafe"]);
|
zig_cmd.args(&["-O", "ReleaseSafe"]);
|
||||||
} else if matches!(opt_level, OptLevel::Size) {
|
} else if matches!(opt_level, OptLevel::Size) {
|
||||||
command.args(&["-O", "ReleaseSmall"]);
|
zig_cmd.args(&["-O", "ReleaseSmall"]);
|
||||||
}
|
}
|
||||||
command.output().unwrap()
|
|
||||||
|
zig_cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_zig_host_wasm32(
|
pub fn build_zig_host_wasm32(
|
||||||
|
@ -338,7 +330,7 @@ pub fn build_zig_host_wasm32(
|
||||||
zig_str_path: &str,
|
zig_str_path: &str,
|
||||||
opt_level: OptLevel,
|
opt_level: OptLevel,
|
||||||
shared_lib_path: Option<&Path>,
|
shared_lib_path: Option<&Path>,
|
||||||
) -> Output {
|
) -> Command {
|
||||||
if shared_lib_path.is_some() {
|
if shared_lib_path.is_some() {
|
||||||
unimplemented!("Linking a shared library to wasm not yet implemented");
|
unimplemented!("Linking a shared library to wasm not yet implemented");
|
||||||
}
|
}
|
||||||
|
@ -358,7 +350,7 @@ pub fn build_zig_host_wasm32(
|
||||||
// we'd like to compile with `-target wasm32-wasi` but that is blocked on
|
// we'd like to compile with `-target wasm32-wasi` but that is blocked on
|
||||||
//
|
//
|
||||||
// https://github.com/ziglang/zig/issues/9414
|
// https://github.com/ziglang/zig/issues/9414
|
||||||
let mut command = Command::new(&zig_executable());
|
let mut zig_cmd = zig();
|
||||||
let args = &[
|
let args = &[
|
||||||
"build-obj",
|
"build-obj",
|
||||||
zig_host_src,
|
zig_host_src,
|
||||||
|
@ -379,18 +371,19 @@ pub fn build_zig_host_wasm32(
|
||||||
"--strip",
|
"--strip",
|
||||||
];
|
];
|
||||||
|
|
||||||
command
|
zig_cmd
|
||||||
.env_clear()
|
.env_clear()
|
||||||
.env("PATH", env_path)
|
.env("PATH", env_path)
|
||||||
.env("HOME", env_home)
|
.env("HOME", env_home)
|
||||||
.args(args);
|
.args(args);
|
||||||
|
|
||||||
if matches!(opt_level, OptLevel::Optimize) {
|
if matches!(opt_level, OptLevel::Optimize) {
|
||||||
command.args(&["-O", "ReleaseSafe"]);
|
zig_cmd.args(&["-O", "ReleaseSafe"]);
|
||||||
} else if matches!(opt_level, OptLevel::Size) {
|
} else if matches!(opt_level, OptLevel::Size) {
|
||||||
command.args(&["-O", "ReleaseSmall"]);
|
zig_cmd.args(&["-O", "ReleaseSmall"]);
|
||||||
}
|
}
|
||||||
command.output().unwrap()
|
|
||||||
|
zig_cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
@ -403,9 +396,9 @@ pub fn build_c_host_native(
|
||||||
sources: &[&str],
|
sources: &[&str],
|
||||||
opt_level: OptLevel,
|
opt_level: OptLevel,
|
||||||
shared_lib_path: Option<&Path>,
|
shared_lib_path: Option<&Path>,
|
||||||
) -> Output {
|
) -> Command {
|
||||||
let mut command = Command::new("clang");
|
let mut clang_cmd = clang();
|
||||||
command
|
clang_cmd
|
||||||
.env_clear()
|
.env_clear()
|
||||||
.env("PATH", &env_path)
|
.env("PATH", &env_path)
|
||||||
.env("CPATH", &env_cpath)
|
.env("CPATH", &env_cpath)
|
||||||
|
@ -432,7 +425,7 @@ pub fn build_c_host_native(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
command.args(&[
|
clang_cmd.args(&[
|
||||||
shared_lib_path.to_str().unwrap(),
|
shared_lib_path.to_str().unwrap(),
|
||||||
// This line is commented out because
|
// This line is commented out because
|
||||||
// @bhansconnect: With the addition of Str.graphemes, always
|
// @bhansconnect: With the addition of Str.graphemes, always
|
||||||
|
@ -451,14 +444,15 @@ pub fn build_c_host_native(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
command.args(&["-fPIC", "-c"]);
|
clang_cmd.args(&["-fPIC", "-c"]);
|
||||||
}
|
}
|
||||||
if matches!(opt_level, OptLevel::Optimize) {
|
if matches!(opt_level, OptLevel::Optimize) {
|
||||||
command.arg("-O3");
|
clang_cmd.arg("-O3");
|
||||||
} else if matches!(opt_level, OptLevel::Size) {
|
} else if matches!(opt_level, OptLevel::Size) {
|
||||||
command.arg("-Os");
|
clang_cmd.arg("-Os");
|
||||||
}
|
}
|
||||||
command.output().unwrap()
|
|
||||||
|
clang_cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
@ -471,7 +465,7 @@ pub fn build_swift_host_native(
|
||||||
shared_lib_path: Option<&Path>,
|
shared_lib_path: Option<&Path>,
|
||||||
objc_header_path: Option<&str>,
|
objc_header_path: Option<&str>,
|
||||||
arch: Architecture,
|
arch: Architecture,
|
||||||
) -> Output {
|
) -> Command {
|
||||||
if shared_lib_path.is_some() {
|
if shared_lib_path.is_some() {
|
||||||
unimplemented!("Linking a shared library to Swift not yet implemented");
|
unimplemented!("Linking a shared library to Swift not yet implemented");
|
||||||
}
|
}
|
||||||
|
@ -505,7 +499,7 @@ pub fn build_swift_host_native(
|
||||||
command.arg("-Osize");
|
command.arg("-Osize");
|
||||||
}
|
}
|
||||||
|
|
||||||
command.output().unwrap()
|
command
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rebuild_host(
|
pub fn rebuild_host(
|
||||||
|
@ -567,7 +561,7 @@ pub fn rebuild_host(
|
||||||
&zig_str_path
|
&zig_str_path
|
||||||
);
|
);
|
||||||
|
|
||||||
let output = match target.architecture {
|
let zig_cmd = match target.architecture {
|
||||||
Architecture::Wasm32 => {
|
Architecture::Wasm32 => {
|
||||||
let emit_bin = if matches!(opt_level, OptLevel::Development) {
|
let emit_bin = if matches!(opt_level, OptLevel::Development) {
|
||||||
format!("-femit-bin={}", host_dest.to_str().unwrap())
|
format!("-femit-bin={}", host_dest.to_str().unwrap())
|
||||||
|
@ -633,7 +627,7 @@ pub fn rebuild_host(
|
||||||
_ => internal_error!("Unsupported architecture {:?}", target.architecture),
|
_ => internal_error!("Unsupported architecture {:?}", target.architecture),
|
||||||
};
|
};
|
||||||
|
|
||||||
validate_output("host.zig", &zig_executable(), output)
|
run_build_command(zig_cmd, "host.zig")
|
||||||
} else if cargo_host_src.exists() {
|
} else if cargo_host_src.exists() {
|
||||||
// Compile and link Cargo.toml, if it exists
|
// Compile and link Cargo.toml, if it exists
|
||||||
let cargo_dir = host_input_path.parent().unwrap();
|
let cargo_dir = host_input_path.parent().unwrap();
|
||||||
|
@ -646,25 +640,23 @@ pub fn rebuild_host(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut command = Command::new("cargo");
|
let mut cargo_cmd = cargo();
|
||||||
command.arg("build").current_dir(cargo_dir);
|
cargo_cmd.arg("build").current_dir(cargo_dir);
|
||||||
// Rust doesn't expose size without editing the cargo.toml. Instead just use release.
|
// Rust doesn't expose size without editing the cargo.toml. Instead just use release.
|
||||||
if matches!(opt_level, OptLevel::Optimize | OptLevel::Size) {
|
if matches!(opt_level, OptLevel::Optimize | OptLevel::Size) {
|
||||||
command.arg("--release");
|
cargo_cmd.arg("--release");
|
||||||
}
|
}
|
||||||
|
|
||||||
let source_file = if shared_lib_path.is_some() {
|
let source_file = if shared_lib_path.is_some() {
|
||||||
command.env("RUSTFLAGS", "-C link-dead-code");
|
cargo_cmd.env("RUSTFLAGS", "-C link-dead-code");
|
||||||
command.args(&["--bin", "host"]);
|
cargo_cmd.args(&["--bin", "host"]);
|
||||||
"src/main.rs"
|
"src/main.rs"
|
||||||
} else {
|
} else {
|
||||||
command.arg("--lib");
|
cargo_cmd.arg("--lib");
|
||||||
"src/lib.rs"
|
"src/lib.rs"
|
||||||
};
|
};
|
||||||
|
|
||||||
let output = command.output().unwrap();
|
run_build_command(cargo_cmd, source_file);
|
||||||
|
|
||||||
validate_output(source_file, "cargo build", output);
|
|
||||||
|
|
||||||
if shared_lib_path.is_some() {
|
if shared_lib_path.is_some() {
|
||||||
// For surgical linking, just copy the dynamically linked rust app.
|
// For surgical linking, just copy the dynamically linked rust app.
|
||||||
|
@ -674,7 +666,7 @@ pub fn rebuild_host(
|
||||||
} else {
|
} else {
|
||||||
// Cargo hosts depend on a c wrapper for the api. Compile host.c as well.
|
// Cargo hosts depend on a c wrapper for the api. Compile host.c as well.
|
||||||
|
|
||||||
let output = build_c_host_native(
|
let clang_cmd = build_c_host_native(
|
||||||
target,
|
target,
|
||||||
&env_path,
|
&env_path,
|
||||||
&env_home,
|
&env_home,
|
||||||
|
@ -684,12 +676,12 @@ pub fn rebuild_host(
|
||||||
opt_level,
|
opt_level,
|
||||||
shared_lib_path,
|
shared_lib_path,
|
||||||
);
|
);
|
||||||
validate_output("host.c", "clang", output);
|
|
||||||
|
|
||||||
let output = Command::new("ld")
|
run_build_command(clang_cmd, "host.c");
|
||||||
.env_clear()
|
|
||||||
.env("PATH", &env_path)
|
let mut ld_cmd = Command::new("ld");
|
||||||
.args(&[
|
|
||||||
|
ld_cmd.env_clear().env("PATH", &env_path).args(&[
|
||||||
"-r",
|
"-r",
|
||||||
"-L",
|
"-L",
|
||||||
cargo_out_dir.to_str().unwrap(),
|
cargo_out_dir.to_str().unwrap(),
|
||||||
|
@ -697,10 +689,9 @@ pub fn rebuild_host(
|
||||||
"-lhost",
|
"-lhost",
|
||||||
"-o",
|
"-o",
|
||||||
host_dest.to_str().unwrap(),
|
host_dest.to_str().unwrap(),
|
||||||
])
|
]);
|
||||||
.output()
|
|
||||||
.unwrap();
|
run_build_command(ld_cmd, "c_host.o");
|
||||||
validate_output("c_host.o", "ld", output);
|
|
||||||
|
|
||||||
// Clean up c_host.o
|
// Clean up c_host.o
|
||||||
if c_host_dest.exists() {
|
if c_host_dest.exists() {
|
||||||
|
@ -709,25 +700,24 @@ pub fn rebuild_host(
|
||||||
}
|
}
|
||||||
} else if rust_host_src.exists() {
|
} else if rust_host_src.exists() {
|
||||||
// Compile and link host.rs, if it exists
|
// Compile and link host.rs, if it exists
|
||||||
let mut command = Command::new("rustc");
|
let mut rustc_cmd = Command::new("rustc");
|
||||||
command.args(&[
|
rustc_cmd.args(&[
|
||||||
rust_host_src.to_str().unwrap(),
|
rust_host_src.to_str().unwrap(),
|
||||||
"-o",
|
"-o",
|
||||||
rust_host_dest.to_str().unwrap(),
|
rust_host_dest.to_str().unwrap(),
|
||||||
]);
|
]);
|
||||||
if matches!(opt_level, OptLevel::Optimize) {
|
if matches!(opt_level, OptLevel::Optimize) {
|
||||||
command.arg("-O");
|
rustc_cmd.arg("-O");
|
||||||
} else if matches!(opt_level, OptLevel::Size) {
|
} else if matches!(opt_level, OptLevel::Size) {
|
||||||
command.arg("-C opt-level=s");
|
rustc_cmd.arg("-C opt-level=s");
|
||||||
}
|
}
|
||||||
let output = command.output().unwrap();
|
|
||||||
|
|
||||||
validate_output("host.rs", "rustc", output);
|
run_build_command(rustc_cmd, "host.rs");
|
||||||
|
|
||||||
// Rust hosts depend on a c wrapper for the api. Compile host.c as well.
|
// Rust hosts depend on a c wrapper for the api. Compile host.c as well.
|
||||||
if shared_lib_path.is_some() {
|
if shared_lib_path.is_some() {
|
||||||
// If compiling to executable, let c deal with linking as well.
|
// If compiling to executable, let c deal with linking as well.
|
||||||
let output = build_c_host_native(
|
let clang_cmd = build_c_host_native(
|
||||||
target,
|
target,
|
||||||
&env_path,
|
&env_path,
|
||||||
&env_home,
|
&env_home,
|
||||||
|
@ -740,9 +730,9 @@ pub fn rebuild_host(
|
||||||
opt_level,
|
opt_level,
|
||||||
shared_lib_path,
|
shared_lib_path,
|
||||||
);
|
);
|
||||||
validate_output("host.c", "clang", output);
|
run_build_command(clang_cmd, "host.c");
|
||||||
} else {
|
} else {
|
||||||
let output = build_c_host_native(
|
let clang_cmd = build_c_host_native(
|
||||||
target,
|
target,
|
||||||
&env_path,
|
&env_path,
|
||||||
&env_home,
|
&env_home,
|
||||||
|
@ -753,21 +743,19 @@ pub fn rebuild_host(
|
||||||
shared_lib_path,
|
shared_lib_path,
|
||||||
);
|
);
|
||||||
|
|
||||||
validate_output("host.c", "clang", output);
|
run_build_command(clang_cmd, "host.c");
|
||||||
let output = Command::new("ld")
|
|
||||||
.env_clear()
|
let mut ld_cmd = Command::new("ld");
|
||||||
.env("PATH", &env_path)
|
|
||||||
.args(&[
|
ld_cmd.env_clear().env("PATH", &env_path).args(&[
|
||||||
"-r",
|
"-r",
|
||||||
c_host_dest.to_str().unwrap(),
|
c_host_dest.to_str().unwrap(),
|
||||||
rust_host_dest.to_str().unwrap(),
|
rust_host_dest.to_str().unwrap(),
|
||||||
"-o",
|
"-o",
|
||||||
host_dest.to_str().unwrap(),
|
host_dest.to_str().unwrap(),
|
||||||
])
|
]);
|
||||||
.output()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
validate_output("rust_host.o", "ld", output);
|
run_build_command(ld_cmd, "rust_host.o");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up rust_host.o and c_host.o
|
// Clean up rust_host.o and c_host.o
|
||||||
|
@ -779,7 +767,7 @@ pub fn rebuild_host(
|
||||||
}
|
}
|
||||||
} else if c_host_src.exists() {
|
} else if c_host_src.exists() {
|
||||||
// Compile host.c, if it exists
|
// Compile host.c, if it exists
|
||||||
let output = build_c_host_native(
|
let clang_cmd = build_c_host_native(
|
||||||
target,
|
target,
|
||||||
&env_path,
|
&env_path,
|
||||||
&env_home,
|
&env_home,
|
||||||
|
@ -789,10 +777,11 @@ pub fn rebuild_host(
|
||||||
opt_level,
|
opt_level,
|
||||||
shared_lib_path,
|
shared_lib_path,
|
||||||
);
|
);
|
||||||
validate_output("host.c", "clang", output);
|
|
||||||
|
run_build_command(clang_cmd, "host.c");
|
||||||
} else if swift_host_src.exists() {
|
} else if swift_host_src.exists() {
|
||||||
// Compile host.swift, if it exists
|
// Compile host.swift, if it exists
|
||||||
let output = build_swift_host_native(
|
let swiftc_cmd = build_swift_host_native(
|
||||||
&env_path,
|
&env_path,
|
||||||
&env_home,
|
&env_home,
|
||||||
host_dest.to_str().unwrap(),
|
host_dest.to_str().unwrap(),
|
||||||
|
@ -804,7 +793,8 @@ pub fn rebuild_host(
|
||||||
.then(|| swift_host_header_src.to_str().unwrap()),
|
.then(|| swift_host_header_src.to_str().unwrap()),
|
||||||
target.architecture,
|
target.architecture,
|
||||||
);
|
);
|
||||||
validate_output("host.swift", "swiftc", output);
|
|
||||||
|
run_build_command(swiftc_cmd, "host.swift");
|
||||||
}
|
}
|
||||||
|
|
||||||
host_dest
|
host_dest
|
||||||
|
@ -873,7 +863,7 @@ fn link_linux(
|
||||||
|
|
||||||
if let Architecture::X86_32(_) = target.architecture {
|
if let Architecture::X86_32(_) = target.architecture {
|
||||||
return Ok((
|
return Ok((
|
||||||
Command::new(&zig_executable())
|
zig()
|
||||||
.args(&["build-exe"])
|
.args(&["build-exe"])
|
||||||
.args(input_paths)
|
.args(input_paths)
|
||||||
.args(&[
|
.args(&[
|
||||||
|
@ -1202,7 +1192,7 @@ fn link_wasm32(
|
||||||
let zig_str_path = find_zig_str_path();
|
let zig_str_path = find_zig_str_path();
|
||||||
let wasi_libc_path = find_wasi_libc_path();
|
let wasi_libc_path = find_wasi_libc_path();
|
||||||
|
|
||||||
let child = Command::new(&zig_executable())
|
let child = zig()
|
||||||
// .env_clear()
|
// .env_clear()
|
||||||
// .env("PATH", &env_path)
|
// .env("PATH", &env_path)
|
||||||
.args(&["build-exe"])
|
.args(&["build-exe"])
|
||||||
|
@ -1239,7 +1229,7 @@ fn link_windows(
|
||||||
|
|
||||||
match link_type {
|
match link_type {
|
||||||
LinkType::Dylib => {
|
LinkType::Dylib => {
|
||||||
let child = Command::new(&zig_executable())
|
let child = zig()
|
||||||
.args(&["build-lib"])
|
.args(&["build-lib"])
|
||||||
.args(input_paths)
|
.args(input_paths)
|
||||||
.args([
|
.args([
|
||||||
|
@ -1261,7 +1251,7 @@ fn link_windows(
|
||||||
Ok((child, output_path))
|
Ok((child, output_path))
|
||||||
}
|
}
|
||||||
LinkType::Executable => {
|
LinkType::Executable => {
|
||||||
let child = Command::new(&zig_executable())
|
let child = zig()
|
||||||
.args(&["build-exe"])
|
.args(&["build-exe"])
|
||||||
.args(input_paths)
|
.args(input_paths)
|
||||||
.args([
|
.args([
|
||||||
|
@ -1349,7 +1339,7 @@ pub fn preprocess_host_wasm32(host_input_path: &Path, preprocessed_host_path: &P
|
||||||
(but seems to be an unofficial API)
|
(but seems to be an unofficial API)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let mut command = Command::new(&zig_executable());
|
let mut zig_cmd = zig();
|
||||||
let args = &[
|
let args = &[
|
||||||
"wasm-ld",
|
"wasm-ld",
|
||||||
&bitcode::get_builtins_wasm32_obj_path(),
|
&bitcode::get_builtins_wasm32_obj_path(),
|
||||||
|
@ -1364,28 +1354,30 @@ pub fn preprocess_host_wasm32(host_input_path: &Path, preprocessed_host_path: &P
|
||||||
"--relocatable",
|
"--relocatable",
|
||||||
];
|
];
|
||||||
|
|
||||||
command.args(args);
|
zig_cmd.args(args);
|
||||||
|
|
||||||
// println!("\npreprocess_host_wasm32");
|
// println!("\npreprocess_host_wasm32");
|
||||||
// println!("zig {}\n", args.join(" "));
|
// println!("zig {}\n", args.join(" "));
|
||||||
|
|
||||||
let output = command.output().unwrap();
|
run_build_command(zig_cmd, output_file)
|
||||||
validate_output(output_file, "zig", output)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_output(file_name: &str, cmd_name: &str, output: Output) {
|
fn run_build_command(mut command: Command, file_to_build: &str) {
|
||||||
if !output.status.success() {
|
let cmd_str = format!("{:?}", &command);
|
||||||
match std::str::from_utf8(&output.stderr) {
|
let cmd_output = command.output().unwrap();
|
||||||
|
|
||||||
|
if !cmd_output.status.success() {
|
||||||
|
match std::str::from_utf8(&cmd_output.stderr) {
|
||||||
Ok(stderr) => internal_error!(
|
Ok(stderr) => internal_error!(
|
||||||
"Failed to rebuild {} - stderr of the `{}` command was:\n{}",
|
"Error:\n Failed to rebuild {}:\n The executed command was:\n {}\n stderr of that command:\n {}",
|
||||||
file_name,
|
file_to_build,
|
||||||
cmd_name,
|
cmd_str,
|
||||||
stderr
|
stderr
|
||||||
),
|
),
|
||||||
Err(utf8_err) => internal_error!(
|
Err(utf8_err) => internal_error!(
|
||||||
"Failed to rebuild {} - stderr of the `{}` command was invalid utf8 ({:?})",
|
"Error:\n Failed to rebuild {}:\n The executed command was:\n {}\n stderr of that command could not be parsed as valid utf8:\n {}",
|
||||||
file_name,
|
file_to_build,
|
||||||
cmd_name,
|
cmd_str,
|
||||||
utf8_err
|
utf8_err
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ lazy_static = "1.4.0"
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
# dunce can be removed once ziglang/zig#5109 is fixed
|
# dunce can be removed once ziglang/zig#5109 is fixed
|
||||||
dunce = "1.0.3"
|
dunce = "1.0.3"
|
||||||
|
roc_utils = { path = "../../utils" }
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.build-dependencies]
|
[target.'cfg(target_os = "macos")'.build-dependencies]
|
||||||
tempfile = "3.2.0"
|
tempfile = "3.2.0"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use std::convert::AsRef;
|
use roc_utils::zig;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::OsStr;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
@ -14,13 +13,6 @@ use tempfile::tempdir;
|
||||||
/// To debug the zig code with debug prints, we need to disable the wasm code gen
|
/// To debug the zig code with debug prints, we need to disable the wasm code gen
|
||||||
const DEBUG: bool = false;
|
const DEBUG: bool = false;
|
||||||
|
|
||||||
fn zig_executable() -> String {
|
|
||||||
match std::env::var("ROC_ZIG") {
|
|
||||||
Ok(path) => path,
|
|
||||||
Err(_) => "zig".into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
|
||||||
|
@ -95,12 +87,13 @@ fn generate_object_file(bitcode_path: &Path, zig_object: &str, object_file_name:
|
||||||
println!("Compiling zig object `{}` to: {}", zig_object, src_obj);
|
println!("Compiling zig object `{}` to: {}", zig_object, src_obj);
|
||||||
|
|
||||||
if !DEBUG {
|
if !DEBUG {
|
||||||
run_command(
|
let mut zig_cmd = zig();
|
||||||
&bitcode_path,
|
|
||||||
&zig_executable(),
|
zig_cmd
|
||||||
&["build", zig_object, "-Drelease=true"],
|
.current_dir(&bitcode_path)
|
||||||
0,
|
.args(["build", zig_object, "-Drelease=true"]);
|
||||||
);
|
|
||||||
|
run_command(zig_cmd, 0);
|
||||||
|
|
||||||
println!("Moving zig object `{}` to: {}", zig_object, dest_obj);
|
println!("Moving zig object `{}` to: {}", zig_object, dest_obj);
|
||||||
|
|
||||||
|
@ -130,12 +123,13 @@ fn generate_bc_file(bitcode_path: &Path, zig_object: &str, file_name: &str) {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
let _ = fs::remove_dir_all("./bitcode/zig-cache");
|
let _ = fs::remove_dir_all("./bitcode/zig-cache");
|
||||||
|
|
||||||
run_command(
|
let mut zig_cmd = zig();
|
||||||
&bitcode_path,
|
|
||||||
&zig_executable(),
|
zig_cmd
|
||||||
&["build", zig_object, "-Drelease=true"],
|
.current_dir(&bitcode_path)
|
||||||
0,
|
.args(["build", zig_object, "-Drelease=true"]);
|
||||||
);
|
|
||||||
|
run_command(zig_cmd, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_lib_dir() -> PathBuf {
|
pub fn get_lib_dir() -> PathBuf {
|
||||||
|
@ -204,19 +198,10 @@ fn cp_unless_zig_cache(src_dir: &Path, target_dir: &Path) -> io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_command<S, I: Copy, P: AsRef<Path> + Copy>(
|
fn run_command(mut command: Command, flaky_fail_counter: usize) {
|
||||||
path: P,
|
let command_str = format!("{:?}", &command);
|
||||||
command_str: &str,
|
|
||||||
args: I,
|
let output_result = command.output();
|
||||||
flaky_fail_counter: usize,
|
|
||||||
) where
|
|
||||||
I: IntoIterator<Item = S>,
|
|
||||||
S: AsRef<OsStr>,
|
|
||||||
{
|
|
||||||
let output_result = Command::new(OsStr::new(&command_str))
|
|
||||||
.current_dir(path)
|
|
||||||
.args(args)
|
|
||||||
.output();
|
|
||||||
|
|
||||||
match output_result {
|
match output_result {
|
||||||
Ok(output) => match output.status.success() {
|
Ok(output) => match output.status.success() {
|
||||||
|
@ -234,7 +219,7 @@ fn run_command<S, I: Copy, P: AsRef<Path> + Copy>(
|
||||||
if flaky_fail_counter == 10 {
|
if flaky_fail_counter == 10 {
|
||||||
panic!("{} failed 10 times in a row. The following error is unlikely to be a flaky error: {}", command_str, error_str);
|
panic!("{} failed 10 times in a row. The following error is unlikely to be a flaky error: {}", command_str, error_str);
|
||||||
} else {
|
} else {
|
||||||
run_command(path, command_str, args, flaky_fail_counter + 1)
|
run_command(command, flaky_fail_counter + 1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("{} failed: {}", command_str, error_str);
|
panic!("{} failed: {}", command_str, error_str);
|
||||||
|
|
|
@ -11,6 +11,7 @@ path = "src/tests.rs"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
roc_builtins = { path = "../builtins" }
|
roc_builtins = { path = "../builtins" }
|
||||||
|
roc_utils = { path = "../../utils" }
|
||||||
wasi_libc_sys = { path = "../../wasi-libc-sys" }
|
wasi_libc_sys = { path = "../../wasi-libc-sys" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -25,6 +26,7 @@ roc_types = { path = "../types" }
|
||||||
roc_builtins = { path = "../builtins" }
|
roc_builtins = { path = "../builtins" }
|
||||||
roc_constrain = { path = "../constrain" }
|
roc_constrain = { path = "../constrain" }
|
||||||
roc_unify = { path = "../unify" }
|
roc_unify = { path = "../unify" }
|
||||||
|
roc_utils = { path = "../../utils" }
|
||||||
roc_solve = { path = "../solve" }
|
roc_solve = { path = "../solve" }
|
||||||
roc_mono = { path = "../mono" }
|
roc_mono = { path = "../mono" }
|
||||||
roc_reporting = { path = "../../reporting" }
|
roc_reporting = { path = "../../reporting" }
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use roc_builtins::bitcode;
|
use roc_builtins::bitcode;
|
||||||
|
use roc_utils::zig;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
use wasi_libc_sys::{WASI_COMPILER_RT_PATH, WASI_LIBC_PATH};
|
use wasi_libc_sys::{WASI_COMPILER_RT_PATH, WASI_LIBC_PATH};
|
||||||
|
|
||||||
|
@ -113,13 +113,6 @@ fn build_wasm_test_host() {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zig_executable() -> String {
|
|
||||||
match std::env::var("ROC_ZIG") {
|
|
||||||
Ok(path) => path,
|
|
||||||
Err(_) => "zig".into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_wasm_platform(out_dir: &str, source_path: &str) -> PathBuf {
|
fn build_wasm_platform(out_dir: &str, source_path: &str) -> PathBuf {
|
||||||
let mut outfile = PathBuf::from(out_dir).join(PLATFORM_FILENAME);
|
let mut outfile = PathBuf::from(out_dir).join(PLATFORM_FILENAME);
|
||||||
outfile.set_extension("o");
|
outfile.set_extension("o");
|
||||||
|
@ -146,16 +139,25 @@ fn feature_is_enabled(feature_name: &str) -> bool {
|
||||||
|
|
||||||
// Run cargo with -vv to see commands printed out
|
// Run cargo with -vv to see commands printed out
|
||||||
fn run_zig(args: &[&str]) {
|
fn run_zig(args: &[&str]) {
|
||||||
let zig = zig_executable();
|
let mut zig_cmd = zig();
|
||||||
println!("{} {}", zig, args.join(" "));
|
|
||||||
let output = Command::new(&zig).args(args).output().unwrap();
|
|
||||||
|
|
||||||
if !output.status.success() {
|
let full_zig_cmd = zig_cmd.args(args);
|
||||||
eprintln!("stdout:\n{}", String::from_utf8_lossy(&output.stdout));
|
println!("{:?}", full_zig_cmd);
|
||||||
eprintln!("stderr:\n{}", String::from_utf8_lossy(&output.stderr));
|
|
||||||
panic!("zig call failed with status {:?}", output.status);
|
let zig_cmd_output = full_zig_cmd.output().unwrap();
|
||||||
|
|
||||||
|
if !zig_cmd_output.status.success() {
|
||||||
|
eprintln!(
|
||||||
|
"stdout:\n{}",
|
||||||
|
String::from_utf8_lossy(&zig_cmd_output.stdout)
|
||||||
|
);
|
||||||
|
eprintln!(
|
||||||
|
"stderr:\n{}",
|
||||||
|
String::from_utf8_lossy(&zig_cmd_output.stderr)
|
||||||
|
);
|
||||||
|
panic!("zig call failed with status {:?}", zig_cmd_output.status);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(output.stdout.is_empty(), "{:#?}", output);
|
assert!(zig_cmd_output.stdout.is_empty(), "{:#?}", zig_cmd_output);
|
||||||
assert!(output.stderr.is_empty(), "{:#?}", output);
|
assert!(zig_cmd_output.stderr.is_empty(), "{:#?}", zig_cmd_output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ use roc_load::{EntryPoint, ExecutionMode, LoadConfig, Threading};
|
||||||
use roc_mono::ir::OptLevel;
|
use roc_mono::ir::OptLevel;
|
||||||
use roc_region::all::LineInfo;
|
use roc_region::all::LineInfo;
|
||||||
use roc_reporting::report::RenderTarget;
|
use roc_reporting::report::RenderTarget;
|
||||||
|
use roc_utils::zig;
|
||||||
use target_lexicon::Triple;
|
use target_lexicon::Triple;
|
||||||
|
|
||||||
#[cfg(feature = "gen-llvm-wasm")]
|
#[cfg(feature = "gen-llvm-wasm")]
|
||||||
|
@ -456,9 +457,7 @@ fn llvm_module_to_wasm_file(
|
||||||
.write_to_file(llvm_module, file_type, &test_a_path)
|
.write_to_file(llvm_module, file_type, &test_a_path)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
use std::process::Command;
|
let output = zig()
|
||||||
|
|
||||||
let output = Command::new(&crate::helpers::zig_executable())
|
|
||||||
.current_dir(dir_path)
|
.current_dir(dir_path)
|
||||||
.args(&[
|
.args(&[
|
||||||
"wasm-ld",
|
"wasm-ld",
|
||||||
|
|
|
@ -10,14 +10,6 @@ pub mod llvm;
|
||||||
#[cfg(any(feature = "gen-wasm", feature = "gen-llvm-wasm"))]
|
#[cfg(any(feature = "gen-wasm", feature = "gen-llvm-wasm"))]
|
||||||
pub mod wasm;
|
pub mod wasm;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn zig_executable() -> String {
|
|
||||||
match std::env::var("ROC_ZIG") {
|
|
||||||
Ok(path) => path,
|
|
||||||
Err(_) => "zig".into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn src_hash(src: &str) -> u64 {
|
pub(crate) fn src_hash(src: &str) -> u64 {
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
|
|
|
@ -30,6 +30,7 @@ roc_problem = { path = "../compiler/problem" }
|
||||||
roc_types = { path = "../compiler/types" }
|
roc_types = { path = "../compiler/types" }
|
||||||
roc_unify = { path = "../compiler/unify" }
|
roc_unify = { path = "../compiler/unify" }
|
||||||
roc_reporting = { path = "../reporting" }
|
roc_reporting = { path = "../reporting" }
|
||||||
|
roc_utils = { path = "../utils" }
|
||||||
roc_solve = { path = "../compiler/solve" }
|
roc_solve = { path = "../compiler/solve" }
|
||||||
ven_graph = { path = "../vendor/pathfinding" }
|
ven_graph = { path = "../vendor/pathfinding" }
|
||||||
bumpalo = { version = "3.11.0", features = ["collections"] }
|
bumpalo = { version = "3.11.0", features = ["collections"] }
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::process::Command;
|
|
||||||
use std::process::Stdio;
|
use std::process::Stdio;
|
||||||
|
|
||||||
use crate::editor::code_lines::CodeLines;
|
use crate::editor::code_lines::CodeLines;
|
||||||
|
@ -63,6 +62,7 @@ use roc_solve::module::Solved;
|
||||||
use roc_types::pretty_print::name_and_print_var;
|
use roc_types::pretty_print::name_and_print_var;
|
||||||
use roc_types::pretty_print::DebugPrint;
|
use roc_types::pretty_print::DebugPrint;
|
||||||
use roc_types::subs::{Subs, VarStore, Variable};
|
use roc_types::subs::{Subs, VarStore, Variable};
|
||||||
|
use roc_utils::cargo;
|
||||||
use snafu::OptionExt;
|
use snafu::OptionExt;
|
||||||
use threadpool::ThreadPool;
|
use threadpool::ThreadPool;
|
||||||
use winit::event::VirtualKeyCode;
|
use winit::event::VirtualKeyCode;
|
||||||
|
@ -622,7 +622,7 @@ impl<'a> EdModel<'a> {
|
||||||
|
|
||||||
let roc_file_str = path_to_string(self.file_path);
|
let roc_file_str = path_to_string(self.file_path);
|
||||||
|
|
||||||
let cmd_out = Command::new("cargo")
|
let cmd_out = cargo()
|
||||||
.arg("run")
|
.arg("run")
|
||||||
.arg("check")
|
.arg("check")
|
||||||
.arg(roc_file_str)
|
.arg(roc_file_str)
|
||||||
|
@ -641,7 +641,7 @@ impl<'a> EdModel<'a> {
|
||||||
|
|
||||||
let roc_file_str = path_to_string(self.file_path);
|
let roc_file_str = path_to_string(self.file_path);
|
||||||
|
|
||||||
Command::new("cargo")
|
cargo()
|
||||||
.arg("run")
|
.arg("run")
|
||||||
.arg(roc_file_str)
|
.arg(roc_file_str)
|
||||||
.stdout(Stdio::inherit())
|
.stdout(Stdio::inherit())
|
||||||
|
|
|
@ -10,6 +10,7 @@ crate-type = ["cdylib"]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
roc_builtins = {path = "../compiler/builtins"}
|
roc_builtins = {path = "../compiler/builtins"}
|
||||||
|
roc_utils = {path = "../utils"}
|
||||||
wasi_libc_sys = { path = "../wasi-libc-sys" }
|
wasi_libc_sys = { path = "../wasi-libc-sys" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use snafu::OptionExt;
|
use snafu::OptionExt;
|
||||||
use std::{collections::HashMap, path::PathBuf, slice::SliceIndex};
|
use std::{collections::HashMap, path::PathBuf, process::Command, slice::SliceIndex};
|
||||||
use util_error::{IndexOfFailedSnafu, KeyNotFoundSnafu, OutOfBoundsSnafu, UtilResult};
|
use util_error::{IndexOfFailedSnafu, KeyNotFoundSnafu, OutOfBoundsSnafu, UtilResult};
|
||||||
|
|
||||||
pub mod util_error;
|
pub mod util_error;
|
||||||
|
@ -120,3 +120,81 @@ pub fn get_lib_path() -> Option<PathBuf> {
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gives a friendly error if cargo is not installed.
|
||||||
|
/// Also makes it easy to track where we use cargo in the codebase.
|
||||||
|
pub fn cargo() -> Command {
|
||||||
|
let command_str = "cargo";
|
||||||
|
|
||||||
|
if check_command_available(command_str) {
|
||||||
|
Command::new(command_str)
|
||||||
|
} else {
|
||||||
|
panic!("I could not find the cargo command.\nVisit https://rustup.rs/ to install cargo.",)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gives a friendly error if clang is not installed.
|
||||||
|
/// Also makes it easy to track where we use clang in the codebase.
|
||||||
|
pub fn clang() -> Command {
|
||||||
|
let command_str = "clang";
|
||||||
|
|
||||||
|
if check_command_available(command_str) {
|
||||||
|
Command::new(command_str)
|
||||||
|
} else {
|
||||||
|
panic!("I could not find the clang command.\nPlease install clang.",)
|
||||||
|
//TODO detect OS and provide detailed install instructions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gives a friendly error if zig is not installed.
|
||||||
|
/// Also makes it easy to track where we use zig in the codebase.
|
||||||
|
pub fn zig() -> Command {
|
||||||
|
let command_str = match std::env::var("ROC_ZIG") {
|
||||||
|
Ok(path) => path,
|
||||||
|
Err(_) => "zig".into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if check_command_available(&command_str) {
|
||||||
|
Command::new(command_str)
|
||||||
|
} else {
|
||||||
|
panic!("I could not find the zig command.\nPlease install zig, see instructions at https://ziglang.org/learn/getting-started/.",)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_command_available(command_name: &str) -> bool {
|
||||||
|
if cfg!(target_family = "unix") {
|
||||||
|
let mut cmd = Command::new("which");
|
||||||
|
|
||||||
|
cmd.args([command_name]);
|
||||||
|
|
||||||
|
let cmd_str = format!("{:?}", cmd);
|
||||||
|
|
||||||
|
let cmd_out = cmd.output().unwrap_or_else(|err| {
|
||||||
|
panic!(
|
||||||
|
"Failed to execute `{}` to check if {} is available:\n {}",
|
||||||
|
cmd_str, command_name, err
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
cmd_out.status.success()
|
||||||
|
} else if cfg!(target = "windows") {
|
||||||
|
let mut cmd = Command::new("Get-Command");
|
||||||
|
|
||||||
|
cmd.args([command_name]);
|
||||||
|
|
||||||
|
let cmd_str = format!("{:?}", cmd);
|
||||||
|
|
||||||
|
let cmd_out = cmd.output().unwrap_or_else(|err| {
|
||||||
|
panic!(
|
||||||
|
"Failed to execute `{}` to check if {} is available:\n {}",
|
||||||
|
cmd_str, command_name, err
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
cmd_out.status.success()
|
||||||
|
} else {
|
||||||
|
// We're in uncharted waters, best not to panic if
|
||||||
|
// things may end up working out down the line.
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,3 +6,6 @@ license = "UPL-1.0"
|
||||||
name = "wasi_libc_sys"
|
name = "wasi_libc_sys"
|
||||||
repository = "https://github.com/roc-lang/roc"
|
repository = "https://github.com/roc-lang/roc"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
roc_utils = {path = "../utils"}
|
|
@ -1,8 +1,8 @@
|
||||||
|
use roc_utils::zig;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
@ -13,7 +13,7 @@ fn main() {
|
||||||
let out_file = PathBuf::from(&out_dir).join("wasi-libc.a");
|
let out_file = PathBuf::from(&out_dir).join("wasi-libc.a");
|
||||||
|
|
||||||
// Compile a dummy C program with Zig, with our own private cache directory
|
// Compile a dummy C program with Zig, with our own private cache directory
|
||||||
Command::new(&zig_executable())
|
zig()
|
||||||
.args([
|
.args([
|
||||||
"build-exe",
|
"build-exe",
|
||||||
"-target",
|
"-target",
|
||||||
|
@ -51,13 +51,6 @@ fn main() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn zig_executable() -> String {
|
|
||||||
match std::env::var("ROC_ZIG") {
|
|
||||||
Ok(path) => path,
|
|
||||||
Err(_) => "zig".into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find(dir: &Path, filename: &OsString) -> std::io::Result<Option<PathBuf>> {
|
fn find(dir: &Path, filename: &OsString) -> std::io::Result<Option<PathBuf>> {
|
||||||
for entry in fs::read_dir(dir)? {
|
for entry in fs::read_dir(dir)? {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue