Resolve conflicts

This commit is contained in:
Chad Stearns 2020-10-28 19:48:33 -04:00
commit f2983f1360
19 changed files with 358 additions and 220 deletions

View file

@ -56,6 +56,13 @@ jobs:
with: with:
command: test command: test
- uses: actions-rs/cargo@v1
name: cargo test -- --ignored
continue-on-error: true
with:
command: test
args: -- --ignored
- uses: actions-rs/cargo@v1 - uses: actions-rs/cargo@v1
name: cargo test --release name: cargo test --release
with: with:

View file

@ -1,23 +1,37 @@
# Building the Roc compiler from source # Building the Roc compiler from source
## Installing LLVM, valgrind, libunwind, and libc++-dev ## Installing LLVM, Zig, valgrind, libunwind, and libc++-dev
To build the compiler, you need these installed: To build the compiler, you need these installed:
* `libunwind` (macOS should already have this one installed) * `libunwind` (macOS should already have this one installed)
* `libc++-dev` * `libc++-dev`
* [`zig`](https://ziglang.org/download/) * a particular version of Zig (see below)
* a particular version of LLVM * a particular version of LLVM (see below)
To run the test suite (via `cargo test`), you additionally need to install: To run the test suite (via `cargo test`), you additionally need to install:
* [`valgrind`](https://www.valgrind.org/) (needs special treatment to [install on macOS](https://stackoverflow.com/a/61359781)] * [`valgrind`](https://www.valgrind.org/) (needs special treatment to [install on macOS](https://stackoverflow.com/a/61359781)
Alternatively, you can use `cargo test --no-fail-fast` or `cargo test -p specific_tests` to skip over the valgrind failures & tests.
### libunwind & libc++-dev
MacOS systems should already have `libunwind`, but other systems will need to install it (On Ubuntu, this can be donw with `sudo apt-get install libunwind-dev`).
Some systems may already have `libc++-dev` on them, but if not, you may need to install it. (On Ubuntu, this can be done with `sudo apt-get install libc++-dev`.) Some systems may already have `libc++-dev` on them, but if not, you may need to install it. (On Ubuntu, this can be done with `sudo apt-get install libc++-dev`.)
MacOS systems should already have `libunwind`, but other systems will need to install it (e.g. with `sudo apt-get install libunwind-dev`).
To install Zig on macOS, use `brew install zig`. To install on Ubuntu, checkout [zig's docs](https://github.com/dryzig/zig-debian/blob/master/README.md). ### Zig
We use a specific version of Zig, a build off the the commit `0088efc4b`. The latest tagged version of Zig, 0.6.0, doesn't include the feature to emit LLVM ir, which is a core feature of how we use Zig. To download this specific version, you can use the following links:
* [linux](https://ziglang.org/builds/zig-linux-x86_64-0.6.0+0088efc4b.tar.xz)
* [macOS](https://ziglang.org/builds/zig-macos-x86_64-0.6.0+0088efc4b.tar.xz)
Alternatively, any recent master branch build should work. To install the latest master branch build you can use:
* `brew install zig --HEAD` (on macos)
* `snap install zig --classic --edge` (on ubunutu)
Once 0.7.0 is released, we'll switch back to installing the tagged releases and this process will get easier.
### LLVM
To see which version of LLVM you need, take a look at `Cargo.toml`, in particular the `branch` section of the `inkwell` dependency. It should have something like `llvmX-Y` where X and Y are the major and minor revisions of LLVM you need. To see which version of LLVM you need, take a look at `Cargo.toml`, in particular the `branch` section of the `inkwell` dependency. It should have something like `llvmX-Y` where X and Y are the major and minor revisions of LLVM you need.

23
Cargo.lock generated
View file

@ -2318,6 +2318,7 @@ dependencies = [
"roc_uniq", "roc_uniq",
"serde", "serde",
"serde-xml-rs", "serde-xml-rs",
"serial_test",
"strip-ansi-escapes", "strip-ansi-escapes",
"target-lexicon", "target-lexicon",
"tempfile", "tempfile",
@ -2804,6 +2805,28 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "serial_test"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b15f74add9a9d4a3eb2bf739c9a427d266d3895b53d992c3a7c234fec2ff1f1"
dependencies = [
"lazy_static",
"parking_lot 0.10.2",
"serial_test_derive",
]
[[package]]
name = "serial_test_derive"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65f59259be9fc1bf677d06cc1456e97756004a1a5a577480f71430bd7c17ba33"
dependencies = [
"proc-macro2 1.0.21",
"quote 1.0.7",
"syn 1.0.40",
]
[[package]] [[package]]
name = "sha-1" name = "sha-1"
version = "0.8.2" version = "0.8.2"

View file

@ -61,11 +61,10 @@ add-apt-repository "${REPO_NAME}"
apt-get update apt-get update
apt-get install -y clang-$LLVM_VERSION lldb-$LLVM_VERSION lld-$LLVM_VERSION clangd-$LLVM_VERSION libc++abi-dev libunwind-dev valgrind apt-get install -y clang-$LLVM_VERSION lldb-$LLVM_VERSION lld-$LLVM_VERSION clangd-$LLVM_VERSION libc++abi-dev libunwind-dev valgrind
# install zig # install zig - can't use apt-get since we require at least a specific commit later then the most recent tag (0.6.0)
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 379CE192D401AB61 wget -c https://ziglang.org/builds/zig-linux-x86_64-0.6.0+0088efc4b.tar.xz --no-check-certificate
echo 'deb https://dl.bintray.com/dryzig/zig-ubuntu bionic main' | tee -a /etc/apt/sources.list tar -xf zig-linux-x86_64-0.6.0+0088efc4b.tar.xz
apt update ln -s "$PWD/zig-linux-x86_64-0.6.0+0088efc4b/zig" /usr/local/bin/zig
apt install zig
# symlink llvm tools # symlink llvm tools
ln -s /usr/bin/llvm-as-10 /usr/local/bin/llvm-as ln -s /usr/bin/llvm-as-10 /usr/local/bin/llvm-as

View file

@ -89,4 +89,5 @@ quickcheck_macros = "0.8"
strip-ansi-escapes = "0.1" strip-ansi-escapes = "0.1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde-xml-rs = "0.4" serde-xml-rs = "0.4"
serial_test = "0.5"
tempfile = "3.1.0" tempfile = "3.1.0"

View file

@ -12,123 +12,174 @@ mod helpers;
#[cfg(test)] #[cfg(test)]
mod cli_run { mod cli_run {
use crate::helpers::{ use crate::helpers::{
example_file, extract_valgrind_errors, run_cmd, run_roc, run_with_valgrind, Out, example_file, extract_valgrind_errors, run_cmd, run_roc, run_with_valgrind,
}; };
use serial_test::serial;
#[test] fn check_output(
fn run_hello_world() { folder: &str,
fn check_hello_world_output(out: Out) { file: &str,
if !out.stderr.is_empty() { flags: &[&str],
panic!(out.stderr); expected_ending: &str,
} use_valgrind: bool,
assert!(out.status.success()); ) {
let compile_out = run_roc(
let (valgrind_out, raw_xml) = &[
run_with_valgrind(&[example_file("hello-world", "app").to_str().unwrap()]); &["build", example_file(folder, file).to_str().unwrap()],
flags,
let ending = "Hello, World!!!!!!!!!!!!!\n"; ]
if !&valgrind_out.stdout.ends_with(ending) { .concat(),
panic!(
"expected output to end with {:?} but instead got {:?}",
ending, &valgrind_out.stdout
); );
if !compile_out.stderr.is_empty() {
panic!(compile_out.stderr);
} }
assert!(compile_out.status.success());
let out = if use_valgrind {
let (valgrind_out, raw_xml) =
run_with_valgrind(&[example_file(folder, "app").to_str().unwrap()]);
let memory_errors = extract_valgrind_errors(&raw_xml); let memory_errors = extract_valgrind_errors(&raw_xml);
if !memory_errors.is_empty() { if !memory_errors.is_empty() {
panic!("{:?}", memory_errors); panic!("{:?}", memory_errors);
} }
assert!(valgrind_out.status.success()); valgrind_out
} else {
run_cmd(example_file(folder, "app").to_str().unwrap(), &[])
};
if !&out.stdout.ends_with(expected_ending) {
panic!(
"expected output to end with {:?} but instead got {:#?}",
expected_ending, out
);
} }
check_hello_world_output(run_roc(&[ assert!(out.status.success());
"build",
example_file("hello-world", "Hello.roc").to_str().unwrap(),
]));
check_hello_world_output(run_roc(&[
"build",
"--optimize",
example_file("hello-world", "Hello.roc").to_str().unwrap(),
]));
} }
#[test] #[test]
#[serial(hello_world)]
fn run_hello_world() {
check_output(
"hello-world",
"Hello.roc",
&[],
"Hello, World!!!!!!!!!!!!!\n",
true,
);
}
#[test]
#[serial(hello_world)]
fn run_hello_world_optimized() {
check_output(
"hello-world",
"Hello.roc",
&[],
"Hello, World!!!!!!!!!!!!!\n",
true,
);
}
#[test]
#[serial(quicksort)]
fn run_quicksort() { fn run_quicksort() {
fn check_quicksort_output(out: Out) { check_output(
if !out.stderr.is_empty() { "quicksort",
panic!(out.stderr); "Quicksort.roc",
} &[],
assert!(out.status.success()); "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n",
false,
// let (valgrind_out, raw_xml) =
// run_with_valgrind(&[example_file("quicksort", "app").to_str().unwrap()]);
let valgrind_out = run_cmd(example_file("quicksort", "app").to_str().unwrap(), &[]);
let ending = "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n";
if !&valgrind_out.stdout.ends_with(ending) {
panic!(
"expected output to end with {:?} but instead got {:?}",
ending, &valgrind_out.stdout
); );
} }
// let memory_errors = extract_valgrind_errors(&raw_xml);
// if !memory_errors.is_empty() {
// panic!("{:?}", memory_errors);
// }
assert!(valgrind_out.status.success());
}
// TODO: Uncomment this once we are correctly freeing the RocList even when in dev build.
/*
check_quicksort_output(run_roc(&[
"build",
example_file("quicksort", "Quicksort.roc").to_str().unwrap(),
]));
*/
check_quicksort_output(run_roc(&[
"build",
"--optimize",
example_file("quicksort", "Quicksort.roc").to_str().unwrap(),
]));
}
#[test] #[test]
fn run_multi_module() { #[serial(quicksort)]
fn check_muti_module_output(out: Out) { fn run_quicksort_optimized() {
if !out.stderr.is_empty() { check_output(
panic!(out.stderr); "quicksort",
} "Quicksort.roc",
assert!(out.status.success()); &["--optimize"],
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n",
// let (valgrind_out, raw_xml) = false,
// run_with_valgrind(&[example_file("multi-module", "app").to_str().unwrap()]);
let valgrind_out = run_cmd(example_file("multi-module", "app").to_str().unwrap(), &[]);
let ending = "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n";
if !&valgrind_out.stdout.ends_with(ending) {
panic!(
"expected output to end with {:?} but instead got {:?}",
ending, &valgrind_out.stdout
); );
} }
// let memory_errors = extract_valgrind_errors(&raw_xml);
// if !memory_errors.is_empty() { #[test]
// panic!("{:?}", memory_errors); #[serial(quicksort)]
// } // TODO: Stop ignoring this test once we are correctly freeing the RocList even when in dev build.
assert!(valgrind_out.status.success()); #[ignore]
fn run_quicksort_valgrind() {
check_output(
"quicksort",
"Quicksort.roc",
&[],
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n",
true,
);
} }
// TODO: Uncomment this once we are correctly freeing the RocList even when in dev build. #[test]
/* #[serial(quicksort)]
check_muti_module_output(run_roc(&[ // TODO: Stop ignoring this test once valgrind supports AVX512.
"run", #[ignore]
example_file("multi-module", "Quicksort.roc") fn run_quicksort_optimized_valgrind() {
.to_str() check_output(
.unwrap(), "quicksort",
])); "Quicksort.roc",
*/ &["--optimize"],
check_muti_module_output(run_roc(&[ "[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n",
"run", true,
example_file("multi-module", "Quicksort.roc") );
.to_str() }
.unwrap(),
"--optimize", #[test]
])); #[serial(multi_module)]
fn run_multi_module() {
check_output(
"multi-module",
"Quicksort.roc",
&[],
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n",
false,
);
}
#[test]
#[serial(multi_module)]
fn run_multi_module_optimized() {
check_output(
"multi-module",
"Quicksort.roc",
&["--optimize"],
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n",
false,
);
}
#[test]
#[serial(multi_module)]
// TODO: Stop ignoring this test once we are correctly freeing the RocList even when in dev build.
#[ignore]
fn run_multi_module_valgrind() {
check_output(
"multi-module",
"Quicksort.roc",
&[],
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n",
true,
);
}
#[test]
#[serial(multi_module)]
// TODO: Stop ignoring this test once valgrind supports AVX512.
#[ignore]
fn run_multi_module_optimized_valgrind() {
check_output(
"multi-module",
"Quicksort.roc",
&["--optimize"],
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2]\n",
true,
);
} }
} }

View file

@ -15,6 +15,7 @@ use std::path::PathBuf;
use std::process::{Command, ExitStatus, Stdio}; use std::process::{Command, ExitStatus, Stdio};
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
#[derive(Debug)]
pub struct Out { pub struct Out {
pub stdout: String, pub stdout: String,
pub stderr: String, pub stderr: String,
@ -131,6 +132,9 @@ enum ValgrindField {
Args(ValgrindDummyStruct), Args(ValgrindDummyStruct),
Error(ValgrindError), Error(ValgrindError),
Status(ValgrindDummyStruct), Status(ValgrindDummyStruct),
Stack(ValgrindDummyStruct),
#[serde(rename = "fatal_signal")]
FatalSignal(ValgrindDummyStruct),
ErrorCounts(ValgrindDummyStruct), ErrorCounts(ValgrindDummyStruct),
SuppCounts(ValgrindDummyStruct), SuppCounts(ValgrindDummyStruct),
} }

View file

@ -68,7 +68,7 @@ pub fn target_machine(
Target::from_name(arch).unwrap().create_target_machine( Target::from_name(arch).unwrap().create_target_machine(
&TargetTriple::create(target_triple_str(target)), &TargetTriple::create(target_triple_str(target)),
arch, arch,
"+avx2", // TODO this string was used uncritically from an example, and should be reexamined "", // TODO: this probably should be TargetMachine::get_host_cpu_features() to enable all features.
opt, opt,
reloc, reloc,
model, model,

View file

@ -1,4 +1,2 @@
main.ll
main.o
src/zig-cache
zig-cache zig-cache
src/zig-cache

View file

@ -5,31 +5,19 @@ When their implementations are simple enough (e.g. addition), they
can be implemented directly in Inkwell. can be implemented directly in Inkwell.
When their implementations are complex enough, it's nicer to When their implementations are complex enough, it's nicer to
implement them in a higher-level language like C (or eventually Zig), implement them in a higher-level language like Zig, then compile
compile the result to LLVM bitcode, and import that bitcode into the compiler. the result to LLVM bitcode, and import that bitcode into the compiler.
Compiling the bitcode happens automatically in a Rust build script at `compiler/gen/build.rs`. Compiling the bitcode happens automatically in a Rust build script at `compiler/builtins/build.rs`.
You can find the compiled bitcode in `target/debug/build/roc_gen-[some random characters]/out/builtins.bc`. Then `builtins/src/bitcode/rs` staticlly imports the compiled bitcode for use in the compiler.
> If you want to take a look at the human-readable LLVM IR, cd into `compiler/builtins/bitcode` and You can find the compiled bitcode in `target/debug/build/roc_builtins-[some random characters]/out/builtins.bc`.
> run the following command. It should create `compiler/builtins/bitcode/lib.ll` There will be two directories like `roc_builtins-[some random characters]`, look for the one that has an
> `out` directory as a child.
> ```bash
> zig build-obj src/main.zig -femit-llvm-ir=test.ll -fno-emit-bin --strip
> ```
>
> NOTE: The full command that we use when generating the bitcode is:
> ```bash
> zig build-obj src/main.zig -femit-llvm-ir=test.ll -fno-emit-bin --strip -O ReleaseSafe
> ```
> This is probably less readable then the first command, because it does some mangling of
> non-exported names, etc. But if you're hitting a bug, it may be helpful.
The bitcode is a bunch of bytes that aren't particularly human-readable. > The bitcode is a bunch of bytes that aren't particularly human-readable.
Since Roc is designed to be distributed as a single binary, these bytes > If you want to take a look at the human-readable LLVM IR, look at
need to be included in the raw source somewhere. > `target/debug/build/roc_builtins-[some random characters]/out/builtins.ll`
The `llvm/src/build.rs` file statically imports these raw bytes.
## Calling bitcode functions ## Calling bitcode functions

View file

@ -1,19 +1,21 @@
const std = @import("std"); const std = @import("std");
const math = std.math;
const expect = std.testing.expect; const expect = std.testing.expect;
const print = std.debug.print;
export fn is_finite_(f: f64) bool { export fn atan_(num: f64) f64 {
return std.math.isFinite(f); return math.atan(num);
} }
export fn atan_(f: f64) f64 { export fn is_finite_(num: f64) bool {
return std.math.atan(f); return math.isFinite(num);
} }
export fn pow_int_(base: i64, exp: i64) i64 { export fn pow_int_(base: i64, exp: i64) i64 {
return std.math.pow(i64, base, exp); return math.pow(i64, base, exp);
} }
// Str.split
const RocStr = struct { const RocStr = struct {
str_bytes: [*]u8, str_bytes: [*]u8,
str_len: usize, str_len: usize,

View file

@ -0,0 +1,70 @@
use std::convert::AsRef;
use std::env;
use std::ffi::OsStr;
use std::path::Path;
use std::process::Command;
use std::str;
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),
}
}
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").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",
src_path_str,
&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", &[dest_ll, "-o", dest_bc]);
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed={}", src_path_str);
println!("cargo:rustc-env=BUILTINS_BC={}", dest_bc);
}

View file

@ -0,0 +1,18 @@
use std::fs::File;
use std::io::prelude::Read;
use std::vec::Vec;
pub fn get_bytes() -> Vec<u8> {
// In the build script for the builtins module, we compile the builtins bitcode and set
// BUILTINS_BC to the path to the compiled output.
let path: &'static str = env!(
"BUILTINS_BC",
"Env var BUILTINS_BC not found. Is there a problem with the build script?"
);
let mut builtins_bitcode = File::open(path).expect("Unable to find builtins bitcode source");
let mut buffer = Vec::new();
builtins_bitcode
.read_to_end(&mut buffer)
.expect("Unable to read builtins bitcode");
buffer
}

View file

@ -10,5 +10,6 @@
// and encouraging shortcuts here creates bad incentives. I would rather temporarily // and encouraging shortcuts here creates bad incentives. I would rather temporarily
// re-enable this when working on performance optimizations than have it block PRs. // re-enable this when working on performance optimizations than have it block PRs.
#![allow(clippy::large_enum_variant)] #![allow(clippy::large_enum_variant)]
pub mod bitcode;
pub mod std; pub mod std;
pub mod unique; pub mod unique;

View file

@ -1,31 +0,0 @@
use std::env;
use std::fs;
use std::path::Path;
use std::process::Command;
fn main() {
let src_path = fs::canonicalize("./../builtins/bitcode/src/main.zig")
.expect("Failed to resolve bitcode source");
let src = src_path.to_str().expect("Invalid src path");
let out_dir = env::var_os("OUT_DIR").unwrap();
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;
Command::new("zig")
.args(&["build-obj", src, &emit_ir_arg, "-fno-emit-bin", "--strip", "-O", "ReleaseFast"])
.status()
.unwrap();
let dest_bc_path = Path::new(&out_dir).join("builtins.bc");
let dest_bc = dest_bc_path.to_str().expect("Invalid dest bc path");
Command::new("llvm-as")
.args(&[dest_ll, "-o", dest_bc])
.status()
.unwrap();
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed={}", src);
println!("cargo:rustc-env=BUILTINS_BC={}", dest_bc);
}

View file

@ -29,13 +29,12 @@ use inkwell::values::{
}; };
use inkwell::OptimizationLevel; use inkwell::OptimizationLevel;
use inkwell::{AddressSpace, IntPredicate}; use inkwell::{AddressSpace, IntPredicate};
use roc_builtins::bitcode;
use roc_collections::all::{ImMap, MutSet}; use roc_collections::all::{ImMap, MutSet};
use roc_module::low_level::LowLevel; use roc_module::low_level::LowLevel;
use roc_module::symbol::{Interns, ModuleId, Symbol}; use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_mono::ir::{JoinPointId, Wrapped}; use roc_mono::ir::{JoinPointId, Wrapped};
use roc_mono::layout::{Builtin, Layout, MemoryMode}; use roc_mono::layout::{Builtin, Layout, MemoryMode};
use std::fs::File;
use std::io::prelude::Read;
use target_lexicon::CallingConvention; use target_lexicon::CallingConvention;
/// This is for Inkwell's FunctionValue::verify - we want to know the verification /// This is for Inkwell's FunctionValue::verify - we want to know the verification
@ -183,19 +182,9 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
} }
pub fn module_from_builtins<'ctx>(ctx: &'ctx Context, module_name: &str) -> Module<'ctx> { pub fn module_from_builtins<'ctx>(ctx: &'ctx Context, module_name: &str) -> Module<'ctx> {
// In the build script for the gen module, we compile the builtins bitcode and set let bitcode_bytes = bitcode::get_bytes();
// BUILTINS_BC to the path to the compiled output.
let path: &'static str = env!(
"BUILTINS_BC",
"Env var BUILTINS_BC not found. Is there a problem with the build script?"
);
let mut builtins_bitcode = File::open(path).expect("Unable to find builtins bitcode source");
let mut buffer = std::vec::Vec::new();
builtins_bitcode
.read_to_end(&mut buffer)
.expect("Unable to read builtins bitcode");
let memory_buffer = MemoryBuffer::create_from_memory_range(&buffer, module_name); let memory_buffer = MemoryBuffer::create_from_memory_range(&bitcode_bytes, module_name);
let module = Module::parse_bitcode_from_buffer(&memory_buffer, ctx) let module = Module::parse_bitcode_from_buffer(&memory_buffer, ctx)
.unwrap_or_else(|err| panic!("Unable to import builtins bitcode. LLVM error: {:?}", err)); .unwrap_or_else(|err| panic!("Unable to import builtins bitcode. LLVM error: {:?}", err));

View file

@ -1,21 +1,28 @@
{ pkgs, isMacOS }: { pkgs, isMacOS }:
if isMacOS # We require at least specific commit of Zig after the latest tagged
then # release (0.6.0), so we just download the binaries for that commit
# As of 2020-10-25, building Zig from source on MacOS fails
# so we just download the binary from their release page
let let
version = "0.6.0"; version = "0.6.0+0088efc4b";
archiveName = "zig-macos-x86_64-${version}+91a1c20e7"; osName =
if isMacOS
then "macos"
else "linux";
archiveName = "zig-${osName}-x86_64-${version}";
sha256 =
if isMacOS
then "665c1a7f472cfc5e0715f0ddf6ff8409fb749ac91cbbae68c443b4a37ebd058e"
else "bab70ae3bd0af538022bc3ef50d8f34fa8dceac39ba7d9e5d528eee7e6d5a1cf";
in in
pkgs.stdenv.mkDerivation { pkgs.stdenv.mkDerivation {
pname = "zig"; pname = "zig";
version = version; version = version;
buildInputs = [ pkgs.gzip ]; buildInputs = [ pkgs.gzip ];
src = pkgs.fetchurl { src = pkgs.fetchurl {
inherit sha256;
name = "${archiveName}.tar.xz"; name = "${archiveName}.tar.xz";
url = "https://ziglang.org/builds/${archiveName}.tar.xz"; url = "https://ziglang.org/builds/${archiveName}.tar.xz";
sha256 = "0svwlk76w171ikr8wjzchm4svd4hvna8idv84pi7ar2fr4i8bkic";
}; };
phases = [ "installPhase" ]; phases = [ "installPhase" ];
installPhase = '' installPhase = ''
@ -27,5 +34,3 @@ if isMacOS
chmod +x $out/bin/zig chmod +x $out/bin/zig
''; '';
} }
else
pkgs.zig

View file

@ -1,8 +1,7 @@
{ pkgs, zig }: { pkgs, zig }:
# As of 2020-10-25, building zls is not available on Nix # As of 2020-10-25, building zls is not available on Nix. For some reason,
# For some reason, this hangs on `zig build`. I'll try # this hangs on `zig build`. I'll try to figure it our later.
# to figure it our later :(
let let
rev = "e8c20351d85da8eb4bf22480045b994007284d69"; rev = "e8c20351d85da8eb4bf22480045b994007284d69";

View file

@ -35,9 +35,9 @@ let
# build libraries # build libraries
pkgs.rustup pkgs.rustup
pkgs.cargo pkgs.cargo
llvm
pkgs.valgrind pkgs.valgrind
zig zig
llvm
# llb deps # llb deps
pkgs.libffi pkgs.libffi
pkgs.libxml2 pkgs.libxml2