authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-20 10:27:35+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-05-20 16:54:00+02:00
log3a5d0f7700dc28b523e17ba461874b807786b939
tree3f5c2aa584c7b652fa410cb6b9a214af300b963b
parentf291b8b9bccf223418eaeea2efc8ca87851e59eb

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.

6 files changed, 20 insertions(+), 14 deletions(-)

doc/langref.html.in+2
...@@ -10280,6 +10280,7 @@ Operating Systems:...@@ -10280,6 +10280,7 @@ Operating Systems:
10280 ps410280 ps4
10281 elfiamcu10281 elfiamcu
10282 tvos10282 tvos
10283 wasi
10283 watchos10284 watchos
10284 mesa3d10285 mesa3d
10285 contiki10286 contiki
...@@ -10348,6 +10349,7 @@ Available libcs:...@@ -10348,6 +10349,7 @@ Available libcs:
10348 sparc-linux-gnu10349 sparc-linux-gnu
10349 sparcv9-linux-gnu10350 sparcv9-linux-gnu
10350 wasm32-freestanding-musl10351 wasm32-freestanding-musl
10352 wasm32-wasi-musl
10351 x86_64-linux-gnu10353 x86_64-linux-gnu
10352 x86_64-linux-gnux3210354 x86_64-linux-gnux32
10353 x86_64-linux-musl</code></pre>10355 x86_64-linux-musl</code></pre>
lib/std/zig.zig+1-3
...@@ -165,9 +165,7 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro...@@ -165,9 +165,7 @@ pub fn binNameAlloc(allocator: *std.mem.Allocator, options: BinNameOptions) erro
165 .Static => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{165 .Static => return std.fmt.allocPrint(allocator, "{s}{s}.a", .{
166 target.libPrefix(), root_name,166 target.libPrefix(), root_name,
167 }),167 }),
168 .Dynamic => return std.fmt.allocPrint(allocator, "{s}{s}.wasm", .{168 .Dynamic => return std.fmt.allocPrint(allocator, "{s}.wasm", .{root_name}),
169 target.libPrefix(), root_name,
170 }),
171 }169 }
172 },170 },
173 .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.oFileExt() }),171 .Obj => return std.fmt.allocPrint(allocator, "{s}{s}", .{ root_name, target.oFileExt() }),
src/Compilation.zig+9-10
...@@ -770,8 +770,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -770,8 +770,8 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
770 .Lib => is_dyn_lib,770 .Lib => is_dyn_lib,
771 .Exe => true,771 .Exe => true,
772 };772 };
773 const needs_c_symbols = !options.skip_linker_dependencies and773
774 (is_exe_or_dyn_lib or (options.target.isWasm() and options.output_mode != .Obj));774 const needs_c_symbols = !options.skip_linker_dependencies and is_exe_or_dyn_lib;
775775
776 const comp: *Compilation = comp: {776 const comp: *Compilation = comp: {
777 // For allocations that have the same lifetime as Compilation. This arena is used only during this777 // 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 {...@@ -1418,7 +1418,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1418 },1418 },
1419 });1419 });
1420 }1420 }
1421 if (comp.wantBuildWASILibcSysrootFromSource()) {1421 if (comp.wantBuildWasiLibcSysrootFromSource()) {
1422 try comp.work_queue.write(&[_]Job{.{ .wasi_libc_sysroot = {} }});1422 try comp.work_queue.write(&[_]Job{.{ .wasi_libc_sysroot = {} }});
1423 }1423 }
1424 if (comp.wantBuildMinGWFromSource()) {1424 if (comp.wantBuildMinGWFromSource()) {
...@@ -1462,7 +1462,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -1462,7 +1462,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
1462 // Once it is capable this condition should be removed.1462 // Once it is capable this condition should be removed.
1463 if (build_options.is_stage1) {1463 if (build_options.is_stage1) {
1464 if (comp.bin_file.options.include_compiler_rt) {1464 if (comp.bin_file.options.include_compiler_rt) {
1465 if (is_exe_or_dyn_lib or comp.getTarget().isWasm()) {1465 if (is_exe_or_dyn_lib) {
1466 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });1466 try comp.work_queue.writeItem(.{ .compiler_rt_lib = {} });
1467 } else {1467 } else {
1468 try comp.work_queue.writeItem(.{ .compiler_rt_obj = {} });1468 try comp.work_queue.writeItem(.{ .compiler_rt_obj = {} });
...@@ -2147,7 +2147,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor...@@ -2147,7 +2147,7 @@ pub fn performAllTheWork(self: *Compilation) error{ TimerUnsupported, OutOfMemor
2147 };2147 };
2148 },2148 },
2149 .wasi_libc_sysroot => {2149 .wasi_libc_sysroot => {
2150 wasi_libc.buildWASILibcSysroot(self) catch |err| {2150 wasi_libc.buildWasiLibcSysroot(self) catch |err| {
2151 // TODO Surface more error details.2151 // TODO Surface more error details.
2152 try self.setMiscFailure(2152 try self.setMiscFailure(
2153 .wasi_libc_sysroot,2153 .wasi_libc_sysroot,
...@@ -3263,7 +3263,7 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []cons...@@ -3263,7 +3263,7 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: *Allocator, basename: []cons
3263 if (comp.wantBuildGLibCFromSource() or3263 if (comp.wantBuildGLibCFromSource() or
3264 comp.wantBuildMuslFromSource() or3264 comp.wantBuildMuslFromSource() or
3265 comp.wantBuildMinGWFromSource() or3265 comp.wantBuildMinGWFromSource() or
3266 comp.wantBuildWASILibcSysrootFromSource())3266 comp.wantBuildWasiLibcSysrootFromSource())
3267 {3267 {
3268 return comp.crt_files.get(basename).?.full_object_path;3268 return comp.crt_files.get(basename).?.full_object_path;
3269 }3269 }
...@@ -3303,7 +3303,7 @@ fn wantBuildMuslFromSource(comp: Compilation) bool {...@@ -3303,7 +3303,7 @@ fn wantBuildMuslFromSource(comp: Compilation) bool {
3303 !comp.getTarget().isWasm();3303 !comp.getTarget().isWasm();
3304}3304}
33053305
3306fn wantBuildWASILibcSysrootFromSource(comp: Compilation) bool {3306fn wantBuildWasiLibcSysrootFromSource(comp: Compilation) bool {
3307 return comp.wantBuildLibCFromSource() and comp.getTarget().isWasm();3307 return comp.wantBuildLibCFromSource() and comp.getTarget().isWasm();
3308}3308}
33093309
...@@ -3610,11 +3610,10 @@ fn buildOutputFromZig(...@@ -3610,11 +3610,10 @@ fn buildOutputFromZig(
3610 };3610 };
3611 const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];3611 const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
3612 const target = comp.getTarget();3612 const target = comp.getTarget();
3613 const fixed_output_mode = if (target.cpu.arch.isWasm()) .Obj else output_mode;
3614 const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{3613 const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{
3615 .root_name = root_name,3614 .root_name = root_name,
3616 .target = target,3615 .target = target,
3617 .output_mode = fixed_output_mode,3616 .output_mode = output_mode,
3618 });3617 });
3619 defer comp.gpa.free(bin_basename);3618 defer comp.gpa.free(bin_basename);
36203619
...@@ -3629,7 +3628,7 @@ fn buildOutputFromZig(...@@ -3629,7 +3628,7 @@ fn buildOutputFromZig(
3629 .target = target,3628 .target = target,
3630 .root_name = root_name,3629 .root_name = root_name,
3631 .root_pkg = &root_pkg,3630 .root_pkg = &root_pkg,
3632 .output_mode = fixed_output_mode,3631 .output_mode = output_mode,
3633 .thread_pool = comp.thread_pool,3632 .thread_pool = comp.thread_pool,
3634 .libc_installation = comp.bin_file.options.libc_installation,3633 .libc_installation = comp.bin_file.options.libc_installation,
3635 .emit_bin = emit_bin,3634 .emit_bin = emit_bin,
src/main.zig+6
...@@ -1548,6 +1548,12 @@ fn buildOutputType(...@@ -1548,6 +1548,12 @@ fn buildOutputType(
1548 link_libcpp = true;1548 link_libcpp = true;
1549 }1549 }
15501550
1551 if (cross_target.getCpuArch().isWasm() and output_mode == .Lib and link_mode == null) {
1552 // If link_mode is unspecified, always link as dynamic library when targeting Wasm,
1553 // so that wasm-ld is invoked rather than standard archiver.
1554 link_mode = .Dynamic;
1555 }
1556
1551 // Now that we have target info, we can find out if any of the system libraries1557 // Now that we have target info, we can find out if any of the system libraries
1552 // are part of libc or libc++. We remove them from the list and communicate their1558 // are part of libc or libc++. We remove them from the list and communicate their
1553 // existence via flags instead.1559 // existence via flags instead.
src/target.zig+1
...@@ -146,6 +146,7 @@ pub fn libcNeedsLibUnwind(target: std.Target) bool {...@@ -146,6 +146,7 @@ pub fn libcNeedsLibUnwind(target: std.Target) bool {
146 .watchos,146 .watchos,
147 .tvos,147 .tvos,
148 .freestanding,148 .freestanding,
149 .wasi, // Wasm/WASI currently doesn't offer support for libunwind, so don't link it.
149 => false,150 => false,
150151
151 .windows => target.abi != .msvc,152 .windows => target.abi != .msvc,
src/wasi_libc.zig+1-1
...@@ -6,7 +6,7 @@ const Compilation = @import("Compilation.zig");...@@ -6,7 +6,7 @@ const Compilation = @import("Compilation.zig");
6const build_options = @import("build_options");6const build_options = @import("build_options");
7const target_util = @import("target.zig");7const target_util = @import("target.zig");
88
9pub fn buildWASILibcSysroot(comp: *Compilation) !void {9pub fn buildWasiLibcSysroot(comp: *Compilation) !void {
10 if (!build_options.have_llvm) {10 if (!build_options.have_llvm) {
11 return error.ZigCompilerNotBuiltWithLLVMExtensions;11 return error.ZigCompilerNotBuiltWithLLVMExtensions;
12 }12 }