diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig index 1de0d83aa7..71df1d9311 100644 --- 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 index cac0c78163..7eb5436ee5 100644 --- 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 index 1bafb1b8f7..21b701fc37 100644 --- 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,