aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-11-05 18:44:12 -0500
committerGitHub <noreply@github.com>2023-11-05 18:44:12 -0500
commit702b809ea3e9b9dbdc1fd6efe9306442487e7103 (patch)
treebd639378ad2931013ff49789aadfc2104093261c
parentbec36aa7c028f2eaec94a2358f3e1326fcb9a30c (diff)
parentc893f837151d4764fd34911376836a01192b4d75 (diff)
downloadzig-702b809ea3e9b9dbdc1fd6efe9306442487e7103.tar.gz
zig-702b809ea3e9b9dbdc1fd6efe9306442487e7103.zip
Merge pull request #17815 from Luukdegram/wasm-no-entry
wasm-linker: implement `-fno-entry` and correctly pass `--shared` and `--pie` when given
-rw-r--r--doc/langref.html.in8
-rw-r--r--lib/std/Build/Step/Compile.zig25
-rw-r--r--lib/std/start.zig8
-rw-r--r--src/link/Wasm.zig33
-rw-r--r--src/main.zig57
-rw-r--r--test/link/elf.zig4
-rw-r--r--test/link/macho/entry/build.zig2
-rw-r--r--test/link/macho/entry_in_dylib/build.zig2
-rw-r--r--test/link/wasm/archive/build.zig3
-rw-r--r--test/link/wasm/basic-features/build.zig3
-rw-r--r--test/link/wasm/bss/build.zig6
-rw-r--r--test/link/wasm/export-data/build.zig3
-rw-r--r--test/link/wasm/export/build.zig9
-rw-r--r--test/link/wasm/extern-mangle/build.zig3
-rw-r--r--test/link/wasm/function-table/build.zig9
-rw-r--r--test/link/wasm/infer-features/build.zig3
-rw-r--r--test/link/wasm/producers/build.zig3
-rw-r--r--test/link/wasm/segments/build.zig3
-rw-r--r--test/link/wasm/shared-memory/build.zig149
-rw-r--r--test/link/wasm/stack_pointer/build.zig3
-rw-r--r--test/link/wasm/type/build.zig3
21 files changed, 209 insertions, 130 deletions
diff --git a/doc/langref.html.in b/doc/langref.html.in
index b3ae609a75..7e4d25a2fa 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -11336,12 +11336,12 @@ all your base are belong to us{#end_shell_samp#}
{#header_open|WebAssembly#}
<p>Zig supports building for WebAssembly out of the box.</p>
{#header_open|Freestanding#}
- <p>For host environments like the web browser and nodejs, build as a dynamic library using the freestanding
+ <p>For host environments like the web browser and nodejs, build as an executable using the freestanding
OS target. Here's an example of running Zig code compiled to WebAssembly with nodejs.</p>
- {#code_begin|lib|math#}
+ {#code_begin|exe|math#}
{#target_wasm#}
- {#link_mode_dynamic#}
- {#additonal_option|-rdynamic#}
+ {#additonal_option|-fno-entry#}
+ {#additonal_option|--export=add#}
extern fn print(i32) void;
export fn add(a: i32, b: i32) void {
diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig
index 9ede31c917..2d08541545 100644
--- a/lib/std/Build/Step/Compile.zig
+++ b/lib/std/Build/Step/Compile.zig
@@ -189,7 +189,8 @@ dll_export_fns: ?bool = null,
subsystem: ?std.Target.SubSystem = null,
-entry_symbol_name: ?[]const u8 = null,
+/// How the linker must handle the entry point of the executable.
+entry: Entry = .default,
/// List of symbols forced as undefined in the symbol table
/// thus forcing their resolution by the linker.
@@ -304,6 +305,18 @@ const FrameworkLinkInfo = struct {
weak: bool = false,
};
+const Entry = union(enum) {
+ /// Let the compiler decide whether to make an entry point and what to name
+ /// it.
+ default,
+ /// The executable will have no entry point.
+ disabled,
+ /// The executable will have an entry point with the default symbol name.
+ enabled,
+ /// The executable will have an entry point with the specified symbol name.
+ symbol_name: []const u8,
+};
+
pub const IncludeDir = union(enum) {
path: LazyPath,
path_system: LazyPath,
@@ -1418,9 +1431,13 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
try zig_args.append(try std.fmt.allocPrint(b.allocator, "-ofmt={s}", .{@tagName(ofmt)}));
}
- if (self.entry_symbol_name) |entry| {
- try zig_args.append("--entry");
- try zig_args.append(entry);
+ switch (self.entry) {
+ .default => {},
+ .disabled => try zig_args.append("-fno-entry"),
+ .enabled => try zig_args.append("-fentry"),
+ .symbol_name => |entry_name| {
+ try zig_args.append(try std.fmt.allocPrint(b.allocator, "-fentry={s}", .{entry_name}));
+ },
}
{
diff --git a/lib/std/start.zig b/lib/std/start.zig
index 7925ea9168..ff21ed8187 100644
--- a/lib/std/start.zig
+++ b/lib/std/start.zig
@@ -82,11 +82,15 @@ comptime {
.reactor => "_initialize",
.command => "_start",
};
- if (!@hasDecl(root, wasm_start_sym)) {
+ if (!@hasDecl(root, wasm_start_sym) and @hasDecl(root, "main")) {
+ // Only call main when defined. For WebAssembly it's allowed to pass `-fno-entry` in which
+ // case it's not required to provide an entrypoint such as main.
@export(wasi_start, .{ .name = wasm_start_sym });
}
} else if (native_arch.isWasm() and native_os == .freestanding) {
- if (!@hasDecl(root, start_sym_name)) @export(wasm_freestanding_start, .{ .name = start_sym_name });
+ // Only call main when defined. For WebAssembly it's allowed to pass `-fno-entry` in which
+ // case it's not required to provide an entrypoint such as main.
+ if (!@hasDecl(root, start_sym_name) and @hasDecl(root, "main")) @export(wasm_freestanding_start, .{ .name = start_sym_name });
} else if (native_os != .other and native_os != .freestanding) {
if (!@hasDecl(root, start_sym_name)) @export(_start, .{ .name = start_sym_name });
}
diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig
index fdac89f837..baa10be603 100644
--- a/src/link/Wasm.zig
+++ b/src/link/Wasm.zig
@@ -2817,15 +2817,11 @@ fn setupExports(wasm: *Wasm) !void {
}
fn setupStart(wasm: *Wasm) !void {
- const entry_name = wasm.base.options.entry orelse "_start";
+ // do not export entry point if user set none or no default was set.
+ const entry_name = wasm.base.options.entry orelse return;
const symbol_loc = wasm.findGlobalSymbol(entry_name) orelse {
- if (wasm.base.options.output_mode == .Exe) {
- if (wasm.base.options.wasi_exec_model == .reactor) return; // Not required for reactors
- } else {
- return; // No entry point needed for non-executable wasm files
- }
- log.err("Entry symbol '{s}' missing", .{entry_name});
+ log.err("Entry symbol '{s}' missing, use '-fno-entry' to suppress", .{entry_name});
return error.MissingSymbol;
};
@@ -4535,6 +4531,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
if (wasm.base.options.entry) |entry| {
try argv.append("--entry");
try argv.append(entry);
+ } else {
+ try argv.append("--no-entry");
}
// Increase the default stack size to a more reasonable value of 1MB instead of
@@ -4544,24 +4542,17 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
const arg = try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size});
try argv.append(arg);
- if (wasm.base.options.output_mode == .Exe) {
- if (wasm.base.options.wasi_exec_model == .reactor) {
- // Reactor execution model does not have _start so lld doesn't look for it.
- try argv.append("--no-entry");
- // Make sure "_initialize" and other used-defined functions are exported if this is WASI reactor.
- // If rdynamic is true, it will already be appended, so only verify if the user did not specify
- // the flag in which case, we ensure `--export-dynamic` is called.
- if (!wasm.base.options.rdynamic) {
- try argv.append("--export-dynamic");
- }
- }
- } else if (wasm.base.options.entry == null) {
- try argv.append("--no-entry"); // So lld doesn't look for _start.
- }
if (wasm.base.options.import_symbols) {
try argv.append("--allow-undefined");
}
+ if (wasm.base.options.output_mode == .Lib and wasm.base.options.link_mode == .Dynamic) {
+ try argv.append("--shared");
+ }
+ if (wasm.base.options.pie) {
+ try argv.append("--pie");
+ }
+
// XXX - TODO: add when wasm-ld supports --build-id.
// if (wasm.base.options.build_id) {
// try argv.append("--build-id=tree");
diff --git a/src/main.zig b/src/main.zig
index 385067f703..eb613a65f2 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -519,7 +519,9 @@ const usage_build_generic =
\\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
\\ --sysroot [path] Set the system root directory (usually /)
\\ --version [ver] Dynamic library semver
- \\ --entry [name] Set the entrypoint symbol name
+ \\ -fentry Enable entry point with default symbol name
+ \\ -fentry=[name] Override the entry point symbol name
+ \\ -fno-entry Do not output any entry point
\\ --force_undefined [name] Specify the symbol must be defined for the link to succeed
\\ -fsoname[=name] Override the default SONAME value
\\ -fno-soname Disable emitting a SONAME
@@ -845,6 +847,7 @@ fn buildOutputType(
var linker_import_symbols: bool = false;
var linker_import_table: bool = false;
var linker_export_table: bool = false;
+ var linker_force_entry: ?bool = null;
var linker_initial_memory: ?u64 = null;
var linker_max_memory: ?u64 = null;
var linker_shared_memory: bool = false;
@@ -1081,8 +1084,8 @@ fn buildOutputType(
subsystem = try parseSubSystem(args_iter.nextOrFatal());
} else if (mem.eql(u8, arg, "-O")) {
optimize_mode_string = args_iter.nextOrFatal();
- } else if (mem.eql(u8, arg, "--entry")) {
- entry = args_iter.nextOrFatal();
+ } else if (mem.startsWith(u8, arg, "-fentry=")) {
+ entry = arg["-fentry=".len..];
} else if (mem.eql(u8, arg, "--force_undefined")) {
try force_undefined_symbols.put(gpa, args_iter.nextOrFatal(), {});
} else if (mem.eql(u8, arg, "--stack")) {
@@ -1513,6 +1516,10 @@ fn buildOutputType(
}
} else if (mem.eql(u8, arg, "--import-memory")) {
linker_import_memory = true;
+ } else if (mem.eql(u8, arg, "-fentry")) {
+ linker_force_entry = true;
+ } else if (mem.eql(u8, arg, "-fno-entry")) {
+ linker_force_entry = false;
} else if (mem.eql(u8, arg, "--export-memory")) {
linker_export_memory = true;
} else if (mem.eql(u8, arg, "--import-symbols")) {
@@ -2144,6 +2151,8 @@ fn buildOutputType(
linker_import_table = true;
} else if (mem.eql(u8, arg, "--export-table")) {
linker_export_table = true;
+ } else if (mem.eql(u8, arg, "--no-entry")) {
+ linker_force_entry = false;
} else if (mem.eql(u8, arg, "--initial-memory")) {
const next_arg = linker_args_it.nextOrFatal();
linker_initial_memory = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| {
@@ -2606,6 +2615,23 @@ fn buildOutputType(
link_libcpp = true;
}
+ if (linker_force_entry) |force| {
+ if (!force) {
+ entry = null;
+ } else if (entry == null and output_mode == .Exe) {
+ entry = switch (target_info.target.ofmt) {
+ .coff => "wWinMainCRTStartup",
+ .macho => "_main",
+ .elf, .plan9 => "_start",
+ .wasm => defaultWasmEntryName(wasi_exec_model),
+ else => |tag| fatal("No default entry point available for output format {s}", .{@tagName(tag)}),
+ };
+ }
+ } else if (entry == null and target_info.target.isWasm() and output_mode == .Exe) {
+ // For WebAssembly the compiler defaults to setting the entry name when no flags are set.
+ entry = defaultWasmEntryName(wasi_exec_model);
+ }
+
if (target_info.target.ofmt == .coff) {
// Now that we know the target supports resources,
// we can add the res files as link objects.
@@ -2628,6 +2654,23 @@ fn buildOutputType(
if (single_threaded == null) {
single_threaded = true;
}
+ if (link_mode) |mode| {
+ if (mode == .Dynamic) {
+ if (linker_export_memory != null and linker_export_memory.?) {
+ fatal("flags '-dynamic' and '--export-memory' are incompatible", .{});
+ }
+ // User did not supply `--export-memory` which is incompatible with -dynamic, therefore
+ // set the flag to false to ensure it does not get enabled by default.
+ linker_export_memory = false;
+ }
+ }
+ if (wasi_exec_model != null and wasi_exec_model.? == .reactor) {
+ if (entry) |entry_name| {
+ if (!mem.eql(u8, "_initialize", entry_name)) {
+ fatal("the entry symbol of the reactor model must be '_initialize', but found '{s}'", .{entry_name});
+ }
+ }
+ }
if (linker_shared_memory) {
if (output_mode == .Obj) {
fatal("shared memory is not allowed in object files", .{});
@@ -7225,3 +7268,11 @@ fn createDependenciesModule(
try main_mod.deps.put(arena, "@dependencies", deps_mod);
return deps_mod;
}
+
+fn defaultWasmEntryName(exec_model: ?std.builtin.WasiExecModel) []const u8 {
+ const model = exec_model orelse .command;
+ if (model == .reactor) {
+ return "_initialize";
+ }
+ return "_start";
+}
diff --git a/test/link/elf.zig b/test/link/elf.zig
index 75cc34ec32..0402637348 100644
--- a/test/link/elf.zig
+++ b/test/link/elf.zig
@@ -658,7 +658,7 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {
const exe = addExecutable(b, "main", opts);
exe.addObject(a_o);
exe.addObject(b_o);
- exe.entry_symbol_name = "foo";
+ exe.entry = .{ .symbol_name = "foo" };
const check = exe.checkObject();
check.checkStart();
@@ -674,7 +674,7 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {
const exe = addExecutable(b, "other", opts);
exe.addObject(a_o);
exe.addObject(b_o);
- exe.entry_symbol_name = "bar";
+ exe.entry = .{ .symbol_name = "bar" };
const check = exe.checkObject();
check.checkStart();
diff --git a/test/link/macho/entry/build.zig b/test/link/macho/entry/build.zig
index fcba02cd9a..9f493d2715 100644
--- a/test/link/macho/entry/build.zig
+++ b/test/link/macho/entry/build.zig
@@ -20,7 +20,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
exe.linkLibC();
- exe.entry_symbol_name = "_non_main";
+ exe.entry = .{ .symbol_name = "_non_main" };
const check_exe = exe.checkObject();
diff --git a/test/link/macho/entry_in_dylib/build.zig b/test/link/macho/entry_in_dylib/build.zig
index 97ffa917b4..eb036abe6a 100644
--- a/test/link/macho/entry_in_dylib/build.zig
+++ b/test/link/macho/entry_in_dylib/build.zig
@@ -30,7 +30,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
exe.linkLibrary(lib);
exe.linkLibC();
- exe.entry_symbol_name = "_bootstrap";
+ exe.entry = .{ .symbol_name = "_bootstrap" };
exe.forceUndefinedSymbol("_my_main");
const check_exe = exe.checkObject();
diff --git a/test/link/wasm/archive/build.zig b/test/link/wasm/archive/build.zig
index d87b8e973e..3da284ac8f 100644
--- a/test/link/wasm/archive/build.zig
+++ b/test/link/wasm/archive/build.zig
@@ -15,12 +15,13 @@ pub fn build(b: *std.Build) void {
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
// The code in question will pull-in compiler-rt,
// and therefore link with its archive file.
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "main",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
});
+ lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
diff --git a/test/link/wasm/basic-features/build.zig b/test/link/wasm/basic-features/build.zig
index 703bd13feb..0566fbe2c1 100644
--- a/test/link/wasm/basic-features/build.zig
+++ b/test/link/wasm/basic-features/build.zig
@@ -4,7 +4,7 @@ pub const requires_stage2 = true;
pub fn build(b: *std.Build) void {
// Library with explicitly set cpu features
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "main.zig" },
.optimize = .Debug,
@@ -15,6 +15,7 @@ pub fn build(b: *std.Build) void {
.os_tag = .freestanding,
},
});
+ lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
diff --git a/test/link/wasm/bss/build.zig b/test/link/wasm/bss/build.zig
index e6cb9d4f3d..1bc059acde 100644
--- a/test/link/wasm/bss/build.zig
+++ b/test/link/wasm/bss/build.zig
@@ -14,12 +14,13 @@ pub fn build(b: *std.Build) void {
fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.OptimizeMode, is_safe: bool) void {
{
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize_mode,
});
+ lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
@@ -60,12 +61,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
// verify zero'd declaration is stored in bss for all optimization modes.
{
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib2.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize_mode,
});
+ lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
diff --git a/test/link/wasm/export-data/build.zig b/test/link/wasm/export-data/build.zig
index 7e3128aa76..58a8795390 100644
--- a/test/link/wasm/export-data/build.zig
+++ b/test/link/wasm/export-data/build.zig
@@ -9,12 +9,13 @@ pub fn build(b: *std.Build) void {
return;
}
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.optimize = .ReleaseSafe, // to make the output deterministic in address positions
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
});
+ lib.entry = .disabled;
lib.use_lld = false;
lib.export_symbol_names = &.{ "foo", "bar" };
lib.global_base = 0; // put data section at address 0 to make data symbols easier to parse
diff --git a/test/link/wasm/export/build.zig b/test/link/wasm/export/build.zig
index 5afe2df768..5c0306335d 100644
--- a/test/link/wasm/export/build.zig
+++ b/test/link/wasm/export/build.zig
@@ -13,31 +13,34 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
- const no_export = b.addSharedLibrary(.{
+ const no_export = b.addExecutable(.{
.name = "no-export",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
});
+ no_export.entry = .disabled;
no_export.use_llvm = false;
no_export.use_lld = false;
- const dynamic_export = b.addSharedLibrary(.{
+ const dynamic_export = b.addExecutable(.{
.name = "dynamic",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
});
+ dynamic_export.entry = .disabled;
dynamic_export.rdynamic = true;
dynamic_export.use_llvm = false;
dynamic_export.use_lld = false;
- const force_export = b.addSharedLibrary(.{
+ const force_export = b.addExecutable(.{
.name = "force",
.root_source_file = .{ .path = "main.zig" },
.optimize = optimize,
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
});
+ force_export.entry = .disabled;
force_export.export_symbol_names = &.{"foo"};
force_export.use_llvm = false;
force_export.use_lld = false;
diff --git a/test/link/wasm/extern-mangle/build.zig b/test/link/wasm/extern-mangle/build.zig
index 841d118efd..9f450c2dcc 100644
--- a/test/link/wasm/extern-mangle/build.zig
+++ b/test/link/wasm/extern-mangle/build.zig
@@ -11,12 +11,13 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize,
});
+ lib.entry = .disabled;
lib.import_symbols = true; // import `a` and `b`
lib.rdynamic = true; // export `foo`
diff --git a/test/link/wasm/function-table/build.zig b/test/link/wasm/function-table/build.zig
index 796ba670ad..906a255642 100644
--- a/test/link/wasm/function-table/build.zig
+++ b/test/link/wasm/function-table/build.zig
@@ -13,32 +13,35 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
- const import_table = b.addSharedLibrary(.{
+ const import_table = b.addExecutable(.{
.name = "import_table",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize,
});
+ import_table.entry = .disabled;
import_table.use_llvm = false;
import_table.use_lld = false;
import_table.import_table = true;
- const export_table = b.addSharedLibrary(.{
+ const export_table = b.addExecutable(.{
.name = "export_table",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize,
});
+ export_table.entry = .disabled;
export_table.use_llvm = false;
export_table.use_lld = false;
export_table.export_table = true;
- const regular_table = b.addSharedLibrary(.{
+ const regular_table = b.addExecutable(.{
.name = "regular_table",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize,
});
+ regular_table.entry = .disabled;
regular_table.use_llvm = false;
regular_table.use_lld = false;
diff --git a/test/link/wasm/infer-features/build.zig b/test/link/wasm/infer-features/build.zig
index 6264edfba9..5c7fa57447 100644
--- a/test/link/wasm/infer-features/build.zig
+++ b/test/link/wasm/infer-features/build.zig
@@ -17,7 +17,7 @@ pub fn build(b: *std.Build) void {
// Wasm library that doesn't have any features specified. This will
// infer its featureset from other linked object files.
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "main.zig" },
.optimize = .Debug,
@@ -27,6 +27,7 @@ pub fn build(b: *std.Build) void {
.os_tag = .freestanding,
},
});
+ lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.addObject(c_obj);
diff --git a/test/link/wasm/producers/build.zig b/test/link/wasm/producers/build.zig
index f541a1c8ec..e2bd95f450 100644
--- a/test/link/wasm/producers/build.zig
+++ b/test/link/wasm/producers/build.zig
@@ -14,12 +14,13 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize,
});
+ lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
diff --git a/test/link/wasm/segments/build.zig b/test/link/wasm/segments/build.zig
index d01c34f90d..21b954a902 100644
--- a/test/link/wasm/segments/build.zig
+++ b/test/link/wasm/segments/build.zig
@@ -13,12 +13,13 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize,
});
+ lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
diff --git a/test/link/wasm/shared-memory/build.zig b/test/link/wasm/shared-memory/build.zig
index cf84ad7528..a1d660d135 100644
--- a/test/link/wasm/shared-memory/build.zig
+++ b/test/link/wasm/shared-memory/build.zig
@@ -11,88 +11,87 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.OptimizeMode) void {
- {
- const lib = b.addSharedLibrary(.{
- .name = "lib",
- .root_source_file = .{ .path = "lib.zig" },
- .target = .{
- .cpu_arch = .wasm32,
- .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },
- .cpu_features_add = std.Target.wasm.featureSet(&.{ .atomics, .bulk_memory }),
- .os_tag = .freestanding,
- },
- .optimize = optimize_mode,
- });
- lib.use_lld = false;
- lib.strip = false;
- lib.import_memory = true;
- lib.export_memory = true;
- lib.shared_memory = true;
- lib.max_memory = 67108864;
- lib.single_threaded = false;
- lib.export_symbol_names = &.{"foo"};
+ const lib = b.addExecutable(.{
+ .name = "lib",
+ .root_source_file = .{ .path = "lib.zig" },
+ .target = .{
+ .cpu_arch = .wasm32,
+ .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },
+ .cpu_features_add = std.Target.wasm.featureSet(&.{ .atomics, .bulk_memory }),
+ .os_tag = .freestanding,
+ },
+ .optimize = optimize_mode,
+ });
+ lib.entry = .disabled;
+ lib.use_lld = false;
+ lib.strip = false;
+ lib.import_memory = true;
+ lib.export_memory = true;
+ lib.shared_memory = true;
+ lib.max_memory = 67108864;
+ lib.single_threaded = false;
+ lib.export_symbol_names = &.{"foo"};
- const check_lib = lib.checkObject();
+ const check_lib = lib.checkObject();
- check_lib.checkStart("Section import");
- check_lib.checkNext("entries 1");
- check_lib.checkNext("module env");
- check_lib.checkNext("name memory"); // ensure we are importing memory
+ check_lib.checkStart("Section import");
+ check_lib.checkNext("entries 1");
+ check_lib.checkNext("module env");
+ check_lib.checkNext("name memory"); // ensure we are importing memory
- check_lib.checkStart("Section export");
- check_lib.checkNext("entries 2");
- check_lib.checkNext("name memory"); // ensure we also export memory again
+ check_lib.checkStart("Section export");
+ check_lib.checkNext("entries 2");
+ check_lib.checkNext("name memory"); // ensure we also export memory again
- // This section *must* be emit as the start function is set to the index
- // of __wasm_init_memory
- // release modes will have the TLS segment optimized out in our test-case.
- // This means we won't have __wasm_init_memory in such case, and therefore
- // should also not have a section "start"
- if (optimize_mode == .Debug) {
- check_lib.checkStart("Section start");
- }
-
- // This section is only and *must* be emit when shared-memory is enabled
- // release modes will have the TLS segment optimized out in our test-case.
- if (optimize_mode == .Debug) {
- check_lib.checkStart("Section data_count");
- check_lib.checkNext("count 3");
- }
+ // This section *must* be emit as the start function is set to the index
+ // of __wasm_init_memory
+ // release modes will have the TLS segment optimized out in our test-case.
+ // This means we won't have __wasm_init_memory in such case, and therefore
+ // should also not have a section "start"
+ if (optimize_mode == .Debug) {
+ check_lib.checkStart("Section start");
+ }
- check_lib.checkStart("Section custom");
- check_lib.checkNext("name name");
- check_lib.checkNext("type function");
- if (optimize_mode == .Debug) {
- check_lib.checkNext("name __wasm_init_memory");
- }
- check_lib.checkNext("name __wasm_init_tls");
- check_lib.checkNext("type global");
+ // This section is only and *must* be emit when shared-memory is enabled
+ // release modes will have the TLS segment optimized out in our test-case.
+ if (optimize_mode == .Debug) {
+ check_lib.checkStart("Section data_count");
+ check_lib.checkNext("count 3");
+ }
- // In debug mode the symbol __tls_base is resolved to an undefined symbol
- // from the object file, hence its placement differs than in release modes
- // where the entire tls segment is optimized away, and tls_base will have
- // its original position.
- if (optimize_mode == .Debug) {
- check_lib.checkNext("name __tls_size");
- check_lib.checkNext("name __tls_align");
- check_lib.checkNext("name __tls_base");
- } else {
- check_lib.checkNext("name __tls_base");
- check_lib.checkNext("name __tls_size");
- check_lib.checkNext("name __tls_align");
- }
+ check_lib.checkStart("Section custom");
+ check_lib.checkNext("name name");
+ check_lib.checkNext("type function");
+ if (optimize_mode == .Debug) {
+ check_lib.checkNext("name __wasm_init_memory");
+ }
+ check_lib.checkNext("name __wasm_init_tls");
+ check_lib.checkNext("type global");
- check_lib.checkNext("type data_segment");
- if (optimize_mode == .Debug) {
- check_lib.checkNext("names 3");
- check_lib.checkNext("index 0");
- check_lib.checkNext("name .rodata");
- check_lib.checkNext("index 1");
- check_lib.checkNext("name .bss");
- check_lib.checkNext("index 2");
- check_lib.checkNext("name .tdata");
- }
+ // In debug mode the symbol __tls_base is resolved to an undefined symbol
+ // from the object file, hence its placement differs than in release modes
+ // where the entire tls segment is optimized away, and tls_base will have
+ // its original position.
+ if (optimize_mode == .Debug) {
+ check_lib.checkNext("name __tls_size");
+ check_lib.checkNext("name __tls_align");
+ check_lib.checkNext("name __tls_base");
+ } else {
+ check_lib.checkNext("name __tls_base");
+ check_lib.checkNext("name __tls_size");
+ check_lib.checkNext("name __tls_align");
+ }
- test_step.dependOn(&check_lib.step);
+ check_lib.checkNext("type data_segment");
+ if (optimize_mode == .Debug) {
+ check_lib.checkNext("names 3");
+ check_lib.checkNext("index 0");
+ check_lib.checkNext("name .rodata");
+ check_lib.checkNext("index 1");
+ check_lib.checkNext("name .bss");
+ check_lib.checkNext("index 2");
+ check_lib.checkNext("name .tdata");
}
+
+ test_step.dependOn(&check_lib.step);
}
diff --git a/test/link/wasm/stack_pointer/build.zig b/test/link/wasm/stack_pointer/build.zig
index ce724e5736..00ef54c052 100644
--- a/test/link/wasm/stack_pointer/build.zig
+++ b/test/link/wasm/stack_pointer/build.zig
@@ -13,12 +13,13 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize,
});
+ lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;
diff --git a/test/link/wasm/type/build.zig b/test/link/wasm/type/build.zig
index 7110f465f4..de574e36e4 100644
--- a/test/link/wasm/type/build.zig
+++ b/test/link/wasm/type/build.zig
@@ -13,12 +13,13 @@ pub fn build(b: *std.Build) void {
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
- const lib = b.addSharedLibrary(.{
+ const lib = b.addExecutable(.{
.name = "lib",
.root_source_file = .{ .path = "lib.zig" },
.target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
.optimize = optimize,
});
+ lib.entry = .disabled;
lib.use_llvm = false;
lib.use_lld = false;
lib.strip = false;