authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-05 17:47:27+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-05 23:33:12+02:00
log9e61a64033c4a8e085629fbf81c9238d51f17cc8
tree3f8683174d0e7eeb2196a5559d2e698ded78e733
parent5969d6180fb6cbff4016e57894e92e558ce61b83
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.zig.system: add OS checks for QEMU in getExternalExecutor()

FreeBSD doesn't support the same number of platforms as Linux, and even then, only has usermode emulation for a subset of its supported platforms. NetBSD's usermode emulation support is apparently just broken at the moment.

1 files changed, 56 insertions(+), 42 deletions(-)

lib/std/zig/system.zig+56-42
...@@ -81,53 +81,67 @@ pub fn getExternalExecutor(...@@ -81,53 +81,67 @@ pub fn getExternalExecutor(
81 // If the OS matches, we can use QEMU to emulate a foreign architecture.81 // If the OS matches, we can use QEMU to emulate a foreign architecture.
82 if (options.allow_qemu and os_match and (!cpu_ok or options.qemu_fixes_dl)) {82 if (options.allow_qemu and os_match and (!cpu_ok or options.qemu_fixes_dl)) {
83 return switch (candidate.cpu.arch) {83 return switch (candidate.cpu.arch) {
84 .aarch64 => Executor{ .qemu = "qemu-aarch64" },84 inline .aarch64,
85 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },85 .arm,
86 .arm, .thumb => Executor{ .qemu = "qemu-arm" },86 .riscv64,
87 .armeb, .thumbeb => Executor{ .qemu = "qemu-armeb" },87 .x86,
88 .hexagon => Executor{ .qemu = "qemu-hexagon" },88 .x86_64,
89 .loongarch64 => Executor{ .qemu = "qemu-loongarch64" },89 => |t| switch (candidate.os.tag) {
90 .m68k => Executor{ .qemu = "qemu-m68k" },90 .linux,
91 .mips => Executor{ .qemu = "qemu-mips" },91 .freebsd,
92 .mipsel => Executor{ .qemu = "qemu-mipsel" },92 => .{ .qemu = switch (t) {
93 .mips64 => Executor{93 .x86 => "qemu-i386",
94 .qemu = switch (candidate.abi) {94 .x86_64 => switch (candidate.abi) {
95 .gnuabin32, .muslabin32 => "qemu-mipsn32",95 .gnux32, .muslx32 => return bad_result,
96 else => "qemu-mips64",96 else => "qemu-x86_64",
97 },97 },
98 },98 else => "qemu-" ++ @tagName(t),
99 .mips64el => Executor{99 } },
100 .qemu = switch (candidate.abi) {100 else => bad_result,
101 .gnuabin32, .muslabin32 => "qemu-mipsn32el",
102 else => "qemu-mips64el",
103 },
104 },
105 .or1k => Executor{ .qemu = "qemu-or1k" },
106 .powerpc => Executor{ .qemu = "qemu-ppc" },
107 .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
108 .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
109 .riscv32 => Executor{ .qemu = "qemu-riscv32" },
110 .riscv64 => Executor{ .qemu = "qemu-riscv64" },
111 .s390x => Executor{ .qemu = "qemu-s390x" },
112 .sparc => Executor{
113 .qemu = if (candidate.cpu.has(.sparc, .v8plus))
114 "qemu-sparc32plus"
115 else
116 "qemu-sparc",
117 },101 },
118 .sparc64 => Executor{ .qemu = "qemu-sparc64" },102 inline .aarch64_be,
119 .x86 => Executor{ .qemu = "qemu-i386" },103 .armeb,
120 .x86_64 => switch (candidate.abi) {104 .hexagon,
121 .gnux32, .muslx32 => return bad_result,105 .loongarch64,
122 else => Executor{ .qemu = "qemu-x86_64" },106 .m68k,
107 .mips,
108 .mipsel,
109 .mips64,
110 .mips64el,
111 .or1k,
112 .powerpc,
113 .powerpc64,
114 .powerpc64le,
115 .riscv32,
116 .s390x,
117 .sparc,
118 .sparc64,
119 .thumb,
120 .thumbeb,
121 .xtensa,
122 => |t| switch (candidate.os.tag) {
123 .linux,
124 => .{ .qemu = switch (t) {
125 .powerpc => "qemu-ppc",
126 .powerpc64 => "qemu-ppc64",
127 .powerpc64le => "qemu-ppc64le",
128 .mips64, .mips64el => switch (candidate.abi) {
129 .gnuabin32, .muslabin32 => if (t == .mips64el) "qemu-mipsn32el" else "qemu-mipsn32",
130 else => "qemu-" ++ @tagName(t),
131 },
132 .sparc => if (candidate.cpu.has(.sparc, .v8plus)) "qemu-sparc32plus" else "qemu-sparc",
133 .thumb => "qemu-arm",
134 .thumbeb => "qemu-armeb",
135 else => "qemu-" ++ @tagName(t),
136 } },
137 else => bad_result,
123 },138 },
124 .xtensa => Executor{ .qemu = "qemu-xtensa" },
125 else => bad_result,139 else => bad_result,
126 };140 };
127 }141 }
128142
129 if (options.allow_wasmtime and candidate.cpu.arch.isWasm()) {143 if (options.allow_wasmtime and candidate.cpu.arch.isWasm()) {
130 return Executor{ .wasmtime = "wasmtime" };144 return .{ .wasmtime = "wasmtime" };
131 }145 }
132146
133 switch (candidate.os.tag) {147 switch (candidate.os.tag) {
...@@ -143,7 +157,7 @@ pub fn getExternalExecutor(...@@ -143,7 +157,7 @@ pub fn getExternalExecutor(
143 .x86_64 => host.cpu.arch == .x86_64,157 .x86_64 => host.cpu.arch == .x86_64,
144 else => false,158 else => false,
145 };159 };
146 return if (wine_supported) Executor{ .wine = "wine" } else bad_result;160 return if (wine_supported) .{ .wine = "wine" } else bad_result;
147 }161 }
148 return bad_result;162 return bad_result;
149 },163 },
...@@ -155,7 +169,7 @@ pub fn getExternalExecutor(...@@ -155,7 +169,7 @@ pub fn getExternalExecutor(
155 if (candidate.cpu.arch != host.cpu.arch) {169 if (candidate.cpu.arch != host.cpu.arch) {
156 return bad_result;170 return bad_result;
157 }171 }
158 return Executor{ .darling = "darling" };172 return .{ .darling = "darling" };
159 }173 }
160 return bad_result;174 return bad_result;
161 },175 },