Commit 4e4722a65e
Changed files (5)
src/link/Wasm.zig
@@ -699,18 +699,19 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
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"));
+ try argv.append(try comp.get_libc_crt_file(arena, "crt1.o"));
}
if (!is_obj) {
const system_libs = self.base.options.system_libs.keys();
for (system_libs) |link_lib| {
- const full_name = try std.fmt.allocPrint(arena, "lib{s}.a", .{link_lib});
- if (comp.crt_files.get(full_name)) |crt| {
- try argv.append(crt.full_object_path);
- } else {
- try argv.append(try std.fmt.allocPrint(arena, "-l{s}", .{link_lib}));
- }
+ 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));
}
if (self.base.options.link_libc) {
src/Compilation.zig
@@ -203,8 +203,8 @@ const Job = union(enum) {
/// needed when not linking libc and using LLVM for code generation because it generates
/// calls to, for example, memcpy and memset.
zig_libc: void,
- /// WASI libc sysroot
- wasi_libc_sysroot: void,
+ /// one of WASI libc static objects
+ wasi_libc_crt_file: wasi_libc.CRTFile,
/// Use stage1 C++ code to compile zig code into an object file.
stage1_module: void,
@@ -279,7 +279,7 @@ pub const MiscTask = enum {
libcxx,
libcxxabi,
libtsan,
- wasi_libc_sysroot,
+ wasi_libc_crt_file,
compiler_rt,
libssp,
zig_libc,
@@ -646,6 +646,12 @@ pub const InitOptions = struct {
framework_dirs: []const []const u8 = &[0][]const u8{},
frameworks: []const []const u8 = &[0][]const u8{},
system_libs: []const []const u8 = &[0][]const u8{},
+ /// These correspond to the WASI libc emulated subcomponents including:
+ /// * process clocks
+ /// * getpid
+ /// * mman
+ /// * signal
+ wasi_emulated_libs: []const []const u8 = &[0][]const u8{},
link_libc: bool = false,
link_libcpp: bool = false,
link_libunwind: bool = false,
@@ -1286,6 +1292,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.framework_dirs = options.framework_dirs,
.system_libs = system_libs,
.syslibroot = darwin_options.syslibroot,
+ .wasi_emulated_libs = options.wasi_emulated_libs,
.lib_dirs = options.lib_dirs,
.rpath_list = options.rpath_list,
.strip = strip,
@@ -1426,8 +1433,19 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
},
});
}
- if (comp.wantBuildWasiLibcSysrootFromSource()) {
- try comp.work_queue.write(&[_]Job{.{ .wasi_libc_sysroot = {} }});
+ 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| {
+ comp.work_queue.writeItemAssumeCapacity(.{
+ .wasi_libc_crt_file = wasi_libc.getEmulatedLibCRTFile(lib_name).?,
+ });
+ }
+ // TODO add logic deciding which crt1 we want here.
+ comp.work_queue.writeAssumeCapacity(&[_]Job{
+ .{ .wasi_libc_crt_file = .crt1_o },
+ .{ .wasi_libc_crt_file = .libc_a },
+ });
}
if (comp.wantBuildMinGWFromSource()) {
const static_lib_jobs = [_]Job{
@@ -2169,12 +2187,12 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
);
};
},
- .wasi_libc_sysroot => {
- wasi_libc.buildWasiLibcSysroot(self) catch |err| {
+ .wasi_libc_crt_file => |crt_file| {
+ wasi_libc.buildCRTFile(self, crt_file) catch |err| {
// TODO Surface more error details.
try self.setMiscFailure(
- .wasi_libc_sysroot,
- "unable to build WASI libc sysroot: {s}",
+ .wasi_libc_crt_file,
+ "unable to build WASI libc CRT file: {s}",
.{@errorName(err)},
);
};
@@ -3303,7 +3321,7 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []cons
if (comp.wantBuildGLibCFromSource() or
comp.wantBuildMuslFromSource() or
comp.wantBuildMinGWFromSource() or
- comp.wantBuildWasiLibcSysrootFromSource())
+ comp.wantBuildWasiLibcFromSource())
{
return comp.crt_files.get(basename).?.full_object_path;
}
@@ -3343,8 +3361,9 @@ fn wantBuildMuslFromSource(comp: Compilation) bool {
!comp.getTarget().isWasm();
}
-fn wantBuildWasiLibcSysrootFromSource(comp: Compilation) bool {
- return comp.wantBuildLibCFromSource() and comp.getTarget().isWasm();
+fn wantBuildWasiLibcFromSource(comp: Compilation) bool {
+ return comp.wantBuildLibCFromSource() and comp.getTarget().isWasm() and
+ comp.getTarget().os.tag == .wasi;
}
fn wantBuildMinGWFromSource(comp: Compilation) bool {
src/link.zig
@@ -110,6 +110,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,
lib_dirs: []const []const u8,
rpath_list: []const []const u8,
src/main.zig
@@ -15,6 +15,7 @@ const Package = @import("Package.zig");
const build_options = @import("build_options");
const introspect = @import("introspect.zig");
const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
+const wasi_libc = @import("wasi_libc.zig");
const translate_c = @import("translate_c.zig");
const Cache = @import("Cache.zig");
const target_util = @import("target.zig");
@@ -616,6 +617,9 @@ 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);
+ defer wasi_emulated_libs.deinit();
+
var clang_argv = std.ArrayList([]const u8).init(gpa);
defer clang_argv.deinit();
@@ -1586,6 +1590,13 @@ fn buildOutputType(
if (std.fs.path.isAbsolute(lib_name)) {
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);
+ _ = system_libs.orderedRemove(i);
+ continue;
+ }
+ }
i += 1;
}
}
@@ -1895,6 +1906,7 @@ fn buildOutputType(
.framework_dirs = framework_dirs.items,
.frameworks = frameworks.items,
.system_libs = system_libs.items,
+ .wasi_emulated_libs = wasi_emulated_libs.items,
.link_libc = link_libc,
.link_libcpp = link_libcpp,
.link_libunwind = link_libunwind,
src/wasi_libc.zig
@@ -1,4 +1,5 @@
const std = @import("std");
+const mem = std.mem;
const path = std.fs.path;
const Allocator = std.mem.Allocator;
@@ -7,7 +8,34 @@ const build_options = @import("build_options");
const target_util = @import("target.zig");
const musl = @import("musl.zig");
-pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
+pub const CRTFile = enum {
+ crt1_o,
+ crt1_reactor_o,
+ crt1_command_o,
+ libc_a,
+ libwasi_emulated_process_clocks_a,
+ libwasi_emulated_getpid_a,
+ libwasi_emulated_mman_a,
+ libwasi_emulated_signal_a,
+};
+
+pub fn getEmulatedLibCRTFile(lib_name: []const u8) ?CRTFile {
+ if (mem.eql(u8, lib_name, "wasi-emulated-process-clocks")) {
+ return .libwasi_emulated_process_clocks_a;
+ }
+ if (mem.eql(u8, lib_name, "wasi-emulated-getpid")) {
+ return .libwasi_emulated_getpid_a;
+ }
+ if (mem.eql(u8, lib_name, "wasi-emulated-mman")) {
+ return .libwasi_emulated_mman_a;
+ }
+ if (mem.eql(u8, lib_name, "wasi-emulated-signal")) {
+ return .libwasi_emulated_signal_a;
+ }
+ return null;
+}
+
+pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void {
if (!build_options.have_llvm) {
return error.ZigCompilerNotBuiltWithLLVMExtensions;
}
@@ -17,176 +45,190 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
defer arena_allocator.deinit();
const arena = &arena_allocator.allocator;
- {
- // Compile crt sources.
- var args = std.ArrayList([]const u8).init(arena);
- try addCCArgs(comp, arena, &args, false);
- try addLibcBottomHalfIncludes(comp, arena, &args);
-
- var crt_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
- for (crt_src_files) |file_path| {
- try crt_sources.append(.{
- .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
- "libc", try sanitize(arena, file_path),
- }),
- .extra_flags = args.items,
- });
- }
- try comp.build_crt_file("crt", .Obj, crt_sources.items);
- }
-
- {
- // Compile WASI libc (sysroot).
- var libc_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
-
- {
- // Compile dlmalloc.
+ switch (crt_file) {
+ .crt1_o => {
var args = std.ArrayList([]const u8).init(arena);
- try addCCArgs(comp, arena, &args, true);
- try args.appendSlice(&[_][]const u8{
- "-I",
- try comp.zig_lib_directory.join(arena, &[_][]const u8{
- "libc",
- "wasi",
- "dlmalloc",
- "include",
- }),
+ try addCCArgs(comp, arena, &args, false);
+ try addLibcBottomHalfIncludes(comp, arena, &args);
+ return comp.build_crt_file("crt1", .Obj, &[1]Compilation.CSourceFile{
+ .{
+ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
+ "libc", try sanitize(arena, crt1_src_file),
+ }),
+ .extra_flags = args.items,
+ },
});
-
- for (dlmalloc_src_files) |file_path| {
- try libc_sources.append(.{
+ },
+ .crt1_reactor_o => {
+ var args = std.ArrayList([]const u8).init(arena);
+ try addCCArgs(comp, arena, &args, false);
+ try addLibcBottomHalfIncludes(comp, arena, &args);
+ return comp.build_crt_file("crt1-reactor", .Obj, &[1]Compilation.CSourceFile{
+ .{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
- "libc", try sanitize(arena, file_path),
+ "libc", try sanitize(arena, crt1_reactor_src_file),
}),
.extra_flags = args.items,
- });
- }
- }
-
- {
- // Compile libc-bottom-half.
+ },
+ });
+ },
+ .crt1_command_o => {
var args = std.ArrayList([]const u8).init(arena);
- try addCCArgs(comp, arena, &args, true);
+ try addCCArgs(comp, arena, &args, false);
try addLibcBottomHalfIncludes(comp, arena, &args);
-
- for (libc_bottom_half_src_files) |file_path| {
- try libc_sources.append(.{
+ return comp.build_crt_file("crt1-command", .Obj, &[1]Compilation.CSourceFile{
+ .{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
- "libc", try sanitize(arena, file_path),
+ "libc", try sanitize(arena, crt1_command_src_file),
}),
.extra_flags = args.items,
+ },
+ });
+ },
+ .libc_a => {
+ var libc_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{
+ "-I",
+ try comp.zig_lib_directory.join(arena, &[_][]const u8{
+ "libc",
+ "wasi",
+ "dlmalloc",
+ "include",
+ }),
});
+
+ for (dlmalloc_src_files) |file_path| {
+ try libc_sources.append(.{
+ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
+ "libc", try sanitize(arena, file_path),
+ }),
+ .extra_flags = args.items,
+ });
+ }
}
- }
- {
- // Compile libc-top-half.
+ {
+ // Compile libc-bottom-half.
+ var args = std.ArrayList([]const u8).init(arena);
+ try addCCArgs(comp, arena, &args, true);
+ try addLibcBottomHalfIncludes(comp, arena, &args);
+
+ for (libc_bottom_half_src_files) |file_path| {
+ try libc_sources.append(.{
+ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
+ "libc", try sanitize(arena, file_path),
+ }),
+ .extra_flags = args.items,
+ });
+ }
+ }
+
+ {
+ // Compile libc-top-half.
+ var args = std.ArrayList([]const u8).init(arena);
+ try addCCArgs(comp, arena, &args, true);
+ try addLibcTopHalfIncludes(comp, arena, &args);
+
+ for (libc_top_half_src_files) |file_path| {
+ try libc_sources.append(.{
+ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
+ "libc", try sanitize(arena, file_path),
+ }),
+ .extra_flags = args.items,
+ });
+ }
+ }
+
+ try comp.build_crt_file("c", .Lib, libc_sources.items);
+ },
+ .libwasi_emulated_process_clocks_a => {
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
- try addLibcTopHalfIncludes(comp, arena, &args);
+ try addLibcBottomHalfIncludes(comp, arena, &args);
- for (libc_top_half_src_files) |file_path| {
- try libc_sources.append(.{
+ var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
+ for (emulated_process_clocks_src_files) |file_path| {
+ try emu_clocks_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
});
}
- }
-
- try comp.build_crt_file("c", .Lib, libc_sources.items);
- }
-
- {
- // Compile emulated process clocks.
- var args = std.ArrayList([]const u8).init(arena);
- try addCCArgs(comp, arena, &args, true);
- try addLibcBottomHalfIncludes(comp, arena, &args);
-
- var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
- for (emulated_process_clocks_src_files) |file_path| {
- try emu_clocks_sources.append(.{
- .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
- "libc", try sanitize(arena, file_path),
- }),
- .extra_flags = args.items,
- });
- }
- try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, emu_clocks_sources.items);
- }
-
- {
- // Compile emulated getpid.
- var args = std.ArrayList([]const u8).init(arena);
- try addCCArgs(comp, arena, &args, true);
- try addLibcBottomHalfIncludes(comp, arena, &args);
-
- var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
- for (emulated_getpid_src_files) |file_path| {
- try emu_getpid_sources.append(.{
- .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
- "libc", try sanitize(arena, file_path),
- }),
- .extra_flags = args.items,
- });
- }
- try comp.build_crt_file("wasi-emulated-getpid", .Lib, emu_getpid_sources.items);
- }
-
- {
- // Compile emulated mman.
- var args = std.ArrayList([]const u8).init(arena);
- try addCCArgs(comp, arena, &args, true);
- try addLibcBottomHalfIncludes(comp, arena, &args);
-
- var emu_mman_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
- for (emulated_mman_src_files) |file_path| {
- try emu_mman_sources.append(.{
- .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
- "libc", try sanitize(arena, file_path),
- }),
- .extra_flags = args.items,
- });
- }
- try comp.build_crt_file("wasi-emulated-mman", .Lib, emu_mman_sources.items);
- }
-
- {
- // Compile emulated signals.
- var emu_signal_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
-
- {
+ try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, emu_clocks_sources.items);
+ },
+ .libwasi_emulated_getpid_a => {
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
+ try addLibcBottomHalfIncludes(comp, arena, &args);
- for (emulated_signal_bottom_half_src_files) |file_path| {
- try emu_signal_sources.append(.{
+ var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
+ for (emulated_getpid_src_files) |file_path| {
+ try emu_getpid_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
});
}
- }
-
- {
+ try comp.build_crt_file("wasi-emulated-getpid", .Lib, emu_getpid_sources.items);
+ },
+ .libwasi_emulated_mman_a => {
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
- try addLibcTopHalfIncludes(comp, arena, &args);
- try args.append("-D_WASI_EMULATED_SIGNAL");
+ try addLibcBottomHalfIncludes(comp, arena, &args);
- for (emulated_signal_top_half_src_files) |file_path| {
- try emu_signal_sources.append(.{
+ var emu_mman_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
+ for (emulated_mman_src_files) |file_path| {
+ try emu_mman_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
});
}
- }
+ try comp.build_crt_file("wasi-emulated-mman", .Lib, emu_mman_sources.items);
+ },
+ .libwasi_emulated_signal_a => {
+ var emu_signal_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
+
+ {
+ var args = std.ArrayList([]const u8).init(arena);
+ try addCCArgs(comp, arena, &args, true);
+
+ for (emulated_signal_bottom_half_src_files) |file_path| {
+ try emu_signal_sources.append(.{
+ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
+ "libc", try sanitize(arena, file_path),
+ }),
+ .extra_flags = args.items,
+ });
+ }
+ }
- try comp.build_crt_file("wasi-emulated-signal", .Lib, emu_signal_sources.items);
+ {
+ var args = std.ArrayList([]const u8).init(arena);
+ try addCCArgs(comp, arena, &args, true);
+ try addLibcTopHalfIncludes(comp, arena, &args);
+ try args.append("-D_WASI_EMULATED_SIGNAL");
+
+ for (emulated_signal_top_half_src_files) |file_path| {
+ try emu_signal_sources.append(.{
+ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
+ "libc", try sanitize(arena, file_path),
+ }),
+ .extra_flags = args.items,
+ });
+ }
+ }
+
+ try comp.build_crt_file("wasi-emulated-signal", .Lib, emu_signal_sources.items);
+ },
}
}
@@ -1084,11 +1126,9 @@ const libc_top_half_src_files = [_][]const u8{
"wasi/libc-top-half/sources/arc4random.c",
};
-const crt_src_files = &[_][]const u8{
- "wasi/libc-bottom-half/crt/crt1.c",
- "wasi/libc-bottom-half/crt/crt1-command.c",
- "wasi/libc-bottom-half/crt/crt1-reactor.c",
-};
+const crt1_src_file = "wasi/libc-bottom-half/crt/crt1.c";
+const crt1_command_src_file = "wasi/libc-bottom-half/crt/crt1-command.c";
+const crt1_reactor_src_file = "wasi/libc-bottom-half/crt/crt1-reactor.c";
const emulated_process_clocks_src_files = &[_][]const u8{
"wasi/libc-bottom-half/clocks/clock.c",