authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-07 08:37:04+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-09 01:25:38+02:00
log93a4403271ef62d8ae2cd10f58cc23d4b7bbdf4d
treecffa7232a2e239a72e38648613768b0c3c5aedde
parent6f6182a5f3a4b027bbff6405600fd21b3ef8b86c

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 ```

2 files changed, 86 insertions(+), 52 deletions(-)

src/link/Wasm.zig+14-5
......@@ -702,11 +702,20 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
702702 try argv.append(try comp.get_libc_crt_file(arena, "crt.o"));
703703 }
704704
705 if (!is_obj and self.base.options.link_libc) {
706 try argv.append(try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) {
707 .Static => "libc.a",
708 .Dynamic => unreachable,
709 }));
705 if (!is_obj) {
706 const system_libs = self.base.options.system_libs.keys();
707 for (system_libs) |link_lib| {
708 const full_name = try std.fmt.allocPrint(arena, "lib{s}.a", .{link_lib});
709 if (comp.crt_files.get(full_name)) |crt| {
710 try argv.append(crt.full_object_path);
711 } else {
712 try argv.append(try std.fmt.allocPrint(arena, "-l{s}", .{link_lib}));
713 }
714 }
715
716 if (self.base.options.link_libc) {
717 try argv.append(try comp.get_libc_crt_file(arena, "libc.a"));
718 }
710719 }
711720
712721 // Positional arguments to the linker such as object files.
src/wasi_libc.zig+72-47
......@@ -23,21 +23,21 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
2323 try addCCArgs(comp, arena, &args, false);
2424 try addLibcBottomHalfIncludes(comp, arena, &args);
2525
26 var comp_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
26 var crt_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
2727 for (crt_src_files) |file_path| {
28 try comp_sources.append(.{
28 try crt_sources.append(.{
2929 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
3030 "libc", try sanitize(arena, file_path),
3131 }),
3232 .extra_flags = args.items,
3333 });
3434 }
35 try comp.build_crt_file("crt", .Obj, comp_sources.items);
35 try comp.build_crt_file("crt", .Obj, crt_sources.items);
3636 }
3737
3838 {
3939 // Compile WASI libc (sysroot).
40 var comp_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
40 var libc_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
4141
4242 {
4343 // Compile dlmalloc.
......@@ -54,7 +54,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
5454 });
5555
5656 for (dlmalloc_src_files) |file_path| {
57 try comp_sources.append(.{
57 try libc_sources.append(.{
5858 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
5959 "libc", try sanitize(arena, file_path),
6060 }),
......@@ -70,7 +70,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
7070 try addLibcBottomHalfIncludes(comp, arena, &args);
7171
7272 for (libc_bottom_half_src_files) |file_path| {
73 try comp_sources.append(.{
73 try libc_sources.append(.{
7474 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
7575 "libc", try sanitize(arena, file_path),
7676 }),
......@@ -80,63 +80,88 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
8080 }
8181
8282 {
83 // Compile emulated sources depending only on libc-bottom-half.
83 // Compile libc-top-half.
8484 var args = std.ArrayList([]const u8).init(arena);
8585 try addCCArgs(comp, arena, &args, true);
86 try addLibcBottomHalfIncludes(comp, arena, &args);
86 try addLibcTopHalfIncludes(comp, arena, &args);
8787
88 for (emulated_process_clocks_src_files) |file_path| {
89 try comp_sources.append(.{
88 for (libc_top_half_src_files) |file_path| {
89 try libc_sources.append(.{
9090 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
9191 "libc", try sanitize(arena, file_path),
9292 }),
9393 .extra_flags = args.items,
9494 });
9595 }
96 }
9697
97 for (emulated_getpid_src_files) |file_path| {
98 try comp_sources.append(.{
99 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
100 "libc", try sanitize(arena, file_path),
101 }),
102 .extra_flags = args.items,
103 });
104 }
98 try comp.build_crt_file("c", .Lib, libc_sources.items);
99 }
105100
106 for (emulated_mman_src_files) |file_path| {
107 try comp_sources.append(.{
108 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
109 "libc", try sanitize(arena, file_path),
110 }),
111 .extra_flags = args.items,
112 });
113 }
101 {
102 // Compile emulated process clocks.
103 var args = std.ArrayList([]const u8).init(arena);
104 try addCCArgs(comp, arena, &args, true);
105 try addLibcBottomHalfIncludes(comp, arena, &args);
106
107 var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
108 for (emulated_process_clocks_src_files) |file_path| {
109 try emu_clocks_sources.append(.{
110 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
111 "libc", try sanitize(arena, file_path),
112 }),
113 .extra_flags = args.items,
114 });
114115 }
116 try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, emu_clocks_sources.items);
117 }
115118
116 {
117 // Compile emulated signals (bottom-half).
118 var args = std.ArrayList([]const u8).init(arena);
119 try addCCArgs(comp, arena, &args, true);
119 {
120 // Compile emulated getpid.
121 var args = std.ArrayList([]const u8).init(arena);
122 try addCCArgs(comp, arena, &args, true);
123 try addLibcBottomHalfIncludes(comp, arena, &args);
120124
121 for (emulated_signal_bottom_half_src_files) |file_path| {
122 try comp_sources.append(.{
123 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
124 "libc", try sanitize(arena, file_path),
125 }),
126 .extra_flags = args.items,
127 });
128 }
125 var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
126 for (emulated_getpid_src_files) |file_path| {
127 try emu_getpid_sources.append(.{
128 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
129 "libc", try sanitize(arena, file_path),
130 }),
131 .extra_flags = args.items,
132 });
133 }
134 try comp.build_crt_file("wasi-emulated-getpid", .Lib, emu_getpid_sources.items);
135 }
136
137 {
138 // Compile emulated mman.
139 var args = std.ArrayList([]const u8).init(arena);
140 try addCCArgs(comp, arena, &args, true);
141 try addLibcBottomHalfIncludes(comp, arena, &args);
142
143 var emu_mman_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
144 for (emulated_mman_src_files) |file_path| {
145 try emu_mman_sources.append(.{
146 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
147 "libc", try sanitize(arena, file_path),
148 }),
149 .extra_flags = args.items,
150 });
129151 }
152 try comp.build_crt_file("wasi-emulated-mman", .Lib, emu_mman_sources.items);
153 }
154
155 {
156 // Compile emulated signals.
157 var emu_signal_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
130158
131159 {
132 // Compile emulated signals (top-half).
133160 var args = std.ArrayList([]const u8).init(arena);
134161 try addCCArgs(comp, arena, &args, true);
135 try addLibcTopHalfIncludes(comp, arena, &args);
136 try args.append("-D_WASI_EMULATED_SIGNAL");
137162
138 for (emulated_signal_top_half_src_files) |file_path| {
139 try comp_sources.append(.{
163 for (emulated_signal_bottom_half_src_files) |file_path| {
164 try emu_signal_sources.append(.{
140165 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
141166 "libc", try sanitize(arena, file_path),
142167 }),
......@@ -146,13 +171,13 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
146171 }
147172
148173 {
149 // Compile libc-top-half.
150174 var args = std.ArrayList([]const u8).init(arena);
151175 try addCCArgs(comp, arena, &args, true);
152176 try addLibcTopHalfIncludes(comp, arena, &args);
177 try args.append("-D_WASI_EMULATED_SIGNAL");
153178
154 for (libc_top_half_src_files) |file_path| {
155 try comp_sources.append(.{
179 for (emulated_signal_top_half_src_files) |file_path| {
180 try emu_signal_sources.append(.{
156181 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
157182 "libc", try sanitize(arena, file_path),
158183 }),
......@@ -161,7 +186,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
161186 }
162187 }
163188
164 try comp.build_crt_file("c", .Lib, comp_sources.items);
189 try comp.build_crt_file("wasi-emulated-signal", .Lib, emu_signal_sources.items);
165190 }
166191}
167192