From 259b7c3f3fc3f8902f8aa4e6e7539df271073a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 30 Jul 2025 18:58:47 +0200 Subject: [PATCH 1/2] std.Target: pull Os.requiresLibC() up to Target --- lib/std/Target.zig | 101 ++++++++++++++++++++++----------------------- src/target.zig | 2 +- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index c75e2b51fb..ccc8ab79d8 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -697,57 +697,6 @@ pub const Os = struct { => |field| @field(os.version_range, @tagName(field)).isAtLeast(ver), }; } - - /// On Darwin, we always link libSystem which contains libc. - /// Similarly on FreeBSD and NetBSD we always link system libc - /// since this is the stable syscall interface. - pub fn requiresLibC(os: Os) bool { - return switch (os.tag) { - .aix, - .driverkit, - .macos, - .ios, - .tvos, - .watchos, - .visionos, - .dragonfly, - .openbsd, - .haiku, - .solaris, - .illumos, - .serenity, - => true, - - .linux, - .windows, - .freebsd, - .netbsd, - .freestanding, - .fuchsia, - .ps3, - .zos, - .rtems, - .cuda, - .nvcl, - .amdhsa, - .ps4, - .ps5, - .mesa3d, - .contiki, - .amdpal, - .hermit, - .hurd, - .wasi, - .emscripten, - .uefi, - .opencl, - .opengl, - .vulkan, - .plan9, - .other, - => false, - }; - } }; pub const aarch64 = @import("Target/aarch64.zig"); @@ -2055,6 +2004,56 @@ pub inline fn isWasiLibC(target: *const Target) bool { return target.os.tag == .wasi and target.abi.isMusl(); } +/// Does this target require linking libc? This may be the case if the target has an unstable +/// syscall interface, for example. +pub fn requiresLibC(target: *const Target) bool { + return switch (target.os.tag) { + .aix, + .driverkit, + .macos, + .ios, + .tvos, + .watchos, + .visionos, + .dragonfly, + .openbsd, + .haiku, + .solaris, + .illumos, + .serenity, + => true, + + .linux + .windows, + .freebsd, + .netbsd, + .freestanding, + .fuchsia, + .ps3, + .zos, + .rtems, + .cuda, + .nvcl, + .amdhsa, + .ps4, + .ps5, + .mesa3d, + .contiki, + .amdpal, + .hermit, + .hurd, + .wasi, + .emscripten, + .uefi, + .opencl, + .opengl, + .vulkan, + .plan9, + .other, + => false, + }; +} + pub const DynamicLinker = struct { /// Contains the memory used to store the dynamic linker path. This field /// should not be used directly. See `get` and `set`. This field exists so diff --git a/src/target.zig b/src/target.zig index ad83414c23..dbcfe341a4 100644 --- a/src/target.zig +++ b/src/target.zig @@ -20,7 +20,7 @@ pub fn cannotDynamicLink(target: *const std.Target) bool { /// Similarly on FreeBSD and NetBSD we always link system libc /// since this is the stable syscall interface. pub fn osRequiresLibC(target: *const std.Target) bool { - return target.os.requiresLibC(); + return target.requiresLibC(); } pub fn libCNeedsLibUnwind(target: *const std.Target, link_mode: std.builtin.LinkMode) bool { From 03facba4963abd142985c9617ca38de46b1615f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Wed, 30 Jul 2025 18:59:08 +0200 Subject: [PATCH 2/2] std.Target: require libc for Android API levels prior to 29 Emulated TLS depends on libc pthread functions. Closes #24589. --- lib/std/Target.zig | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/std/Target.zig b/lib/std/Target.zig index ccc8ab79d8..fb9149c759 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -2023,7 +2023,12 @@ pub fn requiresLibC(target: *const Target) bool { .serenity, => true, - .linux + // Android API levels prior to 29 did not have native TLS support. For these API levels, TLS + // is implemented through calls to `__emutls_get_address`. We provide this function in + // compiler-rt, but it's implemented by way of `pthread_key_create` et al, so linking libc + // is required. + .linux => target.abi.isAndroid() and target.os.version_range.linux.android < 29, + .windows, .freebsd, .netbsd,