Compile and link with musl libc

This commit is contained in:
David Gonzalez Martin 2024-03-01 22:19:12 -06:00
parent cd2ee23a71
commit 0c603f1ca3
8 changed files with 3659 additions and 114 deletions

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ const data_structures = @import("../library.zig");
const MyHashMap = data_structures.MyHashMap; const MyHashMap = data_structures.MyHashMap;
const UnpinnedArray = data_structures.UnpinnedArray; const UnpinnedArray = data_structures.UnpinnedArray;
const bindings = @import("llvm_bindings.zig"); pub const bindings = @import("llvm_bindings.zig");
pub const Logger = enum { pub const Logger = enum {
print_module, print_module,
@ -3245,7 +3245,6 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const target_triple = switch (unit.descriptor.os) { const target_triple = switch (unit.descriptor.os) {
.linux => "x86_64-linux-none", .linux => "x86_64-linux-none",
.macos => "aarch64-apple-macosx-none", .macos => "aarch64-apple-macosx-none",
else => |t| @panic(@tagName(t)),
}; };
const cpu = "generic"; const cpu = "generic";
const features = ""; const features = "";
@ -3286,10 +3285,10 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
} }
const format: Format = switch (unit.descriptor.os) { const format: Format = switch (unit.descriptor.os) {
.windows => .coff, // .windows => .coff,
.macos => .macho, .macos => .macho,
.linux => .elf, .linux => .elf,
else => unreachable, // else => unreachable,
}; };
const driver_program = switch (format) { const driver_program = switch (format) {
@ -3347,8 +3346,8 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
// try arguments.append_slice(context.allocator, &.{ "-lc" }); // try arguments.append_slice(context.allocator, &.{ "-lc" });
// } // }
}, },
.windows => {}, // .windows => {},
else => |t| @panic(@tagName(t)), // else => |t| @panic(@tagName(t)),
} }
var stdout_ptr: [*]const u8 = undefined; var stdout_ptr: [*]const u8 = undefined;
@ -3356,7 +3355,11 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
var stderr_ptr: [*]const u8 = undefined; var stderr_ptr: [*]const u8 = undefined;
var stderr_len: usize = 0; var stderr_len: usize = 0;
const linking_result = bindings.NativityLLDLink(format, arguments.pointer, arguments.length, &stdout_ptr, &stdout_len, &stderr_ptr, &stderr_len); const linking_result = switch (format) {
.elf => bindings.NativityLLDLinkELF(arguments.pointer, arguments.length, &stdout_ptr, &stdout_len, &stderr_ptr, &stderr_len),
.coff => bindings.NativityLLDLinkCOFF(arguments.pointer, arguments.length, &stdout_ptr, &stdout_len, &stderr_ptr, &stderr_len),
.macho => bindings.NativityLLDLinkMachO(arguments.pointer, arguments.length, &stdout_ptr, &stdout_len, &stderr_ptr, &stderr_len),
};
if (stdout_len > 0) { if (stdout_len > 0) {
// std.debug.print("{s}\n", .{stdout_ptr[0..stdout_len]}); // std.debug.print("{s}\n", .{stdout_ptr[0..stdout_len]});

View File

@ -141,4 +141,7 @@ pub extern fn NativityLLVMTargetCreateTargetMachine(target: *LLVM.Target, target
pub extern fn NativityLLVMModuleSetTargetMachineDataLayout(module: *LLVM.Module, target_machine: *LLVM.Target.Machine) void; pub extern fn NativityLLVMModuleSetTargetMachineDataLayout(module: *LLVM.Module, target_machine: *LLVM.Target.Machine) void;
pub extern fn NativityLLVMModuleSetTargetTriple(module: *LLVM.Module, target_triple_ptr: [*]const u8, target_triple_len: usize) void; pub extern fn NativityLLVMModuleSetTargetTriple(module: *LLVM.Module, target_triple_ptr: [*]const u8, target_triple_len: usize) void;
pub extern fn NativityLLVMModuleAddPassesToEmitFile(module: *LLVM.Module, target_machine: *LLVM.Target.Machine, object_file_path_ptr: [*]const u8, object_file_path_len: usize, codegen_file_type: LLVM.CodeGenFileType, disable_verify: bool) bool; pub extern fn NativityLLVMModuleAddPassesToEmitFile(module: *LLVM.Module, target_machine: *LLVM.Target.Machine, object_file_path_ptr: [*]const u8, object_file_path_len: usize, codegen_file_type: LLVM.CodeGenFileType, disable_verify: bool) 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; pub extern fn NativityLLDLinkELF(argument_ptr: [*]const [*:0]const u8, argument_count: usize, stdout_ptr: *[*]const u8, stdout_len: *usize, stderr_ptr: *[*]const u8, stderr_len: *usize) bool;
pub extern fn NativityLLDLinkCOFF(argument_ptr: [*]const [*:0]const u8, argument_count: usize, stdout_ptr: *[*]const u8, stdout_len: *usize, stderr_ptr: *[*]const u8, stderr_len: *usize) bool;
pub extern fn NativityLLDLinkMachO(argument_ptr: [*]const [*:0]const u8, argument_count: usize, stdout_ptr: *[*]const u8, stdout_len: *usize, stderr_ptr: *[*]const u8, stderr_len: *usize) bool;
pub extern fn NativityLLDLinkWasm(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

@ -204,6 +204,12 @@ pub fn byte_equal(a: []const u8, b: []const u8) bool {
return true; return true;
} }
pub fn byte_equal_terminated(a: [*:0]const u8, b: [*:0]const u8) bool {
const a_slice = span(a);
const b_slice = span(b);
return byte_equal(a_slice, b_slice);
}
const MapResult = struct{ const MapResult = struct{
key_pointer: *anyopaque, key_pointer: *anyopaque,
value_pointer: *anyopaque, value_pointer: *anyopaque,

View File

@ -30,7 +30,9 @@ pub export fn main(c_argc: c_int, c_argv: [*][*:0]c_char, c_envp: [*:null]?[*:0]
return 0; return 0;
} else |err| { } else |err| {
const error_name: []const u8 = @errorName(err); const error_name: []const u8 = @errorName(err);
_ = error_name; // autofix std.io.getStdOut().writeAll("Error: ") catch {};
std.io.getStdOut().writeAll(error_name) catch {};
std.io.getStdOut().writeAll("\n") catch {};
return 1; return 1;
} }
} }
@ -59,7 +61,7 @@ pub fn entry_point(arguments: [][*:0]u8) !void {
// std.process.exit(exit_code); // std.process.exit(exit_code);
} else if (byte_equal(command, "cc")) { } else if (byte_equal(command, "cc")) {
// TODO: transform our arguments to Clang and invoke it // TODO: transform our arguments to Clang and invoke it
todo(); try Compilation.compileCSourceFile(context, command_arguments);
} else if (byte_equal(command, "c++")) { } else if (byte_equal(command, "c++")) {
// TODO: transform our arguments to Clang and invoke it // TODO: transform our arguments to Clang and invoke it
todo(); todo();
@ -80,17 +82,3 @@ pub fn entry_point(arguments: [][*:0]u8) !void {
} }
} }
fn argsCopyZ(alloc: Allocator, args: []const []const u8) ![:null]?[*:0]u8 {
var argv = try alloc.allocSentinel(?[*:0]u8, args.len, null);
for (args, 0..) |arg, i| {
argv[i] = try alloc.dupeZ(u8, arg); // TODO If there was an argsAllocZ we could avoid this allocation.
}
return argv;
}
extern "c" fn NativityClangMain(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
fn clangMain(allocator: Allocator, arguments: []const []const u8) !u8 {
const argv = try argsCopyZ(allocator, arguments);
const exit_code = NativityClangMain(@as(c_int, @intCast(arguments.len)), argv.ptr);
return @as(u8, @bitCast(@as(i8, @truncate(exit_code))));
}

125
build.zig
View File

@ -91,38 +91,33 @@ pub fn build(b: *std.Build) !void {
} }
}; };
if (os == .linux) {
const directory = "musl-libc-main";
var maybe_dir = std.fs.cwd().openDir(prefix ++ "/" ++ directory, .{});
_ = &maybe_dir;
if (maybe_dir) |*dir| {
dir.close();
} else |err| {
_ = &err; // autofix
const url = "https://github.com/birth-software/musl-libc/archive/refs/heads/main.tar.gz";
const run = b.addRunArtifact(fetcher);
compiler.step.dependOn(&run.step);
run.addArg("-prefix");
run.addArg(prefix);
run.addArg("-url");
run.addArg(url);
}
}
const llvm_include_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_path, "/include" }); 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" }); const llvm_lib_dir = try std.mem.concat(b.allocator, u8, &.{ llvm_path, "/lib" });
compiler.addIncludePath(std.Build.LazyPath.relative(llvm_include_dir)); compiler.addIncludePath(std.Build.LazyPath.relative(llvm_include_dir));
const cpp_files = .{ const cpp_files = .{
"src/llvm/llvm.cpp", "src/llvm/llvm.cpp",
"src/llvm/lld.cpp", "src/llvm/lld.cpp",
// "src/llvm/clang_main.cpp", "src/llvm/clang_main.cpp",
// "src/llvm/clang_cc1.cpp", "src/llvm/clang_cc1.cpp",
// "src/llvm/clang_cc1as.cpp", "src/llvm/clang_cc1as.cpp",
"src/llvm/ar.cpp",
}; };
compiler.addCSourceFiles(.{ compiler.addCSourceFiles(.{
.files = &cpp_files, .files = &cpp_files,
.flags = &.{"-g"}, .flags = &.{
"-g",
"-std=c++17",
"-D__STDC_CONSTANT_MACROS",
"-D__STDC_FORMAT_MACROS",
"-D__STDC_LIMIT_MACROS",
"-D_GNU_SOURCE",
"-fvisibility-inlines-hidden",
"-fno-exceptions",
"-fno-rtti",
"-Werror=type-limits",
"-Wno-missing-braces",
"-Wno-comment",
},
}); });
const zlib = if (target.result.os.tag == .windows) "zstd.lib" else "libzstd.a"; const zlib = if (target.result.os.tag == .windows) "zstd.lib" else "libzstd.a";
@ -320,48 +315,48 @@ pub fn build(b: *std.Build) !void {
zlib, zlib,
"libz.a", "libz.a",
// Clang // Clang
// "libclangAnalysis.a", "libclangAnalysis.a",
// "libclangAnalysisFlowSensitive.a", "libclangAnalysisFlowSensitive.a",
// "libclangAnalysisFlowSensitiveModels.a", "libclangAnalysisFlowSensitiveModels.a",
// "libclangAPINotes.a", "libclangAPINotes.a",
// "libclangARCMigrate.a", "libclangARCMigrate.a",
// "libclangAST.a", "libclangAST.a",
// "libclangASTMatchers.a", "libclangASTMatchers.a",
// "libclangBasic.a", "libclangBasic.a",
// "libclangCodeGen.a", "libclangCodeGen.a",
// "libclangCrossTU.a", "libclangCrossTU.a",
// "libclangDependencyScanning.a", "libclangDependencyScanning.a",
// "libclangDirectoryWatcher.a", "libclangDirectoryWatcher.a",
// "libclangDriver.a", "libclangDriver.a",
// "libclangDynamicASTMatchers.a", "libclangDynamicASTMatchers.a",
// "libclangEdit.a", "libclangEdit.a",
// "libclangExtractAPI.a", "libclangExtractAPI.a",
// "libclangFormat.a", "libclangFormat.a",
// "libclangFrontend.a", "libclangFrontend.a",
// "libclangFrontendTool.a", "libclangFrontendTool.a",
// "libclangHandleCXX.a", "libclangHandleCXX.a",
// "libclangHandleLLVM.a", "libclangHandleLLVM.a",
// "libclangIndex.a", "libclangIndex.a",
// "libclangIndexSerialization.a", "libclangIndexSerialization.a",
// "libclangInterpreter.a", "libclangInterpreter.a",
// "libclangLex.a", "libclangLex.a",
// "libclangParse.a", "libclangParse.a",
// "libclangRewrite.a", "libclangRewrite.a",
// "libclangRewriteFrontend.a", "libclangRewriteFrontend.a",
// "libclangSema.a", "libclangSema.a",
// "libclangSerialization.a", "libclangSerialization.a",
// "libclangStaticAnalyzerCheckers.a", "libclangStaticAnalyzerCheckers.a",
// "libclangStaticAnalyzerCore.a", "libclangStaticAnalyzerCore.a",
// "libclangStaticAnalyzerFrontend.a", "libclangStaticAnalyzerFrontend.a",
// "libclangSupport.a", "libclangSupport.a",
// "libclangTooling.a", "libclangTooling.a",
// "libclangToolingASTDiff.a", "libclangToolingASTDiff.a",
// "libclangToolingCore.a", "libclangToolingCore.a",
// "libclangToolingInclusions.a", "libclangToolingInclusions.a",
// "libclangToolingInclusionsStdlib.a", "libclangToolingInclusionsStdlib.a",
// "libclangToolingRefactoring.a", "libclangToolingRefactoring.a",
// "libclangToolingSyntax.a", "libclangToolingSyntax.a",
// "libclangTransformer.a", "libclangTransformer.a",
}; };
for (llvm_libraries) |llvm_library| { for (llvm_libraries) |llvm_library| {

1470
src/llvm/ar.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ namespace lld {
extern "C" void stream_to_string(raw_string_ostream& stream, const char** message_ptr, size_t* message_len); extern "C" void stream_to_string(raw_string_ostream& stream, const char** message_ptr, size_t* message_len);
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) extern "C" bool NativityLLDLinkELF(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); auto arguments = ArrayRef<const char*>(argument_ptr, argument_count);
std::string stdout_string; std::string stdout_string;
@ -37,18 +37,7 @@ extern "C" bool NativityLLDLink(Format format, const char** argument_ptr, size_t
std::string stderr_string; std::string stderr_string;
raw_string_ostream stderr_stream(stderr_string); raw_string_ostream stderr_stream(stderr_string);
bool success = false; bool success = lld::elf::link(arguments, stdout_stream, stderr_stream, true, 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(stdout_stream, stdout_ptr, stdout_len);
stream_to_string(stderr_stream, stderr_ptr, stderr_len); stream_to_string(stderr_stream, stderr_ptr, stderr_len);
@ -56,3 +45,53 @@ extern "C" bool NativityLLDLink(Format format, const char** argument_ptr, size_t
return success; return success;
} }
extern "C" bool NativityLLDLinkCOFF(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 = lld::coff::link(arguments, stdout_stream, stderr_stream, true, false);
stream_to_string(stdout_stream, stdout_ptr, stdout_len);
stream_to_string(stderr_stream, stderr_ptr, stderr_len);
return success;
}
extern "C" bool NativityLLDLinkMachO(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 = lld::macho::link(arguments, stdout_stream, stderr_stream, true, false);
stream_to_string(stdout_stream, stdout_ptr, stdout_len);
stream_to_string(stderr_stream, stderr_ptr, stderr_len);
return success;
}
extern "C" bool NativityLLDLinkWasm(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 = lld::wasm::link(arguments, stdout_stream, stderr_stream, true, false);
stream_to_string(stdout_stream, stdout_ptr, stdout_len);
stream_to_string(stderr_stream, stderr_ptr, stderr_len);
return success;
}