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
```
This commit is contained in:
Jakub Konka 2021-06-07 08:37:04 +02:00
parent 6f6182a5f3
commit 93a4403271
2 changed files with 113 additions and 79 deletions

View File

@ -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.

View File

@ -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,73 +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(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
"libc", try sanitize(arena, file_path),
}),
.extra_flags = args.items,
});
}
}
{
// Compile emulated sources depending only on libc-bottom-half.
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
try addLibcBottomHalfIncludes(comp, arena, &args);
for (emulated_process_clocks_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,
});
}
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,
});
}
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 signals (bottom-half).
var args = std.ArrayList([]const u8).init(arena);
try addCCArgs(comp, arena, &args, true);
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,
});
}
}
{
// 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(.{
try libc_sources.append(.{
.src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
"libc", try sanitize(arena, file_path),
}),
@ -152,7 +86,7 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
try addLibcTopHalfIncludes(comp, arena, &args);
for (libc_top_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),
}),
@ -161,7 +95,98 @@ pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
}
}
try comp.build_crt_file("c", .Lib, comp_sources.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);
{
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,
});
}
}
{
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);
}
}