aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Rønne Petersen <alex@alexrp.com>2025-08-04 17:59:47 +0200
committerGitHub <noreply@github.com>2025-08-04 17:59:47 +0200
commit163e9ce7d9a1ff4e2cb6bbdac7fbdfdd0b751ade (patch)
tree223e633a61aff34d31648316a57e41722aeb1c5f
parent9b509dad30a9e7fa6f59e656c0df2b7e265b400a (diff)
parent03facba4963abd142985c9617ca38de46b1615f1 (diff)
downloadzig-163e9ce7d9a1ff4e2cb6bbdac7fbdfdd0b751ade.tar.gz
zig-163e9ce7d9a1ff4e2cb6bbdac7fbdfdd0b751ade.zip
Merge pull request #24629 from alexrp/android-requires-libc
`std.Target`: require libc for Android API levels prior to 29
-rw-r--r--lib/std/Target.zig106
-rw-r--r--src/target.zig2
2 files changed, 56 insertions, 52 deletions
diff --git a/lib/std/Target.zig b/lib/std/Target.zig
index 59cf7bda01..f960a4bb4c 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,61 @@ 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,
+
+ // 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,
+ .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 ba7cca6391..b0fc3dd070 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 {