From 5464392e116b590cc9c2b662e967bc544b7d0a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Tue, 14 Apr 2026 14:08:32 +0200 Subject: [PATCH] std.os: add APIs to determine whether Zig std requires libc for a target This is distinct from the question of whether the target formally considers libc to be the only stable syscall interface; for example, FreeBSD and NetBSD have stable syscalls, but we don't yet have syscall layers for them in std.os. --- lib/std/os.zig | 41 ++++++++++++++++++++++++++++++++++++++ src/Compilation/Config.zig | 11 +--------- test/src/StackTrace.zig | 5 +---- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/lib/std/os.zig b/lib/std/os.zig index 4f6643c3af..76364027fd 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1,4 +1,5 @@ const builtin = @import("builtin"); +const std = @import("std.zig"); const native_os = builtin.os.tag; pub const linux = @import("os/linux.zig"); @@ -8,6 +9,46 @@ pub const wasi = @import("os/wasi.zig"); pub const emscripten = @import("os/emscripten.zig"); pub const windows = @import("os/windows.zig"); +/// Returns whether the Zig standard library requires libc in order to interface +/// with the operating system on the given target. +pub fn targetRequiresLibC(target: *const std.Target) bool { + if (target.requiresLibC()) return true; + return switch (target.os.tag) { + .linux => switch (target.cpu.arch) { + // https://codeberg.org/ziglang/zig/issues/30940 + .alpha, + // https://codeberg.org/ziglang/zig/issues/30942 + .csky, + // https://codeberg.org/ziglang/zig/issues/30943 + .hppa, + .hppa64, + // https://codeberg.org/ziglang/zig/issues/30944 + .microblaze, + .microblazeel, + // https://codeberg.org/ziglang/zig/issues/30946 + .sh, + .sheb, + // https://codeberg.org/ziglang/zig/issues/30945 + .sparc, + // https://codeberg.org/ziglang/zig/issues/30947 + .xtensa, + .xtensaeb, + => true, + else => false, + }, + .freebsd => true, // https://codeberg.org/ziglang/zig/issues/30981 + .netbsd => true, // https://codeberg.org/ziglang/zig/issues/30980 + .openbsd => true, // https://codeberg.org/ziglang/zig/issues/30982 + else => false, + }; +} + +/// Returns whether the Zig standard library requires libc in order to interface +/// with the operating system on the current target. +pub fn requiresLibC() bool { + return targetRequiresLibC(&builtin.target); +} + test { _ = linux; if (native_os == .uefi) _ = uefi; diff --git a/src/Compilation/Config.zig b/src/Compilation/Config.zig index 3687db7b8e..b7f6df9096 100644 --- a/src/Compilation/Config.zig +++ b/src/Compilation/Config.zig @@ -234,19 +234,10 @@ pub fn resolve(options: Options) ResolveError!Config { break :b true; } if (options.link_libc) |x| break :b x; - switch (target.os.tag) { - // These targets don't require libc, but we don't yet have a syscall layer for them, - // so we default to linking libc for now. - .freebsd, - .netbsd, - .openbsd, - => break :b true, - else => {}, - } if (options.ensure_libc_on_non_freestanding and target.os.tag != .freestanding) break :b true; - break :b target.requiresLibC(); + break :b std.os.targetRequiresLibC(target); }; const link_mode = b: { diff --git a/test/src/StackTrace.zig b/test/src/StackTrace.zig index ae323c4497..9beb890460 100644 --- a/test/src/StackTrace.zig +++ b/test/src/StackTrace.zig @@ -58,10 +58,7 @@ fn addCaseTarget( .fuchsia => false, else => true, }; - const both_libc = switch (target.result.os.tag) { - .freebsd, .netbsd, .openbsd => false, - else => !target.result.requiresLibC(), - }; + const both_libc = !std.os.targetRequiresLibC(&target.result); // See `std.debug.StackIterator.fp_usability` logic. const fp_usability: enum { useless, unsafe, safe, ideal } = switch (target.result.cpu.arch) {