From 93a4403271ef62d8ae2cd10f58cc23d4b7bbdf4d Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 7 Jun 2021 08:37:04 +0200 Subject: cc,wasi: package emulations as static archives This replicates the expected behavior when using `clang` with upstream `wasi-libc` sysroot: linking emulated subcomponents such as process clocks or signals requires an explicit link flag in the compiler invocation, for example: ``` zig cc -target wasm32-wasi -lwasi-emulated-process-clocks main.c -o main.wasm ``` --- src/link/Wasm.zig | 19 ++++++--- src/wasi_libc.zig | 119 +++++++++++++++++++++++++++++++++--------------------- 2 files changed, 86 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 77283384be..443ace855a 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -702,11 +702,20 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { try argv.append(try comp.get_libc_crt_file(arena, "crt.o")); } - 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, - })); + 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})); + } + } + + if (self.base.options.link_libc) { + try argv.append(try comp.get_libc_crt_file(arena, "libc.a")); + } } // Positional arguments to the linker such as object files. diff --git a/src/wasi_libc.zig b/src/wasi_libc.zig index b7be6af82f..37e7f44488 100644 --- a/src/wasi_libc.zig +++ b/src/wasi_libc.zig @@ -23,21 +23,21 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void { try addCCArgs(comp, arena, &args, false); try addLibcBottomHalfIncludes(comp, arena, &args); - var comp_sources = std.ArrayList(Compilation.CSourceFile).init(arena); + var crt_sources = std.ArrayList(Compilation.CSourceFile).init(arena); for (crt_src_files) |file_path| { - try comp_sources.append(.{ + 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, comp_sources.items); + try comp.build_crt_file("crt", .Obj, crt_sources.items); } { // Compile WASI libc (sysroot). - var comp_sources = std.ArrayList(Compilation.CSourceFile).init(arena); + var libc_sources = std.ArrayList(Compilation.CSourceFile).init(arena); { // Compile dlmalloc. @@ -54,7 +54,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void { }); for (dlmalloc_src_files) |file_path| { - try comp_sources.append(.{ + try libc_sources.append(.{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", try sanitize(arena, file_path), }), @@ -70,7 +70,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void { try addLibcBottomHalfIncludes(comp, arena, &args); for (libc_bottom_half_src_files) |file_path| { - try comp_sources.append(.{ + try libc_sources.append(.{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", try sanitize(arena, file_path), }), @@ -80,63 +80,88 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void { } { - // Compile emulated sources depending only on libc-bottom-half. + // Compile libc-top-half. var args = std.ArrayList([]const u8).init(arena); try addCCArgs(comp, arena, &args, true); - try addLibcBottomHalfIncludes(comp, arena, &args); + try addLibcTopHalfIncludes(comp, arena, &args); - for (emulated_process_clocks_src_files) |file_path| { - try comp_sources.append(.{ + 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, }); } + } - for (emulated_getpid_src_files) |file_path| { - try comp_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); + } - for (emulated_mman_src_files) |file_path| { - try comp_sources.append(.{ - .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ - "libc", try sanitize(arena, file_path), - }), - .extra_flags = args.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 signals (bottom-half). - var args = std.ArrayList([]const u8).init(arena); - try addCCArgs(comp, arena, &args, true); + { + // Compile emulated getpid. + 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 comp_sources.append(.{ - .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ - "libc", try sanitize(arena, file_path), - }), - .extra_flags = args.items, - }); - } + 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); { - // Compile emulated signals (top-half). 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 comp_sources.append(.{ + 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), }), @@ -146,13 +171,13 @@ 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 addLibcTopHalfIncludes(comp, arena, &args); + try args.append("-D_WASI_EMULATED_SIGNAL"); - for (libc_top_half_src_files) |file_path| { - try comp_sources.append(.{ + 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), }), @@ -161,7 +186,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void { } } - try comp.build_crt_file("c", .Lib, comp_sources.items); + try comp.build_crt_file("wasi-emulated-signal", .Lib, emu_signal_sources.items); } } -- cgit v1.2.3