authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-05-04 01:53:51+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-05-04 01:53:51+02:00
logdffd18f133972cb2e1b0695340f8104c3cd3b5f8
tree34b2ed2832ae2f4f772fd12d07eb5500d557b6a5
parentf4e9846bca69e20f907384cdad43b86a3aae1fb2
parentd2f92e1797cf30c2fb0993d7e09de73e496144f5
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #23752 from alexrp/static-native-glibc

compiler: Allow linking native glibc statically

3 files changed, 20 insertions(+), 7 deletions(-)

src/Compilation/Config.zig+14-6
...@@ -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,8 +313,8 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -312,8 +313,8 @@ 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.libcNeedsLibUnwind(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;
319 }320 }
...@@ -352,7 +353,7 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -352,7 +353,7 @@ pub fn resolve(options: Options) ResolveError!Config {
352 break :b .static;353 break :b .static;
353 }354 }
354 if (explicitly_exe_or_dyn_lib and link_libc and355 if (explicitly_exe_or_dyn_lib and link_libc and
355 (target.isGnuLibC() or target_util.osRequiresLibC(target)))356 (target_util.osRequiresLibC(target) or (target.isGnuLibC() and !options.resolved_target.is_native_abi)))
356 {357 {
357 if (options.link_mode == .static) return error.LibCRequiresDynamicLinking;358 if (options.link_mode == .static) return error.LibCRequiresDynamicLinking;
358 break :b .dynamic;359 break :b .dynamic;
...@@ -367,11 +368,11 @@ pub fn resolve(options: Options) ResolveError!Config {...@@ -367,11 +368,11 @@ pub fn resolve(options: Options) ResolveError!Config {
367368
368 if (options.link_mode) |link_mode| break :b link_mode;369 if (options.link_mode) |link_mode| break :b link_mode;
369370
370 if (explicitly_exe_or_dyn_lib and link_libc and371 if (explicitly_exe_or_dyn_lib and link_libc and options.resolved_target.is_native_abi and
371 options.resolved_target.is_native_abi and target.abi.isMusl())372 (target.isGnuLibC() or target.isMuslLibC()))
372 {373 {
373 // If targeting the system's native ABI and the system's libc is374 // If targeting the system's native ABI and the system's libc is
374 // musl, link dynamically by default.375 // glibc or musl, link dynamically by default.
375 break :b .dynamic;376 break :b .dynamic;
376 }377 }
377378
...@@ -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+5-1
...@@ -23,7 +23,11 @@ pub fn osRequiresLibC(target: std.Target) bool {...@@ -23,7 +23,11 @@ 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) bool {26pub fn libCNeedsLibUnwind(target: std.Target, link_mode: std.builtin.LinkMode) bool {
27 return target.isGnuLibC() and link_mode == .static;
28}
29
30pub fn libCxxNeedsLibUnwind(target: std.Target) bool {
27 return switch (target.os.tag) {31 return switch (target.os.tag) {
28 .macos,32 .macos,
29 .ios,33 .ios,