improvements towards compiling on MacOS
This commit is contained in:
parent
07c1cd7d53
commit
f0971d4c25
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@ -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
|
||||||
|
@ -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 => {
|
||||||
|
@ -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)) {
|
||||||
|
@ -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});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user