From 6d5002028a2fe71b67d8106b30c6602bc8e44121 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 19 May 2021 21:59:21 +0200 Subject: [PATCH] cc,wasi: link compiled WASI libc with wasm-ld --- lib/std/target.zig | 3 --- lib/std/zig.zig | 11 ++++++++++- src/Compilation.zig | 3 ++- src/link.zig | 4 +--- src/link/Wasm.zig | 13 +++++++++++++ src/wasi_libc.zig | 5 +++++ 6 files changed, 31 insertions(+), 8 deletions(-) diff --git a/lib/std/target.zig b/lib/std/target.zig index fb54d2e18f..aa65ca669e 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -1307,9 +1307,6 @@ pub const Target = struct { } pub fn libPrefix_cpu_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) [:0]const u8 { - if (cpu_arch.isWasm()) { - return ""; - } switch (abi) { .msvc => return "", else => return "lib", diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 911edbd21c..61e7ca5545 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -160,8 +160,17 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro }, .wasm => switch (options.output_mode) { .Exe => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.exeFileExt() }), + .Lib => { + switch (options.link_mode orelse .Static) { + .Static => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ + target.libPrefix(), root_name, + }), + .Dynamic => return std.fmt.allocPrint(allocator, "{s}{s}.wasm", .{ + target.libPrefix(), root_name, + }), + } + }, .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.oFileExt() }), - .Lib => return std.fmt.allocPrint(allocator, "{s}.wasm", .{root_name}), }, .c => return std.fmt.allocPrint(allocator, "{s}.c", .{root_name}), .spirv => return std.fmt.allocPrint(allocator, "{s}.spv", .{root_name}), diff --git a/src/Compilation.zig b/src/Compilation.zig index 5c856b6217..1d1f2f01b8 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3262,7 +3262,8 @@ fn detectLibCFromLibCInstallation(arena: *Allocator, target: Target, lci: *const pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []const u8) ![]const u8 { if (comp.wantBuildGLibCFromSource() or comp.wantBuildMuslFromSource() or - comp.wantBuildMinGWFromSource()) + comp.wantBuildMinGWFromSource() or + comp.wantBuildWASILibcSysrootFromSource()) { return comp.crt_files.get(basename).?.full_object_path; } diff --git a/src/link.zig b/src/link.zig index 33b73a3360..7338593a0e 100644 --- a/src/link.zig +++ b/src/link.zig @@ -412,9 +412,7 @@ pub const File = struct { return; } const use_lld = build_options.have_llvm and base.options.use_lld; - if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static and - !base.options.target.isWasm()) - { + if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static) { return base.linkAsArchive(comp); } switch (base.tag) { diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 41b08b09d6..8e296b2b6a 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -573,6 +573,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { null; const target = self.base.options.target; + const link_in_crt = self.base.options.link_libc and self.base.options.output_mode == .Exe; const id_symlink_basename = "lld.id"; @@ -695,6 +696,18 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { full_out_path, }); + if (link_in_crt) { + // TODO work out if we want standard crt, a reactor or a command + try argv.append(try comp.get_libc_crt_file(arena, "crt.o.wasm")); + } + + if (!is_obj and self.base.options.link_libc) { + try argv.append(try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) { + .Static => "libc.a", + .Dynamic => unreachable, + })); + } + // Positional arguments to the linker such as object files. try argv.appendSlice(self.base.options.objects); diff --git a/src/wasi_libc.zig b/src/wasi_libc.zig index 5b7738204b..e2d3652928 100644 --- a/src/wasi_libc.zig +++ b/src/wasi_libc.zig @@ -17,6 +17,7 @@ pub fn buildWASILibcSysroot(comp: *Compilation) !void { const arena = &arena_allocator.allocator; { + // Compile crt sources. var args = std.ArrayList([]const u8).init(arena); try addCCArgs(comp, arena, &args, false); try args.appendSlice(&[_][]const u8{ @@ -62,9 +63,11 @@ pub fn buildWASILibcSysroot(comp: *Compilation) !void { } { + // Compile WASI libc (sysroot). var comp_sources = std.ArrayList(Compilation.CSourceFile).init(arena); { + // Compile dlmalloc. var args = std.ArrayList([]const u8).init(arena); try addCCArgs(comp, arena, &args, true); try args.appendSlice(&[_][]const u8{ @@ -88,6 +91,7 @@ pub fn buildWASILibcSysroot(comp: *Compilation) !void { } { + // Compile libc-bottom-half. var args = std.ArrayList([]const u8).init(arena); try addCCArgs(comp, arena, &args, true); try args.appendSlice(&[_][]const u8{ @@ -131,6 +135,7 @@ pub fn buildWASILibcSysroot(comp: *Compilation) !void { } { + // Compile libc-top-half. var args = std.ArrayList([]const u8).init(arena); try addCCArgs(comp, arena, &args, true); try args.appendSlice(&[_][]const u8{