macoscommand-line-interfaceapple-m1fat

bad CPU type in executable error from the CLI Provider Perspective


I've my own open-source CLI tool called surmagic. In my latest update, I've built on a different machine, which has an M1 CPU. Before and after publishing I've tested on that machine, via installing the homebrew. And it works as expected. After a while, I've tested on another machine that has an Intel CPU. And, I've been faced with this error:

> surmagic --version
zsh: bad CPU type in executable: surmagic

I know what this error means from other libraries that I've used before, but the problem is how to solve this error as a CLI tool provider is another question.

I need help with this. How to solve this forever.


Solution

  • Solution

    First, check your Mac's architecture via the command below:

    > arch
    i386
    

    if your result is i386 like in my case. Then check the application binary's architecture via the command below:

    > cd /usr/local/bin
    > lipo -info surmagic
    Non-fat file: surmagic is architecture: arm64
    

    if this result is arm64 non-fat, like in my case, then you need to build a FAT executable for your library.

    Follow the steps below:

    How to Build a Universal Binary

    Firstly, make sure that you are using the correct version of Xcode/Swift:

    > xcrun swift build --version
    Swift Package Manager - Swift 5.5.0
    

    Note: If this is not Swift 5.3 or greater, use xcode-select -s to switch to the Xcode 12 beta.

    Now, when compiling your package, specify both architectures to compile a Universal Binary (the real irony here is my CLI tool actually makes FAT libraries for Xcode project):

    > xcrun swift build -c release --arch arm64 --arch x86_64
    

    To verify that your built binary contains both architectures, you can use the lipo -info command to inspect a binary and confirm:

    > lipo -info .build/apple/Products/Release/surmagic
    Architectures in the fat file: .build/apple/Products/Release/surmagic are: x86_64 arm64
    

    If successful, you should see both x86_64 and arm64.