From 6d5002028a2fe71b67d8106b30c6602bc8e44121 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Wed, 19 May 2021 21:59:21 +0200 Subject: cc,wasi: link compiled WASI libc with wasm-ld --- lib/std/target.zig | 3 --- lib/std/zig.zig | 11 ++++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'lib/std') diff --git a/lib/std/target.zig b/lib/std/target.zig index fb54d2e18f..aa65ca669e 100644 --- a/lib/std/target.zig +++ b/lib/std/target.zig @@ -1307,9 +1307,6 @@ pub const Target = struct { } pub fn libPrefix_cpu_arch_abi(cpu_arch: Cpu.Arch, abi: Abi) [:0]const u8 { - if (cpu_arch.isWasm()) { - return ""; - } switch (abi) { .msvc => return "", else => return "lib", diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 911edbd21c..61e7ca5545 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -160,8 +160,17 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro }, .wasm => switch (options.output_mode) { .Exe => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.exeFileExt() }), + .Lib => { + switch (options.link_mode orelse .Static) { + .Static => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ + target.libPrefix(), root_name, + }), + .Dynamic => return std.fmt.allocPrint(allocator, "{s}{s}.wasm", .{ + target.libPrefix(), root_name, + }), + } + }, .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.oFileExt() }), - .Lib => return std.fmt.allocPrint(allocator, "{s}.wasm", .{root_name}), }, .c => return std.fmt.allocPrint(allocator, "{s}.c", .{root_name}), .spirv => return std.fmt.allocPrint(allocator, "{s}.spv", .{root_name}), -- cgit v1.2.3 From 3a5d0f7700dc28b523e17ba461874b807786b939 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 20 May 2021 10:27:35 +0200 Subject: wasm: link dynamically by default when targeting wasm This matches the behaviour of other languages and leaves us the ability to create actual static Wasm archives with ``` zig build-lib -static some.zig ``` which can then be combined with other Wasm object files and linked into either a Wasm lib or executable using `wasm-ld`. Update langref to reflect the fact we now ship WASI libc. --- doc/langref.html.in | 2 ++ lib/std/zig.zig | 4 +--- src/Compilation.zig | 19 +++++++++---------- src/main.zig | 6 ++++++ src/target.zig | 1 + src/wasi_libc.zig | 2 +- 6 files changed, 20 insertions(+), 14 deletions(-) (limited to 'lib/std') diff --git a/doc/langref.html.in b/doc/langref.html.in index 618cd953f1..d67f97f4c6 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -10280,6 +10280,7 @@ Operating Systems: ps4 elfiamcu tvos + wasi watchos mesa3d contiki @@ -10348,6 +10349,7 @@ Available libcs: sparc-linux-gnu sparcv9-linux-gnu wasm32-freestanding-musl + wasm32-wasi-musl x86_64-linux-gnu x86_64-linux-gnux32 x86_64-linux-musl diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 61e7ca5545..083803e0c8 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -165,9 +165,7 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro .Static => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{ target.libPrefix(), root_name, }), - .Dynamic => return std.fmt.allocPrint(allocator, "{s}{s}.wasm", .{ - target.libPrefix(), root_name, - }), + .Dynamic => return std.fmt.allocPrint(allocator, "{s}.wasm", .{root_name}), } }, .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.oFileExt() }), diff --git a/src/Compilation.zig b/src/Compilation.zig index 1d1f2f01b8..2af35b7d66 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -770,8 +770,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .Lib => is_dyn_lib, .Exe => true, }; - const needs_c_symbols = !options.skip_linker_dependencies and - (is_exe_or_dyn_lib or (options.target.isWasm() and options.output_mode != .Obj)); + + const needs_c_symbols = !options.skip_linker_dependencies and is_exe_or_dyn_lib; const comp: *Compilation = comp: { // For allocations that have the same lifetime as Compilation. This arena is used only during this @@ -1418,7 +1418,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { }, }); } - if (comp.wantBuildWASILibcSysrootFromSource()) { + if (comp.wantBuildWasiLibcSysrootFromSource()) { try comp.work_queue.write(&[_]Job{.{ .wasi_libc_sysroot = {} }}); } if (comp.wantBuildMinGWFromSource()) { @@ -1462,7 +1462,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { // Once it is capable this condition should be removed. if (build_options.is_stage1) { if (comp.bin_file.options.include_compiler_rt) { - if (is_exe_or_dyn_lib or comp.getTarget().isWasm()) { + if (is_exe_or_dyn_lib) { try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} }); } else { try comp.work_queue.writeItem(.{ .compiler_rt_obj = {} }); @@ -2147,7 +2147,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor }; }, .wasi_libc_sysroot => { - wasi_libc.buildWASILibcSysroot(self) catch |err| { + wasi_libc.buildWasiLibcSysroot(self) catch |err| { // TODO Surface more error details. try self.setMiscFailure( .wasi_libc_sysroot, @@ -3263,7 +3263,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.wantBuildWasiLibcSysrootFromSource()) { return comp.crt_files.get(basename).?.full_object_path; } @@ -3303,7 +3303,7 @@ fn wantBuildMuslFromSource(comp: Compilation) bool { !comp.getTarget().isWasm(); } -fn wantBuildWASILibcSysrootFromSource(comp: Compilation) bool { +fn wantBuildWasiLibcSysrootFromSource(comp: Compilation) bool { return comp.wantBuildLibCFromSource() and comp.getTarget().isWasm(); } @@ -3610,11 +3610,10 @@ fn buildOutputFromZig( }; const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len]; const target = comp.getTarget(); - const fixed_output_mode = if (target.cpu.arch.isWasm()) .Obj else output_mode; const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{ .root_name = root_name, .target = target, - .output_mode = fixed_output_mode, + .output_mode = output_mode, }); defer comp.gpa.free(bin_basename); @@ -3629,7 +3628,7 @@ fn buildOutputFromZig( .target = target, .root_name = root_name, .root_pkg = &root_pkg, - .output_mode = fixed_output_mode, + .output_mode = output_mode, .thread_pool = comp.thread_pool, .libc_installation = comp.bin_file.options.libc_installation, .emit_bin = emit_bin, diff --git a/src/main.zig b/src/main.zig index b388329508..86d017b3b7 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1548,6 +1548,12 @@ fn buildOutputType( link_libcpp = true; } + if (cross_target.getCpuArch().isWasm() and output_mode == .Lib and link_mode == null) { + // If link_mode is unspecified, always link as dynamic library when targeting Wasm, + // so that wasm-ld is invoked rather than standard archiver. + link_mode = .Dynamic; + } + // Now that we have target info, we can find out if any of the system libraries // are part of libc or libc++. We remove them from the list and communicate their // existence via flags instead. diff --git a/src/target.zig b/src/target.zig index cb6aecf645..2a3b1d858c 100644 --- a/src/target.zig +++ b/src/target.zig @@ -146,6 +146,7 @@ pub fn libcNeedsLibUnwind(target: std.Target) bool { .watchos, .tvos, .freestanding, + .wasi, // Wasm/WASI currently doesn't offer support for libunwind, so don't link it. => false, .windows => target.abi != .msvc, diff --git a/src/wasi_libc.zig b/src/wasi_libc.zig index e2d3652928..1fba312265 100644 --- a/src/wasi_libc.zig +++ b/src/wasi_libc.zig @@ -6,7 +6,7 @@ const Compilation = @import("Compilation.zig"); const build_options = @import("build_options"); const target_util = @import("target.zig"); -pub fn buildWASILibcSysroot(comp: *Compilation) !void { +pub fn buildWasiLibcSysroot(comp: *Compilation) !void { if (!build_options.have_llvm) { return error.ZigCompilerNotBuiltWithLLVMExtensions; } -- cgit v1.2.3