Thomas Tempelmann
Thomas Tempelmann

Reputation: 12043

Determine CPU type / architecture in macOS

With the upcoming Apple Silicon hardware, some apps may want to determine whether the CPU is an Intel or Apple one.

Which APIs and system calls can provide that information?

As @MarkSetchell points out, sysctl -a can provide some information. For the DTK (macOS 11b3) it returns:

machdep.cpu.brand_string: Apple processor

OTOH, Apple's System Profiler.app shows:

Processor Name: Apple A12Z Bionic

I like to have a similar result, i.e. rather "Apple A12Z Bionic" than "Apple processor".

A quick search for "Apple A12Z Bionic" on the system volume shows that it appears somewhere in the "dyld_shared_cache_arm64e", but not inside System Profiler.app, which suggests that this string is delivered by a framework function rather than being hard-coded in the Profiler app. Therefore, I hope to find the system call that provides this more descriptive name.

Upvotes: 3

Views: 5019

Answers (3)

water_ak47
water_ak47

Reputation: 1306

Working for me.

Reference Sources: https://developer.apple.com/forums/thread/678914

var systeminfo = utsname()
uname(&systeminfo)
let machine = withUnsafeBytes(of: &systeminfo.machine) {bufPtr->String in
    let data = Data(bufPtr)
    if let lastIndex = data.lastIndex(where: {$0 != 0}) {
        return String(data: data[0...lastIndex], encoding: .isoLatin1)!
    } else {
        return String(data: data, encoding: .isoLatin1)!
    }
}
// arm64
print(machine)

The result:

enter image description here

Upvotes: 1

ingconti
ingconti

Reputation: 11636

my two cents for swift 5.x (tested in Mac, iOS and.... (NDA rules..))

func CPUType() ->Int {
    
    var cputype = UInt32(0)
    var size = cputype.byteWidth
    
    let result = sysctlbyname("hw.cputype", &cputype, &size, nil, 0)
    if result == -1 {
        if (errno == ENOENT){
            return 0
        }
        return -1
    }
    return Int(cputype)
}


let CPU_ARCH_MASK          = 0xff      // mask for architecture bits

let CPU_TYPE_X86           = cpu_type_t(7)
let CPU_TYPE_ARM           = cpu_type_t(12)

func CPUType() ->String {
    
    let type: Int = CPUType()
    if type == -1 {
        return "error in CPU type"
    }
    
    let cpu_arch            = type & CPU_ARCH_MASK
    
    if cpu_arch == CPU_TYPE_X86{
        return "X86"
    }
    
    if cpu_arch == CPU_TYPE_ARM{
        return "ARM"
    }
    
    return "unknown"
}

// accessory f.:

extension FixedWidthInteger {
    var byteWidth:Int {
        return self.bitWidth/UInt8.bitWidth
    }
    static var byteWidth:Int {
        return Self.bitWidth/UInt8.bitWidth
    }
}

Upvotes: 5

Thomas Tempelmann
Thomas Tempelmann

Reputation: 12043

As comments suggest, the sysctl function can be used to identify the CPU type (but not deliver the "Apple A12Z Bionic" text I am seeking).

Here's a code sample:

#include <stdio.h>
#include <sys/sysctl.h>

int main(int argc, const char * argv[]) {
    uint32_t cputype = 0;
    size_t size = sizeof (cputype);
    int res = sysctlbyname ("hw.cputype", &cputype, &size, NULL, 0);
    if (res) {
        printf ("error: %d\n", res);
    } else {
        printf ("cputype: 0x%08x\n", cputype);
    }
    return 0;
}

This prints 0x00000007 on an Intel Mac, and 0x0100000c on a Apple Silicon DTK (as of BigSur beta 3).

The 01 in the most significant byte is a flag indicating an ARM 64 bit system. Defined in machine.h:

#define CPU_ARCH_MASK           0xff000000      /* mask for architecture bits */
#define CPU_ARCH_ABI64          0x01000000      /* 64 bit ABI */
#define CPU_ARCH_ABI64_32       0x02000000      /* ABI for 64-bit hardware with 32-bit types; LP32 */

#define CPU_TYPE_X86            ((cpu_type_t) 7)
#define CPU_TYPE_ARM            ((cpu_type_t) 12)
#define CPU_TYPE_ARM64          (CPU_TYPE_ARM | CPU_ARCH_ABI64)
#define CPU_TYPE_ARM64_32       (CPU_TYPE_ARM | CPU_ARCH_ABI64_32)

See also: macOS CPU Architecture (Ohanaware)

Upvotes: 1

Related Questions