Programmatically detect Apple Silicon (i.e. ARM CPU)

Is it possible to programmatically determine, at run time, if an App is running on Apple Silicon? If so, how?

Replies

https://developer.apple.com/documentation/apple_silicon/about_the_rosetta_translation_environment

int processIsTranslated() {
int ret = 0;
sizet size = sizeof(ret);
if (sysctlbyname("sysctl.proc
translated", &ret, &size, NULL, 0) == -1)
{
if (errno == ENOENT)
return 0;
return -1;
}
return ret;
}
my 2 cents for swift:


Code Block
// swift implementation of ADC call
let NATIVE_EXECUTION        =  Int32(0)
let EMULATED_EXECUTION      =  Int32(1)
let UNKONWN_EXECUTION       = -Int32(1)
func processIsTranslated() ->Int32 {
    var ret = Int32(0)
    var size = ret.byteWidth
  let result = sysctlbyname("sysctl.proc_translated", &ret, &size, nil, 0)
    if result == -1 {
        if (errno == ENOENT){
            return 0
        }
        return -1
    }
    return ret
}
func processIsTranslatedStr() -> String {
        switch processIsTranslated() {
        case NATIVE_EXECUTION:
            return "native"
        case EMULATED_EXECUTION:
            return "rosetta"
        default:
            return "unkown"
        }
}



```
    
Found it.. well for the iOS app case anyway: https://developer.apple.com/documentation/foundation/processinfo/3608556-isiosapponmac
The "sysctl.proc_translated" suggestions are only going to tell you if the an Intel (x86_64) binary is running via Rosetta 2 on an Apple Silicon based Mac.

If you want to check the architecture at runtime, you can use uname(_:) to do just that. I added an extension to ProcessInfo to provide a bit more of a modern API for it:

Code Block swift
extension ProcessInfo {
/// Returns a `String` representing the machine hardware name or nil if there was an error invoking `uname(_:)` or decoding the response.
///
/// Return value is the equivalent to running `$ uname -m` in shell.
var machineHardwareName: String? {
var sysinfo = utsname()
let result = uname(&sysinfo)
guard result == EXIT_SUCCESS else { return nil }
let data = Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN))
guard let identifier = String(bytes: data, encoding: .ascii) else { return nil }
return identifier.trimmingCharacters(in: .controlCharacters)
}
}


On an Apple Silicon based mac, this will return arm64 whereas on an Intel one it'll be x86_64. Be aware however that if your program is running in Rosetta then it'll return x86_64 again... You could combine it with the other solutions to check that it's also not running as translated to overcome that edge case.

Since I needed to detect this stuff for a project, I made a Swift package that includes your solutions and improves upon them and makes them easier to use.

It can also detect multiple architectures to have a more general usage.

https://github.com/ITzTravelInTime/SwiftCPUDetect

Here is some example usage of my package


import Foundation
import SwiftCPUDetect

print("Is my app running with Rosetta? \((AppExecutionMode.current() == .emulated) ? "Yes" : "No")")

print("My app is running using the \(CpuArchitecture.current()?.rawValue ?? "[Can't detect architecture]") architecture")

print("My computer is running using the \(CpuArchitecture.actualCurrent()?.rawValue ?? "[Can't detect architecture]") architecture")