Commit 3e2f8233a8
Changed files (4)
lib
src
lib/std/zig/cross_target.zig
@@ -596,6 +596,7 @@ pub const CrossTarget = struct {
pub const Executor = union(enum) {
native,
+ rosetta,
qemu: []const u8,
wine: []const u8,
wasmtime: []const u8,
@@ -626,10 +627,13 @@ pub const CrossTarget = struct {
return .native;
}
}
- // If the OS match and OS is macOS and CPU is arm64, treat always as native
- // since we'll be running the foreign architecture tests using Rosetta2.
+ // If the OS match and OS is macOS and CPU is arm64, we can use Rosetta 2
+ // to emulate the foreign architecture.
if (os_match and os_tag == .macos and builtin.cpu.arch == .aarch64) {
- return .native;
+ return switch (cpu_arch) {
+ .x86_64 => .rosetta,
+ else => .unavailable,
+ };
}
// If the OS matches, we can use QEMU to emulate a foreign architecture.
lib/std/zig/CrossTarget.zig
@@ -643,10 +643,13 @@ pub fn getExternalExecutor(self: CrossTarget) Executor {
return .native;
}
}
- // If the OS match and OS is macOS and CPU is arm64, treat always as native
- // since we'll be running the foreign architecture tests using Rosetta2.
+ // If the OS match and OS is macOS and CPU is arm64, we can use Rosetta 2
+ // to emulate the foreign architecture.
if (os_match and os_tag == .macos and builtin.cpu.arch == .aarch64) {
- return .native;
+ return switch (cpu_arch) {
+ .x86_64 => .rosetta,
+ else => .unavailable,
+ };
}
// If the OS matches, we can use QEMU to emulate a foreign architecture.
lib/std/build.zig
@@ -2529,7 +2529,7 @@ pub const LibExeObjStep = struct {
}
}
} else switch (self.target.getExternalExecutor()) {
- .native, .unavailable => {},
+ .native, .rosetta, .unavailable => {},
.qemu => |bin_name| if (self.enable_qemu) qemu: {
const need_cross_glibc = self.target.isGnuLibC() and self.is_linking_libc;
const glibc_dir_arg = if (need_cross_glibc)
src/test.zig
@@ -1132,6 +1132,29 @@ pub const TestContext = struct {
.native => try argv.append(exe_path),
.unavailable => return, // Pass test.
+ .rosetta => if (builtin.os.tag == .macos) {
+ // Check based on official Apple docs.
+ // If sysctlbyname returns errno.ENOENT, then we are running a native process.
+ // Otherwise, if an error occurs then we are not native and there is no Rosetta available.
+ // Finally if OK, we are running a translated process via Rosetta.
+ // https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment
+ var ret: c_int = 0;
+ var size: usize = @sizeOf(c_int);
+ std.os.sysctlbynameZ(
+ "sysctl.proc_translated",
+ &ret,
+ &size,
+ null,
+ 0,
+ ) catch |err| switch (err) {
+ error.UnknownName => unreachable, // Native process, we should never trigger it as .rosetta.
+ else => return, // No Rosetta available, pass test.
+ };
+ try argv.append(exe_path);
+ } else {
+ return; // Rosetta not available, pass test.
+ },
+
.qemu => |qemu_bin_name| if (enable_qemu) {
// TODO Ability for test cases to specify whether to link libc.
const need_cross_glibc = false; // target.isGnuLibC() and self.is_linking_libc;