8

Build macOS ARM apps in Xcode without a real macOS ARM SDK

 3 years ago
source link: https://worthdoingbadly.com/sim-macos-arm-sdk/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Here’s a script that modifies Xcode’s macOS SDK to build for ARM. You can use this to find code that won’t compile on ARM, to get a head start on porting before Apple releases Xcode for an ARM Mac.

Screenshot saying

What it’s for

An app built with this SDK won’t actually work on ARM.

The script literally just replaces every instance of x86_64 in the current macOS SDK with arm64e, so most structures and methods won’t match a real ARM macOS.

This is only intended to help you identify code and third-party libraries that won’t compile on ARM.

Thanks

Thanks to @stroughtonsmith, who discovered how to modify Xcode to build for ARM macOS.

How to use

First, generate the SDK. I tested this with Xcode 11.0 on macOS 10.15.5, but it’ll likely work for newer Xcode versions.

Clone the generator script to a path without spaces, and generate the modified SDK:

git clone https://github.com/zhuowei/fake-arm-macOS-sdk
cd fake-arm-macOS-sdk
./makesdk.sh

This will print something like

Deleting and recopying /Users/zhuowei/Documents/fake-arm-macOS-sdk/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
Copying some iOS files over
Editing tbd files
Editing headers
Editing Swift modules

Edit your Xcode project to use this SDK:

  • Base SDK: the path of the generated SDK.
  • Architectures: arm64e
  • Valid architectures: x86_64 arm64e
Screenshot of Xcode with the above settings

Product -> Clean Build Folder, then Product -> Build.

If it works, you’ll end up with an app that shows this when opened:

Screenshot saying

Alternatively, you can also compile on the command line:

clang -target arm64e-apple-macosx10.15.0 -isysroot <path to MacOSX.sdk> hello.c
swiftc -target arm64e-apple-macosx10.15.0 -sdk <path to MacOSX.sdk> hello.swift

Known issues

  • ./makesdk.sh won’t work in a path with spaces.
  • Apps built with this (probably) won’t work on an actual ARM macOS.
  • Deprecated methods are still present, since this is just a find-and-replace on the current macOS SDK.

Apple is known to remove deprecated APIs during transitions; for example, Catalyst doesn’t include any deprecated methods from iOS, and Carbon was never made available to 64-bit.

You should look at the compiler warnings and remove uses of deprecated APIs.

  • Core Data doesn’t compile:
error: Cannot run cdtool because either it or the simulator runtime cannot be found. ('(null)' : 'Cannot find a simulator runtime for platform (null).') [0]
  • LLVM’s Sanitizers are not supported.

Example: auditing iTerm 2’s source for ARM incompatibilities

Building iTerm2 with the modified SDK identifies one piece of code that is x86 specific (and that the iTerm2 author noted won’t work on ARM)

Screenshot of the linked code

as well as a number of third-party binary libraries without ARM versions:

ld: warning: ignoring file /Users/zhuowei/Documents/repos/iTerm2/ThirdParty/libsixel/lib/libsixel.a, building for macOS-arm64e but attempting to link with file built for macOS-x86_64
ld: warning: ignoring file /Users/zhuowei/Documents/repos/iTerm2/BetterFontPicker/BetterFontPicker.framework/BetterFontPicker, building for macOS-arm64e but attempting to link with file built for macOS-x86_64
ld: warning: ignoring file /Users/zhuowei/Documents/repos/iTerm2/SearchableComboListView/SearchableComboListView.framework/SearchableComboListView, building for macOS-arm64e but attempting to link with file built for macOS-x86_64
ld: warning: ignoring file /Users/zhuowei/Documents/repos/iTerm2/ThirdParty/NMSSH.framework/NMSSH, building for macOS-arm64e but attempting to link with file built for macOS-x86_64
ld: warning: ignoring file /Users/zhuowei/Documents/repos/iTerm2/ColorPicker/ColorPicker.framework/ColorPicker, building for macOS-arm64e but attempting to link with file built for macOS-x86_64
ld: warning: ignoring file /Users/zhuowei/Documents/repos/iTerm2/ThirdParty/CoreParse.framework/CoreParse, building for macOS-arm64e but attempting to link with file built for macOS-x86_64
ld: warning: ignoring file /Users/zhuowei/Documents/repos/iTerm2/ThirdParty/Sparkle.framework/Sparkle, building for macOS-arm64e but attempting to link with file built for macOS-x86_64

What I learned

  • Thanks to .tbd files, it’s not too difficult to modify the SDKs shipped in Xcode
  • modern Xcode only reads SDKSettings.json, not SDKSettings.plist
  • float to int casts saturate on ARM, just like PowerPC
  • When Swift compiles a .swiftinterface to a binary .swiftmodule, errors aren’t printed until the process completes. This means that it could get stuck for 20 minutes with no output.
  • Apple’s Metal compiler actually checks if the SDK path contains “MacOSX.platform” to determine whether to compile for macOS or iOS

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK