authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-05-03 06:32:15+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-05-03 10:54:36+02:00
logd2f92e1797cf30c2fb0993d7e09de73e496144f5
tree5ff3a50055955dc6fd586defaec9e180f22f6506
parentf6476e9caeadea0c0c6b18841dffcf72bffdd582
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

compiler: Link libunwind when linking glibc statically.

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

3 files changed, 14 insertions(+), 1 deletions(-)

src/Compilation/Config.zig+9-1
...@@ -129,6 +129,7 @@ pub const ResolveError = error{...@@ -129,6 +129,7 @@ pub const ResolveError = error{
129 LldCannotIncrementallyLink,129 LldCannotIncrementallyLink,
130 LtoRequiresLld,130 LtoRequiresLld,
131 SanitizeThreadRequiresLibCpp,131 SanitizeThreadRequiresLibCpp,
132 LibCRequiresLibUnwind,
132 LibCppRequiresLibUnwind,133 LibCppRequiresLibUnwind,
133 OsRequiresLibC,134 OsRequiresLibC,
134 LibCppRequiresLibC,135 LibCppRequiresLibC,
...@@ -312,7 +313,7 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -312,7 +313,7 @@ pub fn resolve(options: Options) ResolveError!Config {
312 break :b false;313 break :b false;
313 };314 };
314315
315 const link_libunwind = b: {316 var link_libunwind = b: {
316 if (link_libcpp and target_util.libCxxNeedsLibUnwind(target)) {317 if (link_libcpp and target_util.libCxxNeedsLibUnwind(target)) {
317 if (options.link_libunwind == false) return error.LibCppRequiresLibUnwind;318 if (options.link_libunwind == false) return error.LibCppRequiresLibUnwind;
318 break :b true;319 break :b true;
...@@ -379,6 +380,13 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -379,6 +380,13 @@ pub fn resolve(options: Options) ResolveError!Config {
379 break :b .static;380 break :b .static;
380 };381 };
381382
383 // This is done here to avoid excessive duplicated logic due to the complex dependencies between these options.
384 if (options.output_mode == .Exe and link_libc and target_util.libCNeedsLibUnwind(target, link_mode)) {
385 if (options.link_libunwind == false) return error.LibCRequiresLibUnwind;
386
387 link_libunwind = true;
388 }
389
382 const import_memory = options.import_memory orelse (options.output_mode == .Obj);390 const import_memory = options.import_memory orelse (options.output_mode == .Obj);
383 const export_memory = b: {391 const export_memory = b: {
384 if (link_mode == .dynamic) {392 if (link_mode == .dynamic) {
src/main.zig+1
...@@ -4206,6 +4206,7 @@ fn createModule(...@@ -4206,6 +4206,7 @@ fn createModule(
4206 error.LldCannotIncrementallyLink => fatal("self-hosted backends do not support linking with LLD", .{}),4206 error.LldCannotIncrementallyLink => fatal("self-hosted backends do not support linking with LLD", .{}),
4207 error.LtoRequiresLld => fatal("LTO requires using LLD", .{}),4207 error.LtoRequiresLld => fatal("LTO requires using LLD", .{}),
4208 error.SanitizeThreadRequiresLibCpp => fatal("thread sanitization is (for now) implemented in C++, so it requires linking libc++", .{}),4208 error.SanitizeThreadRequiresLibCpp => fatal("thread sanitization is (for now) implemented in C++, so it requires linking libc++", .{}),
4209 error.LibCRequiresLibUnwind => fatal("libc of the specified target requires linking libunwind", .{}),
4209 error.LibCppRequiresLibUnwind => fatal("libc++ requires linking libunwind", .{}),4210 error.LibCppRequiresLibUnwind => fatal("libc++ requires linking libunwind", .{}),
4210 error.OsRequiresLibC => fatal("the target OS requires using libc as the stable syscall interface", .{}),4211 error.OsRequiresLibC => fatal("the target OS requires using libc as the stable syscall interface", .{}),
4211 error.LibCppRequiresLibC => fatal("libc++ requires linking libc", .{}),4212 error.LibCppRequiresLibC => fatal("libc++ requires linking libc", .{}),
src/target.zig+4
...@@ -23,6 +23,10 @@ pub fn osRequiresLibC(target: std.Target) bool {...@@ -23,6 +23,10 @@ pub fn osRequiresLibC(target: std.Target) bool {
23 return target.os.requiresLibC();23 return target.os.requiresLibC();
24}24}
2525
26pub fn libCNeedsLibUnwind(target: std.Target, link_mode: std.builtin.LinkMode) bool {
27 return target.isGnuLibC() and link_mode == .static;
28}
29
26pub fn libCxxNeedsLibUnwind(target: std.Target) bool {30pub fn libCxxNeedsLibUnwind(target: std.Target) bool {
27 return switch (target.os.tag) {31 return switch (target.os.tag) {
28 .macos,32 .macos,