aboutsummaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2025-10-29 18:04:11 -0400
committerJacob Young <jacobly0@users.noreply.github.com>2025-10-29 18:15:09 -0400
commit0834e696f75d8477e5bc7a2dc49e7d10800039bc (patch)
tree4bc63d8cf74e7fd9dfe7ab06bde9dd16bba62306 /src/main.zig
parent40901440a620caf1849c627cff0d3a96eda273f5 (diff)
downloadzig-0834e696f75d8477e5bc7a2dc49e7d10800039bc.tar.gz
zig-0834e696f75d8477e5bc7a2dc49e7d10800039bc.zip
Elf2: start implementing dynamic linking
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/main.zig b/src/main.zig
index 03d42ba898..dd8c4695e6 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -558,6 +558,7 @@ const usage_build_generic =
\\ --enable-new-dtags Use the new behavior for dynamic tags (RUNPATH)
\\ --disable-new-dtags Use the old behavior for dynamic tags (RPATH)
\\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
+ \\ --no-dynamic-linker Do not set any dynamic interpreter path
\\ --sysroot [path] Set the system root directory (usually /)
\\ --version [ver] Dynamic library semver
\\ -fentry Enable entry point with default symbol name
@@ -1301,6 +1302,8 @@ fn buildOutputType(
mod_opts.optimize_mode = parseOptimizeMode(rest);
} else if (mem.eql(u8, arg, "--dynamic-linker")) {
create_module.dynamic_linker = args_iter.nextOrFatal();
+ } else if (mem.eql(u8, arg, "--no-dynamic-linker")) {
+ create_module.dynamic_linker = "";
} else if (mem.eql(u8, arg, "--sysroot")) {
const next_arg = args_iter.nextOrFatal();
create_module.sysroot = next_arg;
@@ -2418,6 +2421,11 @@ fn buildOutputType(
mem.eql(u8, arg, "-dynamic-linker"))
{
create_module.dynamic_linker = linker_args_it.nextOrFatal();
+ } else if (mem.eql(u8, arg, "-I") or
+ mem.eql(u8, arg, "--no-dynamic-linker") or
+ mem.eql(u8, arg, "-no-dynamic-linker"))
+ {
+ create_module.dynamic_linker = "";
} else if (mem.eql(u8, arg, "-E") or
mem.eql(u8, arg, "--export-dynamic") or
mem.eql(u8, arg, "-export-dynamic"))
@@ -3191,13 +3199,14 @@ fn buildOutputType(
const resolved_soname: ?[]const u8 = switch (soname) {
.yes => |explicit| explicit,
.no => null,
- .yes_default_value => switch (target.ofmt) {
- .elf => if (have_version)
+ .yes_default_value => if (create_module.resolved_options.output_mode == .Lib and
+ create_module.resolved_options.link_mode == .dynamic and target.ofmt == .elf)
+ if (have_version)
try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ root_name, version.major })
else
- try std.fmt.allocPrint(arena, "lib{s}.so", .{root_name}),
- else => null,
- },
+ try std.fmt.allocPrint(arena, "lib{s}.so", .{root_name})
+ else
+ null,
};
const emit_bin_resolved: Compilation.CreateOptions.Emit = switch (emit_bin) {
@@ -3646,7 +3655,11 @@ fn buildOutputType(
try test_exec_args.append(arena, try std.fmt.allocPrint(arena, "-mcpu={s}", .{mcpu}));
}
if (create_module.dynamic_linker) |dl| {
- try test_exec_args.appendSlice(arena, &.{ "--dynamic-linker", dl });
+ if (dl.len > 0) {
+ try test_exec_args.appendSlice(arena, &.{ "--dynamic-linker", dl });
+ } else {
+ try test_exec_args.append(arena, "--no-dynamic-linker");
+ }
}
try test_exec_args.append(arena, null); // placeholder for the path of the emitted C source file
}
@@ -3793,7 +3806,7 @@ fn createModule(
.result = target,
.is_native_os = target_query.isNativeOs(),
.is_native_abi = target_query.isNativeAbi(),
- .is_explicit_dynamic_linker = !target_query.dynamic_linker.eql(.none),
+ .is_explicit_dynamic_linker = target_query.dynamic_linker != null,
};
};
@@ -3965,6 +3978,7 @@ fn createModule(
error.WasiExecModelRequiresWasi => fatal("only WASI OS targets support execution model", .{}),
error.SharedMemoryIsWasmOnly => fatal("only WebAssembly CPU targets support shared memory", .{}),
error.ObjectFilesCannotShareMemory => fatal("object files cannot share memory", .{}),
+ error.ObjectFilesCannotSpecifyDynamicLinker => fatal("object files cannot specify --dynamic-linker", .{}),
error.SharedMemoryRequiresAtomicsAndBulkMemory => fatal("shared memory requires atomics and bulk_memory CPU features", .{}),
error.ThreadsRequireSharedMemory => fatal("threads require shared memory", .{}),
error.EmittingLlvmModuleRequiresLlvmBackend => fatal("emitting an LLVM module requires using the LLVM backend", .{}),
@@ -3973,6 +3987,7 @@ fn createModule(
error.EmittingBinaryRequiresLlvmLibrary => fatal("producing machine code via LLVM requires using the LLVM library", .{}),
error.LldIncompatibleObjectFormat => fatal("using LLD to link {s} files is unsupported", .{@tagName(target.ofmt)}),
error.LldCannotIncrementallyLink => fatal("self-hosted backends do not support linking with LLD", .{}),
+ error.LldCannotSpecifyDynamicLinkerForSharedLibraries => fatal("LLD does not support --dynamic-linker on shared libraries", .{}),
error.LtoRequiresLld => fatal("LTO requires using LLD", .{}),
error.SanitizeThreadRequiresLibCpp => fatal("thread sanitization is (for now) implemented in C++, so it requires linking libc++", .{}),
error.LibCRequiresLibUnwind => fatal("libc of the specified target requires linking libunwind", .{}),
@@ -3984,6 +3999,7 @@ fn createModule(
error.TargetCannotStaticLinkExecutables => fatal("static linking of executables unavailable on the specified target", .{}),
error.LibCRequiresDynamicLinking => fatal("libc of the specified target requires dynamic linking", .{}),
error.SharedLibrariesRequireDynamicLinking => fatal("using shared libraries requires dynamic linking", .{}),
+ error.DynamicLinkingWithLldRequiresSharedLibraries => fatal("dynamic linking with lld requires at least one shared library", .{}),
error.ExportMemoryAndDynamicIncompatible => fatal("exporting memory is incompatible with dynamic linking", .{}),
error.DynamicLibraryPrecludesPie => fatal("dynamic libraries cannot be position independent executables", .{}),
error.TargetRequiresPie => fatal("the specified target requires position independent executables", .{}),