aboutsummaryrefslogtreecommitdiff
path: root/src/main.zig
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 /src/main.zig
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
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig57
1 files changed, 54 insertions, 3 deletions
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";
+}