diff --git a/src/Compilation.zig b/src/Compilation.zig index 1d85182f06..371bcdaf18 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -651,7 +651,7 @@ pub const InitOptions = struct { /// * getpid /// * mman /// * signal - wasi_emulated_libs: []const []const u8 = &[0][]const u8{}, + wasi_emulated_libs: []const wasi_libc.CRTFile = &[0]wasi_libc.CRTFile{}, link_libc: bool = false, link_libcpp: bool = false, link_libunwind: bool = false, @@ -1434,11 +1434,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { }); } if (comp.wantBuildWasiLibcFromSource()) { - try comp.work_queue.ensureUnusedCapacity(6); // worst-case we need all components const wasi_emulated_libs = comp.bin_file.options.wasi_emulated_libs; - for (wasi_emulated_libs) |lib_name| { + try comp.work_queue.ensureUnusedCapacity(wasi_emulated_libs.len + 2); // worst-case we need all components + for (wasi_emulated_libs) |crt_file| { comp.work_queue.writeItemAssumeCapacity(.{ - .wasi_libc_crt_file = wasi_libc.getEmulatedLibCRTFile(lib_name).?, + .wasi_libc_crt_file = crt_file, }); } // TODO add logic deciding which crt1 we want here. @@ -4157,12 +4157,6 @@ pub fn stage1AddLinkLib(comp: *Compilation, lib_name: []const u8) !void { if (comp.bin_file.options.skip_linker_dependencies) return; // This happens when an `extern "foo"` function is referenced by the stage1 backend. - if (comp.getTarget().os.tag == .wasi and mem.eql(u8, "wasi_snapshot_preview1", lib_name)) { - // Any referenced symbol from this lib, will be undefined until - // runtime as this lib is provided directly by the runtime. - return; - } - // If we haven't seen this library yet and we're targeting Windows, we need to queue up // a work item to produce the DLL import library for this. const gop = try comp.bin_file.options.system_libs.getOrPut(comp.gpa, lib_name); diff --git a/src/link.zig b/src/link.zig index c013db4947..4072e90ca3 100644 --- a/src/link.zig +++ b/src/link.zig @@ -13,6 +13,7 @@ const Type = @import("type.zig").Type; const Cache = @import("Cache.zig"); const build_options = @import("build_options"); const LibCInstallation = @import("libc_installation.zig").LibCInstallation; +const wasi_libc = @import("wasi_libc.zig"); pub const producer_string = if (std.builtin.is_test) "zig test" else "zig " ++ build_options.version; @@ -110,7 +111,7 @@ pub const Options = struct { framework_dirs: []const []const u8, frameworks: []const []const u8, system_libs: std.StringArrayHashMapUnmanaged(void), - wasi_emulated_libs: []const []const u8, + wasi_emulated_libs: []const wasi_libc.CRTFile, lib_dirs: []const []const u8, rpath_list: []const []const u8, diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 39f1f13e60..21bb9d826c 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -15,6 +15,7 @@ const codegen = @import("../codegen/wasm.zig"); const link = @import("../link.zig"); const trace = @import("../tracy.zig").trace; const build_options = @import("build_options"); +const wasi_libc = @import("../wasi_libc.zig"); const Cache = @import("../Cache.zig"); const TypedValue = @import("../TypedValue.zig"); @@ -700,14 +701,22 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic); if (is_exe_or_dyn_lib) { const system_libs = self.base.options.system_libs.keys(); + for (system_libs) |link_lib| { + if (mem.eql(u8, "wasi_snapshot_preview1", link_lib)) { + // Any referenced symbol from this lib, will be undefined until + // runtime as this lib is provided directly by the runtime. + continue; + } try argv.append(try std.fmt.allocPrint(arena, "-l{s}", .{link_lib})); } const wasi_emulated_libs = self.base.options.wasi_emulated_libs; - for (wasi_emulated_libs) |lib_name| { - const full_lib_name = try std.fmt.allocPrint(arena, "lib{s}.a", .{lib_name}); - try argv.append(try comp.get_libc_crt_file(arena, full_lib_name)); + for (wasi_emulated_libs) |crt_file| { + try argv.append(try comp.get_libc_crt_file( + arena, + wasi_libc.emulatedLibCRFileLibName(crt_file), + )); } if (self.base.options.link_libc) { diff --git a/src/main.zig b/src/main.zig index 1e4ec0183f..0b93f97726 100644 --- a/src/main.zig +++ b/src/main.zig @@ -617,7 +617,7 @@ fn buildOutputType( var system_libs = std.ArrayList([]const u8).init(gpa); defer system_libs.deinit(); - var wasi_emulated_libs = std.ArrayList([]const u8).init(gpa); + var wasi_emulated_libs = std.ArrayList(wasi_libc.CRTFile).init(gpa); defer wasi_emulated_libs.deinit(); var clang_argv = std.ArrayList([]const u8).init(gpa); @@ -1591,8 +1591,8 @@ fn buildOutputType( fatal("cannot use absolute path as a system library: {s}", .{lib_name}); } if (target_info.target.os.tag == .wasi) { - if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |_| { - try wasi_emulated_libs.append(lib_name); + if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| { + try wasi_emulated_libs.append(crt_file); _ = system_libs.orderedRemove(i); continue; } diff --git a/src/wasi_libc.zig b/src/wasi_libc.zig index 0c178891c7..b61ba5091c 100644 --- a/src/wasi_libc.zig +++ b/src/wasi_libc.zig @@ -35,6 +35,16 @@ pub fn getEmulatedLibCRTFile(lib_name: []const u8) ?CRTFile { return null; } +pub fn emulatedLibCRFileLibName(crt_file: CRTFile) []const u8 { + return switch (crt_file) { + .libwasi_emulated_process_clocks_a => "libwasi-emulated-process-clocks.a", + .libwasi_emulated_getpid_a => "libwasi-emulated-getpid.a", + .libwasi_emulated_mman_a => "libwasi-emulated-mman.a", + .libwasi_emulated_signal_a => "libwasi-emulated-signal.a", + else => unreachable, + }; +} + pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions;