zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit d2f92e1797cf30c2fb0993d7e09de73e496144f5 (tree)
parent f6476e9caeadea0c0c6b18841dffcf72bffdd582
Author: Alex Rønne Petersen <alex@alexrp.com>
Date:   Sat,  3 May 2025 06:32:15 +0200

compiler: Link libunwind when linking glibc statically.

glibc's libc.a depends on the functions provided by libunwind.

Diffstat:
Msrc/Compilation/Config.zig | 10+++++++++-
Msrc/main.zig | 1+
Msrc/target.zig | 4++++
3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig @@ -129,6 +129,7 @@ pub const ResolveError = error{ LldCannotIncrementallyLink, LtoRequiresLld, SanitizeThreadRequiresLibCpp, + LibCRequiresLibUnwind, LibCppRequiresLibUnwind, OsRequiresLibC, LibCppRequiresLibC, @@ -312,7 +313,7 @@ pub fn resolve(options: Options) ResolveError!Config { break :b false; }; - const link_libunwind = b: { + var link_libunwind = b: { if (link_libcpp and target_util.libCxxNeedsLibUnwind(target)) { if (options.link_libunwind == false) return error.LibCppRequiresLibUnwind; break :b true; @@ -379,6 +380,13 @@ pub fn resolve(options: Options) ResolveError!Config { break :b .static; }; + // This is done here to avoid excessive duplicated logic due to the complex dependencies between these options. + if (options.output_mode == .Exe and link_libc and target_util.libCNeedsLibUnwind(target, link_mode)) { + if (options.link_libunwind == false) return error.LibCRequiresLibUnwind; + + link_libunwind = true; + } + const import_memory = options.import_memory orelse (options.output_mode == .Obj); const export_memory = b: { if (link_mode == .dynamic) { diff --git a/src/main.zig b/src/main.zig @@ -4206,6 +4206,7 @@ fn createModule( error.LldCannotIncrementallyLink => fatal("self-hosted backends do not support linking with LLD", .{}), 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", .{}), error.LibCppRequiresLibUnwind => fatal("libc++ requires linking libunwind", .{}), error.OsRequiresLibC => fatal("the target OS requires using libc as the stable syscall interface", .{}), error.LibCppRequiresLibC => fatal("libc++ requires linking libc", .{}), diff --git a/src/target.zig b/src/target.zig @@ -23,6 +23,10 @@ pub fn osRequiresLibC(target: std.Target) bool { return target.os.requiresLibC(); } +pub fn libCNeedsLibUnwind(target: std.Target, link_mode: std.builtin.LinkMode) bool { + return target.isGnuLibC() and link_mode == .static; +} + pub fn libCxxNeedsLibUnwind(target: std.Target) bool { return switch (target.os.tag) { .macos,