Skip to content
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

machine returns x86_64 on Apple M2 (arm64) #25

Closed
AdamIsrael opened this issue Nov 13, 2022 · 3 comments
Closed

machine returns x86_64 on Apple M2 (arm64) #25

AdamIsrael opened this issue Nov 13, 2022 · 3 comments

Comments

@AdamIsrael
Copy link

Observed behavior: machine returns x86_64.
Expected behavior: machine returns arm64.

I recently switched from testing on an Intel Macbook Pro to an M2 chip, which is arm64. I noticed that platform-info is returning x86_64, though, when I'd expect it to return arm64. Am I just thinking about it wrong?

@sylvestre
Copy link
Contributor

no, you are probably correct :)
would you like to try to fix it?
should be easy

@AdamIsrael
Copy link
Author

AdamIsrael commented Nov 14, 2022

Yep, I'll take that challenge. 😀 It might actually be a problem with the libc crate, but I'll write a test to confirm and then see about patching it.

@AdamIsrael
Copy link
Author

TIL a bunch about Apple Silicon, M2, and universal binaries.

tl;dr: machine is technically correct in returning x86_64 because by default Rust is building ax86_64 binary, which is run through Rosetta on Apple Silicon. As such, I'll close this issue but leave some commentary that may be useful if anyone else stumbles across this.

To test this, I created a simple Rust application, using libc the same way platform-info does:

extern crate libc;
use self::libc::{uname, utsname};

use std::ffi::CStr;
use std::mem::MaybeUninit;

macro_rules! cstr2cow {
    ($v:expr) => {
        CStr::from_ptr($v.as_ref().as_ptr()).to_string_lossy()
    };
}

fn main() {
    unsafe {
        let mut uts = MaybeUninit::<utsname>::uninit();
        if uname(uts.as_mut_ptr()) != -1 {
            let uts = uts.assume_init();
            println!("{}", cstr2cow!(uts.machine));
        }
    }
}

It is possible to build a native arm64 binary:

rustup target add aarch64-apple-darwin
cargo build --target aarch64-apple-darwin

With this binary, machine returns arm64. There's still an open issue about linking a universal binary via cargo but in the meantime it can be done manually via and additional step:

lipo -create -output arch target/release/arch target/aarch64-apple-darwin/release/arch

This creates a Universal Binary containing both architectures:

$ file arch
arch: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64Mach-O 64-bit executable x86_64] [arm64:Mach-O 64-bit executable arm64Mach-O 64-bit executable arm64]
arch (for architecture x86_64):	Mach-O 64-bit executable x86_64
arch (for architecture arm64):	Mach-O 64-bit executable arm64

Running the Universal Binary results in this, which I presume is the default architecture

$ arch
arm64

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants