improvements towards compiling on MacOS

This commit is contained in:
David Gonzalez Martin 2024-02-01 13:42:48 +01:00
parent 07c1cd7d53
commit f0971d4c25
6 changed files with 121 additions and 35 deletions

View File

@ -22,3 +22,17 @@ jobs:
version: master version: master
- name: Test - 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 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
# macos_m1:
# runs-on: macos-14
# 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: zig build test -Dthird_party_ci=true -Dtarget=aarch64-macos-none -Dcpu=apple_m1

View File

@ -319,7 +319,7 @@ pub fn log(comptime logger_scope: LoggerScope, logger: getLoggerScopeType(logger
} }
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 = @import("configuration").print_stack_trace;
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 => {

View File

@ -774,6 +774,10 @@ namespace lld {
bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput); llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput);
} }
namespace macho {
bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput);
}
} }
extern "C" bool NativityLLVMGenerateMachineCode(Module& module, const char* object_file_path_ptr, size_t object_file_path_len, const char* file_path_ptr, size_t file_path_len) extern "C" bool NativityLLVMGenerateMachineCode(Module& module, const char* object_file_path_ptr, size_t object_file_path_len, const char* file_path_ptr, size_t file_path_len)
@ -798,11 +802,6 @@ extern "C" bool NativityLLVMGenerateMachineCode(Module& module, const char* obje
module.setDataLayout(target_machine->createDataLayout()); module.setDataLayout(target_machine->createDataLayout());
module.setTargetTriple(target_triple); module.setTargetTriple(target_triple);
#if 0
SmallVector<char> bytes;
raw_svector_ostream message_stream(bytes);
auto stream = buffer_ostream(message_stream);
#else
std::error_code EC; std::error_code EC;
auto object_file_path = StringRef(object_file_path_ptr, object_file_path_len); auto object_file_path = StringRef(object_file_path_ptr, object_file_path_len);
raw_fd_ostream stream(object_file_path, EC, sys::fs::OF_None); raw_fd_ostream stream(object_file_path, EC, sys::fs::OF_None);
@ -810,7 +809,6 @@ extern "C" bool NativityLLVMGenerateMachineCode(Module& module, const char* obje
return false; return false;
} }
#endif
legacy::PassManager pass; legacy::PassManager pass;
bool result = target_machine->addPassesToEmitFile(pass, stream, nullptr, llvm::CGFT_ObjectFile, false); bool result = target_machine->addPassesToEmitFile(pass, stream, nullptr, llvm::CGFT_ObjectFile, false);
if (result) { if (result) {
@ -821,17 +819,43 @@ extern "C" bool NativityLLVMGenerateMachineCode(Module& module, const char* obje
pass.run(module); pass.run(module);
stream.flush(); stream.flush();
std::vector<const char*> args;
args.push_back("ld.lld");
args.push_back(object_file_path_ptr);
args.push_back("-o");
args.push_back(file_path_ptr);
lld::elf::link(args, llvm::outs(), llvm::errs(), true, false);
return true; return true;
} }
enum class Format {
elf = 0,
macho = 1,
coff = 2,
};
extern "C" bool NativityLLDLink(Format format, const char** argument_ptr, size_t argument_count, const char** stdout_ptr, size_t* stdout_len, const char** stderr_ptr, size_t* stderr_len)
{
auto arguments = ArrayRef<const char*>(argument_ptr, argument_count);
std::string stdout_string;
raw_string_ostream stdout_stream(stdout_string);
std::string stderr_string;
raw_string_ostream stderr_stream(stderr_string);
bool success = false;
switch (format) {
case Format::elf:
success = lld::elf::link(arguments, stdout_stream, stderr_stream, true, false);
break;
case Format::coff:
success = lld::coff::link(arguments, stdout_stream, stderr_stream, true, false);
case Format::macho:
success = lld::macho::link(arguments, stdout_stream, stderr_stream, true, false);
default:
break;
}
stream_to_string(stdout_stream, stdout_ptr, stdout_len);
stream_to_string(stderr_stream, stderr_ptr, stderr_len);
return success;
}
extern "C" bool NativityLLVMCompareTypes(Type* a, Type* b) extern "C" bool NativityLLVMCompareTypes(Type* a, Type* b)
{ {
if (auto* int_a = dyn_cast<IntegerType>(a)) { if (auto* int_a = dyn_cast<IntegerType>(a)) {

View File

@ -90,6 +90,7 @@ pub const LLVM = struct {
const toString = bindings.NativityLLVMModuleToString; const toString = bindings.NativityLLVMModuleToString;
const getIntrinsicDeclaration = bindings.NativityLLVMModuleGetIntrinsicDeclaration; const getIntrinsicDeclaration = bindings.NativityLLVMModuleGetIntrinsicDeclaration;
const createDebugInfoBuilder = bindings.NativityLLVMModuleCreateDebugInfoBuilder; const createDebugInfoBuilder = bindings.NativityLLVMModuleCreateDebugInfoBuilder;
const generateMachineCode = bindings.NativityLLVMGenerateMachineCode;
}; };
pub const Builder = opaque { pub const Builder = opaque {
@ -2925,6 +2926,12 @@ const Error = error{
const address_space = 0; const address_space = 0;
pub const Format = enum(c_uint) {
elf = 0,
macho = 1,
coff = 2,
};
pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !void { pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !void {
const llvm_context = LLVM.Context.create() orelse return Error.context; const llvm_context = LLVM.Context.create() orelse return Error.context;
const module = LLVM.Module.create(@ptrCast(unit.descriptor.name.ptr), unit.descriptor.name.len, llvm_context) orelse return Error.module; const module = LLVM.Module.create(@ptrCast(unit.descriptor.name.ptr), unit.descriptor.name.len, llvm_context) orelse return Error.module;
@ -3286,13 +3293,6 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const value = if (llvm.llvm_value_map.get(load.value)) |v| v else blk: { const value = if (llvm.llvm_value_map.get(load.value)) |v| v else blk: {
const value = switch (load.value.value) { const value = switch (load.value.value) {
.runtime => |instr_index| llvm.llvm_instruction_map.get(instr_index).?, .runtime => |instr_index| llvm.llvm_instruction_map.get(instr_index).?,
// const instruction = unit.instructions.get(instr_index);
// break :b switch (instruction.*) {
// .argument_declaration => llvm.argument_allocas.get(instr_index).?,
// .stack_slot => unreachable,
// else => |t| @panic(@tagName(t)),
// };
// },
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
}; };
try llvm.llvm_value_map.putNoClobber(context.allocator, load.value, value); try llvm.llvm_value_map.putNoClobber(context.allocator, load.value, value);
@ -3401,13 +3401,6 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
.@"unreachable" => { .@"unreachable" => {
_ = llvm.builder.createUnreachable() orelse return LLVM.Value.Instruction.Error.@"unreachable"; _ = llvm.builder.createUnreachable() orelse return LLVM.Value.Instruction.Error.@"unreachable";
}, },
// .fetch_global => |global_declaration| {
// const global_variable = llvm.global_variable_map.get(global_declaration).?;
// const global_type = try llvm.getType(unit, context, global_declaration.declaration.type);
// const is_volatile = false;
// const load = llvm.builder.createLoad(global_type, global_variable.toValue(), is_volatile, "global", "global".len) orelse return LLVM.Value.Instruction.Error.load;
// try llvm.llvm_instruction_map.putNoClobber(context.allocator, instruction_index, load.toValue());
// },
else => |t| @panic(@tagName(t)), else => |t| @panic(@tagName(t)),
} }
} }
@ -3461,8 +3454,57 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const file_path = unit.descriptor.executable_path; const file_path = unit.descriptor.executable_path;
const object_file_path = try std.mem.joinZ(context.allocator, "", &.{ file_path, ".o" }); const object_file_path = try std.mem.joinZ(context.allocator, "", &.{ file_path, ".o" });
const destination_file_path = try std.mem.joinZ(context.allocator, "", &.{file_path}); const destination_file_path = try std.mem.joinZ(context.allocator, "", &.{file_path});
const r = bindings.NativityLLVMGenerateMachineCode(llvm.module, object_file_path.ptr, object_file_path.len, destination_file_path.ptr, destination_file_path.len); const r = llvm.module.generateMachineCode(object_file_path.ptr, object_file_path.len, destination_file_path.ptr, destination_file_path.len);
if (!r) { if (!r) {
@panic("Compilation failed!"); @panic("Compilation failed!");
} }
const format: Format = switch (unit.descriptor.target.os.tag) {
.windows => .coff,
.macos => .macho,
.linux => .elf,
else => unreachable,
};
const driver_program = switch (format) {
.coff => "lld-link",
.elf => "ld.lld",
.macho => "ld64.lld",
};
var arguments = ArrayList([*:0]const u8){};
try arguments.append(context.allocator, driver_program);
try arguments.append(context.allocator, object_file_path.ptr);
try arguments.append(context.allocator, "-o");
try arguments.append(context.allocator, destination_file_path.ptr);
if (format == .macho) {
try arguments.append(context.allocator, "-platform_version");
try arguments.append(context.allocator, "macos");
try arguments.append(context.allocator, "11");
try arguments.append(context.allocator, "14");
try arguments.append(context.allocator, "-arch");
try arguments.append(context.allocator, "arm64");
try arguments.append(context.allocator, "-lSystem");
}
var stdout_ptr: [*]const u8 = undefined;
var stdout_len: usize = 0;
var stderr_ptr: [*]const u8 = undefined;
var stderr_len: usize = 0;
const linking_result = bindings.NativityLLDLink(format, arguments.items.ptr, arguments.items.len, &stdout_ptr, &stdout_len, &stderr_ptr, &stderr_len);
if (stdout_len > 0) {
std.debug.print("{s}\n", .{stdout_ptr[0..stdout_len]});
}
if (stderr_len > 0) {
std.debug.print("{s}\n", .{stderr_ptr[0..stderr_len]});
}
if (!linking_result) {
std.debug.panic("Linker invokation failed: {s}", .{arguments.items});
}
} }

View File

@ -83,7 +83,7 @@ pub extern fn NativityLLVMVerifyModule(module: *LLVM.Module, message_ptr: *[*]co
pub extern fn NativityLLVMModuleToString(module: *LLVM.Module, message_len: *usize) [*]const u8; pub extern fn NativityLLVMModuleToString(module: *LLVM.Module, message_len: *usize) [*]const u8;
pub extern fn NativityLLVMFunctionToString(function: *LLVM.Value.Function, message_len: *usize) [*]const u8; pub extern fn NativityLLVMFunctionToString(function: *LLVM.Value.Function, message_len: *usize) [*]const u8;
pub extern fn NativityLLVMGenerateMachineCode(module: *LLVM.Module, object_file_path_ptr: [*]const u8, object_file_path_len: usize, file_path_ptr: [*]const u8, file_path_len: usize) bool;
pub extern fn NativityLLVMBuilderIsCurrentBlockTerminated(builder: *LLVM.Builder) bool; pub extern fn NativityLLVMBuilderIsCurrentBlockTerminated(builder: *LLVM.Builder) bool;
pub extern fn NativityLLVMGetUndefined(type: *LLVM.Type) ?*LLVM.Value.Constant.Undefined; pub extern fn NativityLLVMGetUndefined(type: *LLVM.Type) ?*LLVM.Value.Constant.Undefined;
pub extern fn NativityLLVMFunctionSetCallingConvention(function: *LLVM.Value.Function, calling_convention: LLVM.Value.Function.CallingConvention) void; pub extern fn NativityLLVMFunctionSetCallingConvention(function: *LLVM.Value.Function, calling_convention: LLVM.Value.Function.CallingConvention) void;
@ -117,3 +117,6 @@ pub extern fn NativityLLVMCreatePhiNode(type: *LLVM.Type, reserved_value_count:
pub extern fn NativityLLVMAllocatGetAllocatedType(alloca: *LLVM.Value.Instruction.Alloca) *LLVM.Type; pub extern fn NativityLLVMAllocatGetAllocatedType(alloca: *LLVM.Value.Instruction.Alloca) *LLVM.Type;
pub extern fn NativityLLVMValueToAlloca(value: *LLVM.Value) ?*LLVM.Value.Instruction.Alloca; pub extern fn NativityLLVMValueToAlloca(value: *LLVM.Value) ?*LLVM.Value.Instruction.Alloca;
pub extern fn NativityLLVMGlobalVariableSetInitializer(global_variable: *LLVM.Value.Constant.GlobalVariable, constant_initializer: *LLVM.Value.Constant) void; pub extern fn NativityLLVMGlobalVariableSetInitializer(global_variable: *LLVM.Value.Constant.GlobalVariable, constant_initializer: *LLVM.Value.Constant) void;
pub extern fn NativityLLVMGenerateMachineCode(module: *LLVM.Module, object_file_path_ptr: [*]const u8, object_file_path_len: usize, file_path_ptr: [*]const u8, file_path_len: usize) bool;
pub extern fn NativityLLDLink(format: llvm.Format, argument_ptr: [*]const [*:0]const u8, argument_count: usize, stdout_ptr: *[*]const u8, stdout_len: *usize, stderr_ptr: *[*]const u8, stderr_len: *usize) bool;

View File

@ -68,6 +68,8 @@ pub fn build(b: *std.Build) !void {
}; };
} }
}; };
const compiler_options = b.addOptions();
compiler_options.addOption(bool, "print_stack_trace", is_ci);
const compiler = b.addExecutable(.{ const compiler = b.addExecutable(.{
.name = "nat", .name = "nat",
@ -75,6 +77,7 @@ pub fn build(b: *std.Build) !void {
.target = target, .target = target,
.optimize = optimization, .optimize = optimization,
}); });
compiler.root_module.addOptions("configuration", compiler_options);
compiler.formatted_panics = is_ci; compiler.formatted_panics = is_ci;
compiler.root_module.unwind_tables = is_ci; compiler.root_module.unwind_tables = is_ci;
compiler.root_module.omit_frame_pointer = false; compiler.root_module.omit_frame_pointer = false;