commit
8a55e05e9e
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
@ -2,9 +2,6 @@ name: CI
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 0 * * *"
|
- cron: "0 0 * * *"
|
||||||
concurrency:
|
concurrency:
|
||||||
@ -13,15 +10,15 @@ concurrency:
|
|||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_and_test:
|
self_hosted_linux:
|
||||||
runs-on: [ self-hosted, Linux, x64 ]
|
runs-on: [ self-hosted, Linux, x64 ]
|
||||||
timeout-minutes: 15
|
timeout-minutes: 15
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Set up Zig
|
- name: Set up Zig
|
||||||
uses: goto-bus-stop/setup-zig@v2
|
uses: davidgm94/setup-zig@foo
|
||||||
with:
|
with:
|
||||||
version: master
|
version: master
|
||||||
- name: Test
|
- name: Test
|
||||||
run: ./ci.sh ../todo_foo_debug_path ../../../../../dev/llvm-static-release-zen4-17.0.6/out/x86_64-linux-musl-native
|
run: zig build test -Dllvm_path=../../../../../dev/llvm/llvm-static-release-zen4-17.0.6/out/x86_64-linux-musl-native -Dself_hosted_ci=true
|
||||||
|
63
.github/workflows/ci_main.yml
vendored
Normal file
63
.github/workflows/ci_main.yml
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
name: CI_Github_FlyCI
|
||||||
|
|
||||||
|
on:
|
||||||
|
# pull_request:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
concurrency:
|
||||||
|
# Cancels pending runs when a PR gets updated.
|
||||||
|
group: ${{ github.head_ref || github.run_id }}-${{ github.actor }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
self_hosted_linux:
|
||||||
|
runs-on: [ self-hosted, Linux, x64 ]
|
||||||
|
timeout-minutes: 15
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Set up Zig
|
||||||
|
uses: davidgm94/setup-zig@foo
|
||||||
|
with:
|
||||||
|
version: master
|
||||||
|
- name: Test
|
||||||
|
run: zig build test -Dllvm_path=../../../../../dev/llvm/llvm-static-release-zen4-17.0.6/out/x86_64-linux-musl-native -Dself_hosted_ci=true
|
||||||
|
# linux_x86_64:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# timeout-minutes: 15
|
||||||
|
# steps:
|
||||||
|
# - name: Checkout
|
||||||
|
# uses: actions/checkout@v3
|
||||||
|
# - name: Set up Zig
|
||||||
|
# uses: davidgm94/setup-zig@foo
|
||||||
|
# with:
|
||||||
|
# version: master
|
||||||
|
# - name: Test
|
||||||
|
# run: ./ci.sh -Dthird_party_ci=true -Dtarget=x86_64-linux-musl -Dcpu=x86_64_v3
|
||||||
|
# windows_x86_64:
|
||||||
|
# runs-on: windows-latest
|
||||||
|
# timeout-minutes: 15
|
||||||
|
# steps:
|
||||||
|
# - name: Checkout
|
||||||
|
# uses: actions/checkout@v3
|
||||||
|
# - name: Set up Zig
|
||||||
|
# uses: davidgm94/setup-zig@foo
|
||||||
|
# with:
|
||||||
|
# version: master
|
||||||
|
# - name: Test
|
||||||
|
# run: zig version
|
||||||
|
# macos_m1:
|
||||||
|
# runs-on: flyci-macos-large-latest-m1
|
||||||
|
# timeout-minutes: 15
|
||||||
|
# steps:
|
||||||
|
# - name: Checkout
|
||||||
|
# uses: actions/checkout@v3
|
||||||
|
# - name: Set up Zig
|
||||||
|
# uses: davidgm94/setup-zig@foo
|
||||||
|
# with:
|
||||||
|
# version: master
|
||||||
|
# - name: Test zig
|
||||||
|
# run: zig version
|
||||||
|
# - name: Test macos
|
||||||
|
# run: ./ci.sh -Dthird_party_ci=true -Dtarget=aarch64-macos-none -Dcpu=apple_m1
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
zig-cache
|
zig-cache/
|
||||||
zig-out
|
zig-out/
|
||||||
nat
|
nat/
|
||||||
|
llvm*/
|
||||||
|
@ -38,8 +38,11 @@ fn parseArguments(context: *const Context) !Descriptor {
|
|||||||
|
|
||||||
var maybe_executable_path: ?[]const u8 = null;
|
var maybe_executable_path: ?[]const u8 = null;
|
||||||
var maybe_main_package_path: ?[]const u8 = null;
|
var maybe_main_package_path: ?[]const u8 = null;
|
||||||
var target_triplet: []const u8 = "x86_64-linux-gnu";
|
var target_triplet: []const u8 = switch (@import("builtin").os.tag) {
|
||||||
var should_transpile_to_c: ?bool = null;
|
.linux => "x86_64-linux-gnu",
|
||||||
|
.macos => "aarch64-macos-none",
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
var maybe_only_parse: ?bool = null;
|
var maybe_only_parse: ?bool = null;
|
||||||
var link_libc = false;
|
var link_libc = false;
|
||||||
var maybe_executable_name: ?[]const u8 = null;
|
var maybe_executable_name: ?[]const u8 = null;
|
||||||
@ -113,21 +116,6 @@ fn parseArguments(context: *const Context) !Descriptor {
|
|||||||
} else {
|
} else {
|
||||||
reportUnterminatedArgumentError(current_argument);
|
reportUnterminatedArgumentError(current_argument);
|
||||||
}
|
}
|
||||||
} else if (equal(u8, current_argument, "-transpile_to_c")) {
|
|
||||||
if (i + 1 != arguments.len) {
|
|
||||||
i += 1;
|
|
||||||
|
|
||||||
const arg = arguments[i];
|
|
||||||
if (std.mem.eql(u8, arg, "true")) {
|
|
||||||
should_transpile_to_c = true;
|
|
||||||
} else if (std.mem.eql(u8, arg, "false")) {
|
|
||||||
should_transpile_to_c = false;
|
|
||||||
} else {
|
|
||||||
unreachable;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
reportUnterminatedArgumentError(current_argument);
|
|
||||||
}
|
|
||||||
} else if (equal(u8, current_argument, "-parse")) {
|
} else if (equal(u8, current_argument, "-parse")) {
|
||||||
if (i + 1 != arguments.len) {
|
if (i + 1 != arguments.len) {
|
||||||
i += 1;
|
i += 1;
|
||||||
@ -179,7 +167,6 @@ fn parseArguments(context: *const Context) !Descriptor {
|
|||||||
|
|
||||||
const cross_target = try std.zig.CrossTarget.parse(.{ .arch_os_abi = target_triplet });
|
const cross_target = try std.zig.CrossTarget.parse(.{ .arch_os_abi = target_triplet });
|
||||||
const target = try std.zig.system.resolveTargetQuery(cross_target);
|
const target = try std.zig.system.resolveTargetQuery(cross_target);
|
||||||
const transpile_to_c = should_transpile_to_c orelse false;
|
|
||||||
const only_parse = maybe_only_parse orelse false;
|
const only_parse = maybe_only_parse orelse false;
|
||||||
|
|
||||||
const main_package_path = if (maybe_main_package_path) |path| blk: {
|
const main_package_path = if (maybe_main_package_path) |path| blk: {
|
||||||
@ -213,10 +200,14 @@ fn parseArguments(context: *const Context) !Descriptor {
|
|||||||
.main_package_path = main_package_path,
|
.main_package_path = main_package_path,
|
||||||
.executable_path = executable_path,
|
.executable_path = executable_path,
|
||||||
.target = target,
|
.target = target,
|
||||||
.transpile_to_c = transpile_to_c,
|
|
||||||
.is_build = is_build,
|
.is_build = is_build,
|
||||||
.only_parse = only_parse,
|
.only_parse = only_parse,
|
||||||
.link_libc = link_libc,
|
.link_libc = switch (target.os.tag) {
|
||||||
|
.linux => link_libc,
|
||||||
|
.macos => true,
|
||||||
|
.windows => link_libc,
|
||||||
|
else => unreachable,
|
||||||
|
},
|
||||||
.generate_debug_information = generate_debug_information,
|
.generate_debug_information = generate_debug_information,
|
||||||
.name = executable_name,
|
.name = executable_name,
|
||||||
};
|
};
|
||||||
@ -431,7 +422,10 @@ fn getLoggerScopeType(comptime logger_scope: LoggerScope) type {
|
|||||||
|
|
||||||
var logger_bitset = std.EnumSet(LoggerScope).initEmpty();
|
var logger_bitset = std.EnumSet(LoggerScope).initEmpty();
|
||||||
|
|
||||||
var writer = std.io.getStdOut().writer();
|
fn getWriter() !std.fs.File.Writer{
|
||||||
|
const stdout = std.io.getStdOut();
|
||||||
|
return stdout.writer();
|
||||||
|
}
|
||||||
|
|
||||||
fn shouldLog(comptime logger_scope: LoggerScope, logger: getLoggerScopeType(logger_scope).Logger) bool {
|
fn shouldLog(comptime logger_scope: LoggerScope, logger: getLoggerScopeType(logger_scope).Logger) bool {
|
||||||
return logger_bitset.contains(logger_scope) and getLoggerScopeType(logger_scope).Logger.bitset.contains(logger);
|
return logger_bitset.contains(logger_scope) and getLoggerScopeType(logger_scope).Logger.bitset.contains(logger);
|
||||||
@ -440,21 +434,23 @@ fn shouldLog(comptime logger_scope: LoggerScope, logger: getLoggerScopeType(logg
|
|||||||
pub fn logln(comptime logger_scope: LoggerScope, logger: getLoggerScopeType(logger_scope).Logger, comptime format: []const u8, arguments: anytype) void {
|
pub fn logln(comptime logger_scope: LoggerScope, logger: getLoggerScopeType(logger_scope).Logger, comptime format: []const u8, arguments: anytype) void {
|
||||||
if (shouldLog(logger_scope, logger)) {
|
if (shouldLog(logger_scope, logger)) {
|
||||||
log(logger_scope, logger, format, arguments);
|
log(logger_scope, logger, format, arguments);
|
||||||
|
const writer = try getWriter();
|
||||||
writer.writeByte('\n') catch unreachable;
|
writer.writeByte('\n') catch unreachable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log(comptime logger_scope: LoggerScope, logger: getLoggerScopeType(logger_scope).Logger, comptime format: []const u8, arguments: anytype) void {
|
pub fn log(comptime logger_scope: LoggerScope, logger: getLoggerScopeType(logger_scope).Logger, comptime format: []const u8, arguments: anytype) void {
|
||||||
if (shouldLog(logger_scope, logger)) {
|
if (shouldLog(logger_scope, logger)) {
|
||||||
std.fmt.format(writer, format, arguments) catch unreachable;
|
std.fmt.format(try getWriter(), format, arguments) catch unreachable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, return_address: ?usize) noreturn {
|
pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, return_address: ?usize) noreturn {
|
||||||
const print_stack_trace = false;
|
const print_stack_trace = true;
|
||||||
switch (print_stack_trace) {
|
switch (print_stack_trace) {
|
||||||
true => @call(.always_inline, std.builtin.default_panic, .{ message, stack_trace, return_address }),
|
true => @call(.always_inline, std.builtin.default_panic, .{ message, stack_trace, return_address }),
|
||||||
false => {
|
false => {
|
||||||
|
const writer = try getWriter();
|
||||||
writer.writeAll("\nPANIC: ") catch {};
|
writer.writeAll("\nPANIC: ") catch {};
|
||||||
writer.writeAll(message) catch {};
|
writer.writeAll(message) catch {};
|
||||||
writer.writeByte('\n') catch {};
|
writer.writeByte('\n') catch {};
|
||||||
@ -1290,7 +1286,10 @@ pub const Builder = struct {
|
|||||||
|
|
||||||
if (unit.evaluateBooleanAtComptime(condition)) |comptime_condition| {
|
if (unit.evaluateBooleanAtComptime(condition)) |comptime_condition| {
|
||||||
if (comptime_condition == true) {
|
if (comptime_condition == true) {
|
||||||
unreachable;
|
@panic("TODO: if comptime true");
|
||||||
|
// return If{
|
||||||
|
// .condition = .true,
|
||||||
|
// };
|
||||||
} else {
|
} else {
|
||||||
return If{
|
return If{
|
||||||
.condition = .false,
|
.condition = .false,
|
||||||
@ -3633,7 +3632,6 @@ pub const Descriptor = struct {
|
|||||||
main_package_path: []const u8,
|
main_package_path: []const u8,
|
||||||
executable_path: []const u8,
|
executable_path: []const u8,
|
||||||
target: std.Target,
|
target: std.Target,
|
||||||
transpile_to_c: bool,
|
|
||||||
is_build: bool,
|
is_build: bool,
|
||||||
only_parse: bool,
|
only_parse: bool,
|
||||||
link_libc: bool,
|
link_libc: bool,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "lld/Common/CommonLinkerContext.h"
|
#include "lld/Common/CommonLinkerContext.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
extern "C" LLVMContext* NativityLLVMCreateContext()
|
extern "C" LLVMContext* NativityLLVMCreateContext()
|
||||||
@ -589,16 +590,26 @@ extern "C" Constant* NativityLLVMContextCreateGlobalStringPointer(IRBuilder<>& b
|
|||||||
return constant;
|
return constant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stream_to_string(raw_string_ostream& stream, const char** message_ptr, size_t* message_len)
|
||||||
|
{
|
||||||
|
stream.flush();
|
||||||
|
|
||||||
|
auto string = stream.str();
|
||||||
|
char* result = new char[string.length()];
|
||||||
|
memcpy(result, string.c_str(), string.length());
|
||||||
|
|
||||||
|
*message_ptr = result;
|
||||||
|
*message_len = string.length();
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" bool NativityLLVMVerifyFunction(Function& function, const char** message_ptr, size_t* message_len)
|
extern "C" bool NativityLLVMVerifyFunction(Function& function, const char** message_ptr, size_t* message_len)
|
||||||
{
|
{
|
||||||
std::string message_buffer;
|
std::string message_buffer;
|
||||||
raw_string_ostream message_stream(message_buffer);
|
raw_string_ostream message_stream(message_buffer);
|
||||||
|
|
||||||
bool result = verifyFunction(function, &message_stream);
|
bool result = verifyFunction(function, &message_stream);
|
||||||
message_stream.flush();
|
|
||||||
auto size = message_stream.str().size();
|
auto size = message_stream.str().size();
|
||||||
*message_ptr = strndup(message_stream.str().c_str(), size);
|
stream_to_string(message_stream, message_ptr, message_len);
|
||||||
*message_len = size;
|
|
||||||
|
|
||||||
// We invert the condition because LLVM conventions are just stupid
|
// We invert the condition because LLVM conventions are just stupid
|
||||||
return !result;
|
return !result;
|
||||||
@ -610,10 +621,7 @@ extern "C" bool NativityLLVMVerifyModule(const Module& module, const char** mess
|
|||||||
raw_string_ostream message_stream(message_buffer);
|
raw_string_ostream message_stream(message_buffer);
|
||||||
|
|
||||||
bool result = verifyModule(module, &message_stream);
|
bool result = verifyModule(module, &message_stream);
|
||||||
message_stream.flush();
|
stream_to_string(message_stream, message_ptr, message_len);
|
||||||
auto size = message_stream.str().size();
|
|
||||||
*message_ptr = strndup(message_stream.str().c_str(), size);
|
|
||||||
*message_len = size;
|
|
||||||
|
|
||||||
// We invert the condition because LLVM conventions are just stupid
|
// We invert the condition because LLVM conventions are just stupid
|
||||||
return !result;
|
return !result;
|
||||||
|
136
build.zig
136
build.zig
@ -1,36 +1,104 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
var all: bool = false;
|
const assert = std.debug.assert;
|
||||||
|
|
||||||
pub fn build(b: *std.Build) !void {
|
pub fn build(b: *std.Build) !void {
|
||||||
all = b.option(bool, "all", "All") orelse false;
|
const self_hosted_ci = b.option(bool, "self_hosted_ci", "This option enables the self-hosted CI behavior") orelse false;
|
||||||
|
const third_party_ci = b.option(bool, "third_party_ci", "This option enables the third-party CI behavior") orelse false;
|
||||||
|
const is_ci = self_hosted_ci or third_party_ci;
|
||||||
|
_ = is_ci; // autofix
|
||||||
|
const native_target = b.resolveTargetQuery(.{});
|
||||||
const optimization = b.standardOptimizeOption(.{});
|
const optimization = b.standardOptimizeOption(.{});
|
||||||
const llvm_debug = b.option(bool, "llvm_debug", "Use LLVM in the debug version") orelse false;
|
var target_query = b.standardTargetOptionsQueryOnly(.{});
|
||||||
const llvm_debug_path = b.option([]const u8, "llvm_debug_path", "LLVM debug path") orelse "../llvm-17-static-debug";
|
const os = target_query.os_tag orelse @import("builtin").os.tag;
|
||||||
const llvm_release_path = b.option([]const u8, "llvm_release_path", "LLVM release path") orelse "../llvm-17-static-release";
|
if (os == .linux) {
|
||||||
const target_query = try std.zig.CrossTarget.parse(.{
|
target_query.abi = .musl;
|
||||||
.arch_os_abi = "native-linux-musl",
|
}
|
||||||
});
|
|
||||||
const target = b.resolveTargetQuery(target_query);
|
const target = b.resolveTargetQuery(target_query);
|
||||||
const exe = b.addExecutable(.{
|
const llvm_version = "17.0.6";
|
||||||
|
var fetcher_run: ?*std.Build.Step.Run = null;
|
||||||
|
const llvm_path = b.option([]const u8, "llvm_path", "LLVM prefix path") orelse blk: {
|
||||||
|
assert(!self_hosted_ci);
|
||||||
|
if (third_party_ci or (!target.query.isNativeOs() or !target.query.isNativeCpu())) {
|
||||||
|
const prefix = "nat/cache";
|
||||||
|
var llvm_directory = try std.ArrayListUnmanaged(u8).initCapacity(b.allocator, 128);
|
||||||
|
llvm_directory.appendSliceAssumeCapacity(prefix ++ "/");
|
||||||
|
llvm_directory.appendSliceAssumeCapacity("llvm-");
|
||||||
|
llvm_directory.appendSliceAssumeCapacity(llvm_version);
|
||||||
|
llvm_directory.appendSliceAssumeCapacity("-");
|
||||||
|
llvm_directory.appendSliceAssumeCapacity(@tagName(target.result.cpu.arch));
|
||||||
|
llvm_directory.appendSliceAssumeCapacity("-");
|
||||||
|
llvm_directory.appendSliceAssumeCapacity(@tagName(target.result.os.tag));
|
||||||
|
llvm_directory.appendSliceAssumeCapacity("-");
|
||||||
|
llvm_directory.appendSliceAssumeCapacity(@tagName(target.result.abi));
|
||||||
|
llvm_directory.appendSliceAssumeCapacity("-");
|
||||||
|
llvm_directory.appendSliceAssumeCapacity(if (std.mem.eql(u8, target.result.cpu.model.name, @tagName(target.result.cpu.arch))) "baseline" else target.result.cpu.model.name);
|
||||||
|
|
||||||
|
var dir = std.fs.cwd().openDir(llvm_directory.items, .{}) catch {
|
||||||
|
const llvm_fetcher = b.addExecutable(.{
|
||||||
|
.name = "llvm_fetcher",
|
||||||
|
.root_source_file = .{ .path = "build/llvm_fetcher.zig" },
|
||||||
|
.target = native_target,
|
||||||
|
.optimize = .ReleaseFast,
|
||||||
|
.single_threaded = true,
|
||||||
|
});
|
||||||
|
const run = b.addRunArtifact(llvm_fetcher);
|
||||||
|
fetcher_run = run;
|
||||||
|
run.addArg("-prefix");
|
||||||
|
run.addArg(prefix);
|
||||||
|
run.addArg("-version");
|
||||||
|
run.addArg(llvm_version);
|
||||||
|
run.addArg("-arch");
|
||||||
|
run.addArg(@tagName(target.result.cpu.arch));
|
||||||
|
run.addArg("-os");
|
||||||
|
run.addArg(@tagName(target.result.os.tag));
|
||||||
|
run.addArg("-abi");
|
||||||
|
run.addArg(@tagName(target.result.abi));
|
||||||
|
run.addArg("-cpu");
|
||||||
|
run.addArg(target.result.cpu.model.name);
|
||||||
|
break :blk llvm_directory.items;
|
||||||
|
};
|
||||||
|
|
||||||
|
dir.close();
|
||||||
|
|
||||||
|
break :blk llvm_directory.items;
|
||||||
|
} else {
|
||||||
|
const use_debug = b.option(bool, "use_debug", "This option enables the LLVM debug build in the development PC") orelse false;
|
||||||
|
break :blk switch (use_debug) {
|
||||||
|
true => "../llvm-17-static-debug",
|
||||||
|
false => "../llvm-17-static-release",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const compiler = b.addExecutable(.{
|
||||||
.name = "nat",
|
.name = "nat",
|
||||||
.root_source_file = .{ .path = "bootstrap/main.zig" },
|
.root_source_file = .{ .path = "bootstrap/main.zig" },
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimization,
|
.optimize = optimization,
|
||||||
.use_llvm = true,
|
|
||||||
.use_lld = true,
|
|
||||||
});
|
});
|
||||||
exe.formatted_panics = false;
|
// compiler.formatted_panics = false;
|
||||||
exe.root_module.unwind_tables = false;
|
// compiler.root_module.unwind_tables = false;
|
||||||
exe.root_module.omit_frame_pointer = false;
|
// compiler.root_module.omit_frame_pointer = false;
|
||||||
|
compiler.want_lto = false;
|
||||||
|
|
||||||
const llvm_dir = if (llvm_debug) llvm_debug_path else llvm_release_path;
|
compiler.linkLibC();
|
||||||
const llvm_include_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_dir, "/include" });
|
compiler.linkSystemLibrary("c++");
|
||||||
const llvm_lib_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_dir, "/lib" });
|
|
||||||
|
|
||||||
exe.linkLibCpp();
|
if (target.result.os.tag == .windows) {
|
||||||
|
compiler.linkSystemLibrary("ole32");
|
||||||
|
compiler.linkSystemLibrary("version");
|
||||||
|
compiler.linkSystemLibrary("uuid");
|
||||||
|
compiler.linkSystemLibrary("msvcrt-os");
|
||||||
|
}
|
||||||
|
|
||||||
exe.addIncludePath(std.Build.LazyPath.relative(llvm_include_dir));
|
if (fetcher_run) |fr| {
|
||||||
exe.addCSourceFile(.{
|
compiler.step.dependOn(&fr.step);
|
||||||
|
}
|
||||||
|
|
||||||
|
const llvm_include_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_path, "/include" });
|
||||||
|
const llvm_lib_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_path, "/lib" });
|
||||||
|
compiler.addIncludePath(std.Build.LazyPath.relative(llvm_include_dir));
|
||||||
|
compiler.addCSourceFile(.{
|
||||||
.file = std.Build.LazyPath.relative("bootstrap/backend/llvm.cpp"),
|
.file = std.Build.LazyPath.relative("bootstrap/backend/llvm.cpp"),
|
||||||
.flags = &.{"-g"},
|
.flags = &.{"-g"},
|
||||||
});
|
});
|
||||||
@ -218,9 +286,6 @@ pub fn build(b: *std.Build) !void {
|
|||||||
"libLLVMXCoreDisassembler.a",
|
"libLLVMXCoreDisassembler.a",
|
||||||
"libLLVMXCoreInfo.a",
|
"libLLVMXCoreInfo.a",
|
||||||
"libLLVMXRay.a",
|
"libLLVMXRay.a",
|
||||||
// Zlib
|
|
||||||
"libz.a",
|
|
||||||
"libzstd.a",
|
|
||||||
//LLD
|
//LLD
|
||||||
"liblldCOFF.a",
|
"liblldCOFF.a",
|
||||||
"liblldCommon.a",
|
"liblldCommon.a",
|
||||||
@ -228,14 +293,16 @@ pub fn build(b: *std.Build) !void {
|
|||||||
"liblldMachO.a",
|
"liblldMachO.a",
|
||||||
"liblldMinGW.a",
|
"liblldMinGW.a",
|
||||||
"liblldWasm.a",
|
"liblldWasm.a",
|
||||||
|
// Zlib
|
||||||
|
"libz.a",
|
||||||
|
if (target.result.os.tag == .windows) "zstd.lib" else "libzstd.a",
|
||||||
};
|
};
|
||||||
|
|
||||||
inline for (llvm_libraries) |llvm_library| {
|
for (llvm_libraries) |llvm_library| {
|
||||||
exe.addObjectFile(std.Build.LazyPath.relative(try std.mem.concat(b.allocator, u8, &.{ llvm_lib_dir, "/", llvm_library })));
|
compiler.addObjectFile(std.Build.LazyPath.relative(try std.mem.concat(b.allocator, u8, &.{ llvm_lib_dir, "/", llvm_library })));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const install_exe = b.addInstallArtifact(compiler, .{});
|
||||||
const install_exe = b.addInstallArtifact(exe, .{});
|
|
||||||
b.getInstallStep().dependOn(&install_exe.step);
|
b.getInstallStep().dependOn(&install_exe.step);
|
||||||
b.installDirectory(.{
|
b.installDirectory(.{
|
||||||
.source_dir = std.Build.LazyPath.relative("lib"),
|
.source_dir = std.Build.LazyPath.relative("lib"),
|
||||||
@ -275,13 +342,28 @@ pub fn build(b: *std.Build) !void {
|
|||||||
debug_command.step.dependOn(b.getInstallStep());
|
debug_command.step.dependOn(b.getInstallStep());
|
||||||
debug_command.addArg(compiler_exe_path);
|
debug_command.addArg(compiler_exe_path);
|
||||||
|
|
||||||
|
const test_runner = b.addExecutable(.{
|
||||||
|
.name = "test_runner",
|
||||||
|
.root_source_file = .{ .path = "build/test_runner.zig" },
|
||||||
|
.target = native_target,
|
||||||
|
.optimize = optimization,
|
||||||
|
.single_threaded = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const test_command = b.addRunArtifact(test_runner);
|
||||||
|
test_command.step.dependOn(&compiler.step);
|
||||||
|
test_command.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
if (b.args) |args| {
|
if (b.args) |args| {
|
||||||
run_command.addArgs(args);
|
run_command.addArgs(args);
|
||||||
debug_command.addArgs(args);
|
debug_command.addArgs(args);
|
||||||
|
test_command.addArgs(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
const run_step = b.step("run", "Test the Nativity compiler");
|
const run_step = b.step("run", "Test the Nativity compiler");
|
||||||
run_step.dependOn(&run_command.step);
|
run_step.dependOn(&run_command.step);
|
||||||
const debug_step = b.step("debug", "Debug the Nativity compiler");
|
const debug_step = b.step("debug", "Debug the Nativity compiler");
|
||||||
debug_step.dependOn(&debug_command.step);
|
debug_step.dependOn(&debug_command.step);
|
||||||
|
const test_step = b.step("test", "Test the Nativity compiler");
|
||||||
|
test_step.dependOn(&test_command.step);
|
||||||
}
|
}
|
||||||
|
112
build/llvm_fetcher.zig
Normal file
112
build/llvm_fetcher.zig
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const equal = std.mem.eql;
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
|
const allocator = arena.allocator();
|
||||||
|
const arguments = try std.process.argsAlloc(allocator);
|
||||||
|
var arch_arg: ?std.Target.Cpu.Arch = null;
|
||||||
|
var os_arg: ?std.Target.Os.Tag = null;
|
||||||
|
var abi_arg: ?std.Target.Abi = null;
|
||||||
|
var cpu_arg: [:0]const u8 = "baseline";
|
||||||
|
var version_arg: ?[]const u8 = null;
|
||||||
|
var prefix_arg: [:0]const u8 = "nat";
|
||||||
|
|
||||||
|
const State = enum{
|
||||||
|
none,
|
||||||
|
prefix,
|
||||||
|
version,
|
||||||
|
arch,
|
||||||
|
os,
|
||||||
|
abi,
|
||||||
|
cpu,
|
||||||
|
};
|
||||||
|
|
||||||
|
var state = State.none;
|
||||||
|
|
||||||
|
for (arguments[1..]) |argument| {
|
||||||
|
switch (state) {
|
||||||
|
.none => {
|
||||||
|
if (equal(u8, argument, "-prefix")) {
|
||||||
|
state = .prefix;
|
||||||
|
} else if (equal(u8, argument, "-version")) {
|
||||||
|
state = .version;
|
||||||
|
} else if (equal(u8, argument, "-arch")) {
|
||||||
|
state = .arch;
|
||||||
|
} else if (equal(u8, argument, "-os")) {
|
||||||
|
state = .os;
|
||||||
|
} else if (equal(u8, argument, "-abi")) {
|
||||||
|
state = .abi;
|
||||||
|
} else if (equal(u8, argument, "-cpu")) {
|
||||||
|
state = .cpu;
|
||||||
|
} else return error.InvalidInput;
|
||||||
|
},
|
||||||
|
.prefix => {
|
||||||
|
prefix_arg = argument;
|
||||||
|
state = .none;
|
||||||
|
},
|
||||||
|
.version => {
|
||||||
|
version_arg = argument;
|
||||||
|
state = .none;
|
||||||
|
},
|
||||||
|
.arch => {
|
||||||
|
arch_arg = std.meta.stringToEnum(std.Target.Cpu.Arch, argument) orelse return error.InvalidInput;
|
||||||
|
state = .none;
|
||||||
|
},
|
||||||
|
.os => {
|
||||||
|
os_arg = std.meta.stringToEnum(std.Target.Os.Tag, argument) orelse return error.InvalidInput;
|
||||||
|
state = .none;
|
||||||
|
},
|
||||||
|
.abi => {
|
||||||
|
abi_arg = std.meta.stringToEnum(std.Target.Abi, argument) orelse return error.InvalidInput;
|
||||||
|
state = .none;
|
||||||
|
},
|
||||||
|
.cpu => {
|
||||||
|
cpu_arg = argument;
|
||||||
|
state = .none;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = version_arg orelse return error.InvalidInput;
|
||||||
|
const arch = arch_arg orelse return error.InvalidInput;
|
||||||
|
const os = os_arg orelse return error.InvalidInput;
|
||||||
|
const abi = abi_arg orelse return error.InvalidInput;
|
||||||
|
const cpu = cpu_arg;
|
||||||
|
const prefix = prefix_arg;
|
||||||
|
|
||||||
|
if (state != .none) return error.InvalidInput;
|
||||||
|
|
||||||
|
const url = try std.mem.concat(allocator, u8, &.{"https://github.com/birth-software/fetch-llvm/releases/download/v", version, "/llvm-", version, "-", @tagName(arch), "-", @tagName(os), "-", @tagName(abi), "-", cpu, ".tar.xz"});
|
||||||
|
const uri = try std.Uri.parse(url);
|
||||||
|
var http_client = std.http.Client{
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
defer http_client.deinit();
|
||||||
|
|
||||||
|
var headers = std.http.Headers{
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
defer headers.deinit();
|
||||||
|
|
||||||
|
var request = try http_client.open(.GET, uri, headers, .{});
|
||||||
|
defer request.deinit();
|
||||||
|
try request.send(.{});
|
||||||
|
try request.wait();
|
||||||
|
|
||||||
|
if (request.response.status != .ok) {
|
||||||
|
std.debug.panic("Status: {s} when fetching TAR {s}", .{@tagName(request.response.status), url});
|
||||||
|
}
|
||||||
|
|
||||||
|
var decompression = try std.compress.xz.decompress(allocator, request.reader());
|
||||||
|
defer decompression.deinit();
|
||||||
|
|
||||||
|
var decompressed_buffer = std.ArrayList(u8).init(allocator);
|
||||||
|
try decompression.reader().readAllArrayList(&decompressed_buffer, std.math.maxInt(u32));
|
||||||
|
|
||||||
|
var memory_stream = std.io.fixedBufferStream(decompressed_buffer.items);
|
||||||
|
const directory = try std.fs.cwd().makeOpenPath(prefix, .{});
|
||||||
|
try std.tar.pipeToFileSystem(directory, memory_stream.reader(), .{
|
||||||
|
.mode_mode = .ignore,
|
||||||
|
});
|
||||||
|
}
|
60
build/test_runner.zig
Normal file
60
build/test_runner.zig
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const TestError = error{
|
||||||
|
junk_in_test_directory,
|
||||||
|
abnormal_exit_code,
|
||||||
|
signaled,
|
||||||
|
stopped,
|
||||||
|
unknown,
|
||||||
|
fail,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
|
const allocator = arena.allocator();
|
||||||
|
const standalone_test_dir_path = "test/standalone";
|
||||||
|
var standalone_test_dir = try std.fs.cwd().openDir(standalone_test_dir_path, .{
|
||||||
|
.iterate = true,
|
||||||
|
});
|
||||||
|
var standalone_iterator = standalone_test_dir.iterate();
|
||||||
|
var standalone_test_names = std.ArrayListUnmanaged([]const u8){};
|
||||||
|
|
||||||
|
while (try standalone_iterator.next()) |entry| {
|
||||||
|
switch (entry.kind) {
|
||||||
|
.directory => try standalone_test_names.append(allocator, entry.name),
|
||||||
|
else => return error.junk_in_test_directory,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
standalone_test_dir.close();
|
||||||
|
|
||||||
|
var ran_test_count: usize = 0;
|
||||||
|
var failed_test_count: usize = 0;
|
||||||
|
|
||||||
|
for (standalone_test_names.items) |standalone_test_name| {
|
||||||
|
defer ran_test_count += 1;
|
||||||
|
std.debug.print("{s}... ", .{standalone_test_name});
|
||||||
|
const source_file_path = try std.mem.concat(allocator, u8, &.{standalone_test_dir_path, "/", standalone_test_name, "/main.nat"});
|
||||||
|
const process_run = try std.ChildProcess.run(.{
|
||||||
|
.allocator = allocator,
|
||||||
|
.argv = &.{"zig-out/bin/nat", "-main_source_file", source_file_path},
|
||||||
|
});
|
||||||
|
const result: TestError!bool = switch (process_run.term) {
|
||||||
|
.Exited => |exit_code| if (exit_code == 0) true else error.abnormal_exit_code,
|
||||||
|
.Signal => error.signaled,
|
||||||
|
.Stopped => error.stopped,
|
||||||
|
.Unknown => error.unknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
const success = result catch b: {
|
||||||
|
failed_test_count += 1;
|
||||||
|
break :b false;
|
||||||
|
};
|
||||||
|
std.debug.print("[{s}]\n", .{if (success) "OK" else "FAIL"});
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.print("\nTest count: {}. Failed test count: {}\n", .{ran_test_count, failed_test_count});
|
||||||
|
if (failed_test_count > 0) {
|
||||||
|
return error.fail;
|
||||||
|
}
|
||||||
|
}
|
139
ci.sh
139
ci.sh
@ -1,139 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
argument_count=$#;
|
|
||||||
extra_args=""
|
|
||||||
use_debug="true"
|
|
||||||
if [ $argument_count -ne 0 ]; then
|
|
||||||
llvm_debug_path=$1
|
|
||||||
llvm_release_path=$2
|
|
||||||
use_debug="false"
|
|
||||||
extra_args="-Dllvm_debug_path=$llvm_debug_path -Dllvm_release_path=$llvm_release_path"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\e[90mCompiling Nativity with Zig...\e[0m"
|
|
||||||
zig build -Dllvm_debug=$use_debug $extra_args
|
|
||||||
if [[ "$?" != 0 ]]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
failed_test_count=0
|
|
||||||
passed_test_count=0
|
|
||||||
test_directory_name=test
|
|
||||||
standalone_test_directory=$test_directory_name/standalone
|
|
||||||
standalone_test_directory_files=$standalone_test_directory/*
|
|
||||||
integral_test_directory=$test_directory_name/integral
|
|
||||||
integral_test_directory_files=$integral_test_directory/*
|
|
||||||
standalone_test_count=$(ls 2>/dev/null -Ubad1 -- $standalone_test_directory/* | wc -l)
|
|
||||||
integral_test_count=$(ls 2>/dev/null -Ubad1 -- $integral_test_directory/* | wc -l)
|
|
||||||
total_test_count=$(($standalone_test_count + $integral_test_count))
|
|
||||||
|
|
||||||
ran_test_count=0
|
|
||||||
test_i=1
|
|
||||||
passed_compilation_count=0
|
|
||||||
failed_compilation_count=0
|
|
||||||
failed_compilations=()
|
|
||||||
failed_tests=()
|
|
||||||
my_current_directory=$(pwd)
|
|
||||||
nat_compiler=$my_current_directory/zig-out/bin/nat
|
|
||||||
|
|
||||||
for standalone_test_case in $standalone_test_directory_files
|
|
||||||
do
|
|
||||||
STANDALONE_TEST_NAME=${standalone_test_case##*/}
|
|
||||||
$nat_compiler -main_source_file $standalone_test_case/main.nat
|
|
||||||
|
|
||||||
if [[ "$?" == "0" ]]; then
|
|
||||||
passed_compilation_count=$(($passed_compilation_count + 1))
|
|
||||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
||||||
nat/$STANDALONE_TEST_NAME
|
|
||||||
|
|
||||||
if [[ "$?" == "0" ]]; then
|
|
||||||
passed_test_count=$(($passed_test_count + 1))
|
|
||||||
result="\e[32mPASSED\e[0m"
|
|
||||||
else
|
|
||||||
failed_test_count=$(($failed_test_count + 1))
|
|
||||||
result="\e[31mFAILED\e[0m"
|
|
||||||
failed_tests+=("$test_i. $STANDALONE_TEST_NAME")
|
|
||||||
fi
|
|
||||||
|
|
||||||
ran_test_count=$(($ran_test_count + 1))
|
|
||||||
else
|
|
||||||
result="\e[31mOS NOT SUPPORTED\e[0m"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
failed_compilation_count=$(($failed_compilation_count + 1))
|
|
||||||
result="\e[31mCOMPILATION FAILURE\e[0m"
|
|
||||||
failed_compilations+=("$test_i. $STANDALONE_TEST_NAME")
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "[$test_i/$total_test_count] [$result] [STANDALONE] $STANDALONE_TEST_NAME"
|
|
||||||
|
|
||||||
test_i=$(($test_i + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
# for integral_test_case in $integral_test_directory_files
|
|
||||||
# do
|
|
||||||
# MY_TESTNAME=${integral_test_case##*/}
|
|
||||||
# cd test/integral/$MY_TESTNAME
|
|
||||||
# $nat_compiler
|
|
||||||
#
|
|
||||||
# if [[ "$?" == "0" ]]; then
|
|
||||||
# passed_compilation_count=$(($passed_compilation_count + 1))
|
|
||||||
# if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
|
||||||
# nat/$MY_TESTNAME
|
|
||||||
#
|
|
||||||
# if [[ "$?" == "0" ]]; then
|
|
||||||
# passed_test_count=$(($passed_test_count + 1))
|
|
||||||
# result="\e[32mPASSED\e[0m"
|
|
||||||
# else
|
|
||||||
# failed_test_count=$(($failed_test_count + 1))
|
|
||||||
# result="\e[31mFAILED\e[0m"
|
|
||||||
# failed_tests+=("$test_i. $MY_TESTNAME")
|
|
||||||
# fi
|
|
||||||
#
|
|
||||||
# ran_test_count=$(($ran_test_count + 1))
|
|
||||||
# else
|
|
||||||
# result="\e[31mOS NOT SUPPORTED\e[0m"
|
|
||||||
# fi
|
|
||||||
# else
|
|
||||||
# failed_compilation_count=$(($failed_compilation_count + 1))
|
|
||||||
# result="\e[31mCOMPILATION FAILURE\e[0m"
|
|
||||||
# failed_compilations+=("$test_i. $MY_TESTNAME")
|
|
||||||
# fi
|
|
||||||
#
|
|
||||||
# echo -e "[$test_i/$total_test_count] [$result] [INTEGRAL] $MY_TESTNAME"
|
|
||||||
#
|
|
||||||
# test_i=$(($test_i + 1))
|
|
||||||
# cd $my_current_directory
|
|
||||||
# done
|
|
||||||
|
|
||||||
printf "\n"
|
|
||||||
echo -e "\e[35m[SUMMARY]\e[0m"
|
|
||||||
echo -e "\e[35m=========\e[0m"
|
|
||||||
echo -e "Ran $total_test_count compilations (\e[32m$passed_compilation_count\e[0m succeeded, \e[31m$failed_compilation_count\e[0m failed)."
|
|
||||||
echo -e "Ran $ran_test_count tests (\e[32m $passed_test_count\e[0m passed, \e[31m$failed_test_count\e[0m failed)."
|
|
||||||
|
|
||||||
if [[ "$failed_compilation_count" != "0" ]]; then
|
|
||||||
printf $"\nFailed compilations:\n"
|
|
||||||
for failed_compilation in "${failed_compilations[@]}"
|
|
||||||
do
|
|
||||||
echo -e "\e[31m$failed_compilation\e[0m"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
if [[ "$failed_test_count" != "0" ]]; then
|
|
||||||
echo $'\n'
|
|
||||||
echo "Failed tests:"
|
|
||||||
for failed_test in "${failed_tests[@]}"
|
|
||||||
do
|
|
||||||
echo -e "\e[31m$failed_test\e[0m"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "\e[35m=========\e[0m"
|
|
||||||
|
|
||||||
if [[ "$failed_test_count" == "0" && "$failed_compilation_count" == "0" ]]; then
|
|
||||||
echo -e "\e[32mSUCCESS!\e[0m"
|
|
||||||
true
|
|
||||||
else
|
|
||||||
echo -e "\e[31mFAILURE!\e[0m"
|
|
||||||
false
|
|
||||||
fi
|
|
Loading…
x
Reference in New Issue
Block a user