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 {...@@ -702,11 +702,20 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
702 try argv.append(try comp.get_libc_crt_file(arena, "crt.o"));702 try argv.append(try comp.get_libc_crt_file(arena, "crt.o"));
703 }703 }
704704
705 if (!is_obj and self.base.options.link_libc) {705 if (!is_obj) {
706 try argv.append(try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) {706 const system_libs = self.base.options.system_libs.keys();
707 .Static => "libc.a",707 for (system_libs) |link_lib| {
708 .Dynamic => unreachable,708 const full_name = try std.fmt.allocPrint(arena, "lib{s}.a", .{link_lib});
709 }));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 }
710 }719 }
711720
712 // Positional arguments to the linker such as object files.721 // 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 {...@@ -23,21 +23,21 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
23 try addCCArgs(comp, arena, &args, false);23 try addCCArgs(comp, arena, &args, false);
24 try addLibcBottomHalfIncludes(comp, arena, &args);24 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);
27 for (crt_src_files) |file_path| {27 for (crt_src_files) |file_path| {
28 try comp_sources.append(.{28 try crt_sources.append(.{
29 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{29 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
30 "libc", try sanitize(arena, file_path),30 "libc", try sanitize(arena, file_path),
31 }),31 }),
32 .extra_flags = args.items,32 .extra_flags = args.items,
33 });33 });
34 }34 }
35 try comp.build_crt_file("crt", .Obj, comp_sources.items);35 try comp.build_crt_file("crt", .Obj, crt_sources.items);
36 }36 }
3737
38 {38 {
39 // Compile WASI libc (sysroot).39 // 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
42 {42 {
43 // Compile dlmalloc.43 // Compile dlmalloc.
...@@ -54,7 +54,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {...@@ -54,7 +54,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
54 });54 });
5555
56 for (dlmalloc_src_files) |file_path| {56 for (dlmalloc_src_files) |file_path| {
57 try comp_sources.append(.{57 try libc_sources.append(.{
58 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{58 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
59 "libc", try sanitize(arena, file_path),59 "libc", try sanitize(arena, file_path),
60 }),60 }),
...@@ -70,7 +70,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {...@@ -70,7 +70,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
70 try addLibcBottomHalfIncludes(comp, arena, &args);70 try addLibcBottomHalfIncludes(comp, arena, &args);
7171
72 for (libc_bottom_half_src_files) |file_path| {72 for (libc_bottom_half_src_files) |file_path| {
73 try comp_sources.append(.{73 try libc_sources.append(.{
74 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{74 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
75 "libc", try sanitize(arena, file_path),75 "libc", try sanitize(arena, file_path),
76 }),76 }),
...@@ -80,63 +80,88 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {...@@ -80,63 +80,88 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
80 }80 }
8181
82 {82 {
83 // Compile emulated sources depending only on libc-bottom-half.83 // Compile libc-top-half.
84 var args = std.ArrayList([]const u8).init(arena);84 var args = std.ArrayList([]const u8).init(arena);
85 try addCCArgs(comp, arena, &args, true);85 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| {88 for (libc_top_half_src_files) |file_path| {
89 try comp_sources.append(.{89 try libc_sources.append(.{
90 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{90 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
91 "libc", try sanitize(arena, file_path),91 "libc", try sanitize(arena, file_path),
92 }),92 }),
93 .extra_flags = args.items,93 .extra_flags = args.items,
94 });94 });
95 }95 }
96 }
9697
97 for (emulated_getpid_src_files) |file_path| {98 try comp.build_crt_file("c", .Lib, libc_sources.items);
98 try comp_sources.append(.{99 }
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 }
105100
106 for (emulated_mman_src_files) |file_path| {101 {
107 try comp_sources.append(.{102 // Compile emulated process clocks.
108 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{103 var args = std.ArrayList([]const u8).init(arena);
109 "libc", try sanitize(arena, file_path),104 try addCCArgs(comp, arena, &args, true);
110 }),105 try addLibcBottomHalfIncludes(comp, arena, &args);
111 .extra_flags = args.items,106
112 });107 var emu_clocks_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
113 }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 });
114 }115 }
116 try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, emu_clocks_sources.items);
117 }
115118
116 {119 {
117 // Compile emulated signals (bottom-half).120 // Compile emulated getpid.
118 var args = std.ArrayList([]const u8).init(arena);121 var args = std.ArrayList([]const u8).init(arena);
119 try addCCArgs(comp, arena, &args, true);122 try addCCArgs(comp, arena, &args, true);
123 try addLibcBottomHalfIncludes(comp, arena, &args);
120124
121 for (emulated_signal_bottom_half_src_files) |file_path| {125 var emu_getpid_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
122 try comp_sources.append(.{126 for (emulated_getpid_src_files) |file_path| {
123 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{127 try emu_getpid_sources.append(.{
124 "libc", try sanitize(arena, file_path),128 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
125 }),129 "libc", try sanitize(arena, file_path),
126 .extra_flags = args.items,130 }),
127 });131 .extra_flags = args.items,
128 }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 });
129 }151 }
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
131 {159 {
132 // Compile emulated signals (top-half).
133 var args = std.ArrayList([]const u8).init(arena);160 var args = std.ArrayList([]const u8).init(arena);
134 try addCCArgs(comp, arena, &args, true);161 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| {163 for (emulated_signal_bottom_half_src_files) |file_path| {
139 try comp_sources.append(.{164 try emu_signal_sources.append(.{
140 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{165 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
141 "libc", try sanitize(arena, file_path),166 "libc", try sanitize(arena, file_path),
142 }),167 }),
...@@ -146,13 +171,13 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {...@@ -146,13 +171,13 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
146 }171 }
147172
148 {173 {
149 // Compile libc-top-half.
150 var args = std.ArrayList([]const u8).init(arena);174 var args = std.ArrayList([]const u8).init(arena);
151 try addCCArgs(comp, arena, &args, true);175 try addCCArgs(comp, arena, &args, true);
152 try addLibcTopHalfIncludes(comp, arena, &args);176 try addLibcTopHalfIncludes(comp, arena, &args);
177 try args.append("-D_WASI_EMULATED_SIGNAL");
153178
154 for (libc_top_half_src_files) |file_path| {179 for (emulated_signal_top_half_src_files) |file_path| {
155 try comp_sources.append(.{180 try emu_signal_sources.append(.{
156 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{181 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
157 "libc", try sanitize(arena, file_path),182 "libc", try sanitize(arena, file_path),
158 }),183 }),
...@@ -161,7 +186,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {...@@ -161,7 +186,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
161 }186 }
162 }187 }
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);
165 }190 }
166}191}
167192