Commit 6d5002028a

Jakub Konka <kubkon@jakubkonka.com>
2021-05-19 21:59:21
cc,wasi: link compiled WASI libc with wasm-ld
1 parent f102a58
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",
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}),
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);
 
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;
     }
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) {
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{