Skip to content

Rename --glibc-runtimes to --libc-runtimes and make it work with musl; add more targets to the module test matrix #23810

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 11, 2025
Merged
12 changes: 7 additions & 5 deletions lib/compiler/build_runner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,9 @@ pub fn main() !void {
// but it is handled by the parent process. The build runner
// only sees this flag.
graph.system_package_mode = true;
} else if (mem.eql(u8, arg, "--glibc-runtimes")) {
builder.glibc_runtimes_dir = nextArgOrFatal(args, &arg_idx);
} else if (mem.eql(u8, arg, "--libc-runtimes") or mem.eql(u8, arg, "--glibc-runtimes")) {
// --glibc-runtimes was the old name of the flag; kept for compatibility for now.
builder.libc_runtimes_dir = nextArgOrFatal(args, &arg_idx);
} else if (mem.eql(u8, arg, "--verbose-link")) {
builder.verbose_link = true;
} else if (mem.eql(u8, arg, "--verbose-air")) {
Expand Down Expand Up @@ -1279,9 +1280,10 @@ fn usage(b: *std.Build, out_stream: anytype) !void {
\\ -fqemu, -fno-qemu Integration with system-installed QEMU to execute
\\ foreign-architecture programs on Linux hosts
\\ (default: no)
\\ --glibc-runtimes [path] Enhances QEMU integration by providing glibc built
\\ for multiple foreign architectures, allowing
\\ execution of non-native programs that link with glibc.
\\ --libc-runtimes [path] Enhances QEMU integration by providing dynamic libc
\\ (e.g. glibc or musl) built for multiple foreign
\\ architectures, allowing execution of non-native
\\ programs that link with libc.
\\ -frosetta, -fno-rosetta Rely on Rosetta to execute x86_64 programs on
\\ ARM64 macOS hosts. (default: no)
\\ -fwasmtime, -fno-wasmtime Integration with system-installed wasmtime to
Expand Down
5 changes: 3 additions & 2 deletions lib/std/Build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ enable_wine: bool = false,
/// this will be the directory $glibc-build-dir/install/glibcs
/// Given the example of the aarch64 target, this is the directory
/// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`.
glibc_runtimes_dir: ?[]const u8 = null,
/// Also works for dynamic musl.
libc_runtimes_dir: ?[]const u8 = null,

dep_prefix: []const u8 = "",

Expand Down Expand Up @@ -390,7 +391,7 @@ fn createChildOnly(
.enable_rosetta = parent.enable_rosetta,
.enable_wasmtime = parent.enable_wasmtime,
.enable_wine = parent.enable_wine,
.glibc_runtimes_dir = parent.glibc_runtimes_dir,
.libc_runtimes_dir = parent.libc_runtimes_dir,
.dep_prefix = parent.fmt("{s}{s}.", .{ parent.dep_prefix, dep_name }),
.modules = .init(allocator),
.named_writefiles = .init(allocator),
Expand Down
44 changes: 21 additions & 23 deletions lib/std/Build/Step/Run.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1026,11 +1026,11 @@ fn runCommand(
}

const root_target = exe.rootModuleTarget();
const need_cross_glibc = root_target.isGnuLibC() and
exe.is_linking_libc;
const need_cross_libc = exe.is_linking_libc and
(root_target.isGnuLibC() or (root_target.isMuslLibC() and exe.linkage == .dynamic));
const other_target = exe.root_module.resolved_target.?.result;
switch (std.zig.system.getExternalExecutor(b.graph.host.result, &other_target, .{
.qemu_fixes_dl = need_cross_glibc and b.glibc_runtimes_dir != null,
.qemu_fixes_dl = need_cross_libc and b.libc_runtimes_dir != null,
.link_libc = exe.is_linking_libc,
})) {
.native, .rosetta => {
Expand All @@ -1047,31 +1047,29 @@ fn runCommand(
},
.qemu => |bin_name| {
if (b.enable_qemu) {
const glibc_dir_arg = if (need_cross_glibc)
b.glibc_runtimes_dir orelse
return failForeign(run, "--glibc-runtimes", argv[0], exe)
else
null;

try interp_argv.append(bin_name);

if (glibc_dir_arg) |dir| {
try interp_argv.append("-L");
try interp_argv.append(b.pathJoin(&.{
dir,
try std.zig.target.glibcRuntimeTriple(
b.allocator,
root_target.cpu.arch,
root_target.os.tag,
root_target.abi,
),
}));
if (need_cross_libc) {
if (b.libc_runtimes_dir) |dir| {
try interp_argv.append("-L");
try interp_argv.append(b.pathJoin(&.{
dir,
try if (root_target.isGnuLibC()) std.zig.target.glibcRuntimeTriple(
b.allocator,
root_target.cpu.arch,
root_target.os.tag,
root_target.abi,
) else if (root_target.isMuslLibC()) std.zig.target.muslRuntimeTriple(
b.allocator,
root_target.cpu.arch,
root_target.abi,
) else unreachable,
}));
} else return failForeign(run, "--libc-runtimes", argv[0], exe);
}

try interp_argv.appendSlice(argv);
} else {
return failForeign(run, "-fqemu", argv[0], exe);
}
} else return failForeign(run, "-fqemu", argv[0], exe);
},
.darling => |bin_name| {
if (b.enable_darling) {
Expand Down
38 changes: 10 additions & 28 deletions lib/std/Target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -838,7 +838,6 @@ pub const Abi = enum {
.aix => if (arch == .powerpc) .eabihf else .none,
.haiku => switch (arch) {
.arm,
.thumb,
.powerpc,
=> .eabihf,
else => .none,
Expand Down Expand Up @@ -877,22 +876,13 @@ pub const Abi = enum {
},
.freebsd => switch (arch) {
.arm,
.armeb,
.thumb,
.thumbeb,
.powerpc,
=> .eabihf,
// Soft float tends to be more common for MIPS.
.mips,
.mipsel,
=> .eabi,
else => .none,
},
.netbsd => switch (arch) {
.arm,
.armeb,
.thumb,
.thumbeb,
.powerpc,
=> .eabihf,
// Soft float tends to be more common for MIPS.
Expand All @@ -903,7 +893,6 @@ pub const Abi = enum {
},
.openbsd => switch (arch) {
.arm,
.thumb,
=> .eabi,
.powerpc,
=> .eabihf,
Expand Down Expand Up @@ -2209,7 +2198,6 @@ pub const DynamicLinker = struct {

.haiku => switch (cpu.arch) {
.arm,
.thumb,
.aarch64,
.m68k,
.powerpc,
Expand Down Expand Up @@ -2238,9 +2226,7 @@ pub const DynamicLinker = struct {

.linux => if (abi.isAndroid())
switch (cpu.arch) {
.arm,
.thumb,
=> if (abi == .androideabi) init("/system/bin/linker") else none,
.arm => if (abi == .androideabi) init("/system/bin/linker") else none,

.aarch64,
.riscv64,
Expand Down Expand Up @@ -2458,19 +2444,11 @@ pub const DynamicLinker = struct {

.freebsd => switch (cpu.arch) {
.arm,
.armeb,
.thumb,
.thumbeb,
.aarch64,
.mips,
.mipsel,
.mips64,
.mips64el,
.powerpc,
.powerpc64,
.powerpc64le,
.riscv64,
.sparc64,
.x86,
.x86_64,
=> initFmt("{s}/libexec/ld-elf.so.1", .{
Expand All @@ -2485,8 +2463,6 @@ pub const DynamicLinker = struct {
.netbsd => switch (cpu.arch) {
.arm,
.armeb,
.thumb,
.thumbeb,
.aarch64,
.aarch64_be,
.m68k,
Expand All @@ -2495,6 +2471,8 @@ pub const DynamicLinker = struct {
.mips64,
.mips64el,
.powerpc,
.powerpc64,
.riscv32,
.riscv64,
.sparc,
.sparc64,
Expand All @@ -2506,7 +2484,6 @@ pub const DynamicLinker = struct {

.openbsd => switch (cpu.arch) {
.arm,
.thumb,
.aarch64,
.mips64,
.mips64el,
Expand Down Expand Up @@ -2534,11 +2511,16 @@ pub const DynamicLinker = struct {
},

.illumos,
=> switch (cpu.arch) {
.x86,
.x86_64,
=> initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, .none) == 64) "64/" else ""}),
else => none,
},

.solaris,
=> switch (cpu.arch) {
.sparc,
.sparc64,
.x86,
.x86_64,
=> initFmt("/lib/{s}ld.so.1", .{if (ptrBitWidth_cpu_abi(cpu, .none) == 64) "64/" else ""}),
else => none,
Expand Down
1 change: 1 addition & 0 deletions lib/std/fs/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,7 @@ test "pwritev, preadv" {
test "setEndPos" {
// https://github.com/ziglang/zig/issues/20747 (open fd does not have write permission)
if (native_os == .wasi and builtin.link_libc) return error.SkipZigTest;
if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23806

var tmp = tmpDir(.{});
defer tmp.cleanup();
Expand Down
3 changes: 3 additions & 0 deletions lib/std/hash/xxhash.zig
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ fn testExpect(comptime H: type, seed: anytype, input: []const u8, expected: u64)

test "xxhash3" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807

const H = XxHash3;
// Non-Seeded Tests
Expand Down Expand Up @@ -814,6 +815,7 @@ test "xxhash3" {

test "xxhash3 smhasher" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807

const Test = struct {
fn do() !void {
Expand All @@ -827,6 +829,7 @@ test "xxhash3 smhasher" {

test "xxhash3 iterative api" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23807

const Test = struct {
fn do() !void {
Expand Down
2 changes: 2 additions & 0 deletions lib/std/os/linux/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const expectEqual = std.testing.expectEqual;
const fs = std.fs;

test "fallocate" {
if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23809

var tmp = std.testing.tmpDir(.{});
defer tmp.cleanup();

Expand Down
2 changes: 2 additions & 0 deletions lib/std/posix/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1377,6 +1377,8 @@ fn expectMode(dir: posix.fd_t, file: []const u8, mode: posix.mode_t) !void {
}

test "fchmodat smoke test" {
if (builtin.cpu.arch.isMIPS64() and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23808

if (!std.fs.has_executable_bit) return error.SkipZigTest;

var tmp = tmpDir(.{});
Expand Down
14 changes: 14 additions & 0 deletions lib/std/zig/target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ pub fn glibcRuntimeTriple(
};
}

/// Returns the subdirectory triple to be used to find the correct musl for the given `arch` and
/// `abi` in an installation directory.
///
/// `abi` must be a musl ABI, i.e. `.isMusl()`.
pub fn muslRuntimeTriple(
allocator: Allocator,
arch: std.Target.Cpu.Arch,
abi: std.Target.Abi,
) Allocator.Error![]const u8 {
assert(abi.isMusl());

return std.Target.linuxTripleSimple(allocator, arch, .linux, abi);
}

pub fn osArchName(target: std.Target) [:0]const u8 {
return switch (target.os.tag) {
.linux => switch (target.cpu.arch) {
Expand Down
1 change: 1 addition & 0 deletions test/behavior/basic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,7 @@ test "arrays and vectors with big integers" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_llvm and (builtin.abi == .gnuabin32 or builtin.abi == .muslabin32)) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/23805

inline for (.{ u65528, u65529, u65535 }) |Int| {
var a: [1]Int = undefined;
Expand Down
Loading
Loading