Skip to content

Instantly share code, notes, and snippets.

@RedenticDev
Last active April 24, 2024 11:12
Show Gist options
  • Save RedenticDev/e2924d0169bd139545ac851f9ebd2c1f to your computer and use it in GitHub Desktop.
Save RedenticDev/e2924d0169bd139545ac851f9ebd2c1f to your computer and use it in GitHub Desktop.
Xcode 12 & Theos

What's the problem?

Since June, 22nd 2020, Apple released Xcode 12, that introduced an internal change to Xcode, breaking arm64e compilation for tweak developers. This is due to the update of clang/LLVM (AFAIK) in Xcode 12.

Details of the problem

More specifically:

  • compiling code for arm64e with Xcode 11 Toolchain will allow this code to run only on iOS 13 and lower for all versions!.
  • compiling code for arm64e with Xcode 12 Toolchain will allow this code to run only for iOS 14 (and up).

No error is produced during compilation. arm64 slices are not concerned and will always work.

Why does this annoy us and not others?

Apps and other "classic" stuff are not impacted by this change, because they only need to be compiled for arm64, which is not impacted by this change. Only IPAs, debs, and "system" stuff that need to be compiled for arm64e are impacted.

Workarounds

Methods to allow arm64e compiling. Tested on macOS Catalina & Big Sur.

Method 1: bypass (deprecated and not recommended)

This method consists on swapping the Xcode 12 toolchain with the one of Xcode 11:

  1. Execute the script below (please take a look at it and change variables as needed) if your setup is similar to mine.
  2. If you have Xcode 11 installed too, go to Xcode 12 › Xcode › Preferences › Locations › Command Line Tools and change to Xcode 11.x in the dropdown menu.

Method 2: forced compilation (do that!)

Although it's not recommended by theos maintainers, it works well and is less constraining that switching between Xcode installations (which it not even possible anymore with Apple Silicon Macs). If you cannot get Xcode 11, download its toolchain here.
To proceed, add this in your tweak's Makefile:

PREFIX="/path/to/xcode-11-xctoolchain/usr/bin/"

OR
compile your tweak like this:

make package PREFIX="/path/to/xcode-11-xctoolchain/usr/bin/"

Method 3: Xcode 11 + 12

Painful and only for Intel Macs, but the best solution according to @kabiroberai. Depending on your configuration/available storage, you can:

  • Stay with Xcode 11 and don't update
  • Use Xcode 11 as main but sideload Xcode 12 for other purposes (thanks to this awesome tool)
  • Use Xcode 12 as main but switch installations each time you want to compile for arm64e too (similar to above): sudo xcode-select -s /path/to/Xcode_11.app, make package, then again sudo xcode-select -s /path/to/Xcode_12.app

Double-sliced packages (useless, ignore it)

Waiting for the fix within theos to support both arm64e slices in only one package, there is a "bypass" available to create this type of package. To do so, simply use opa334's script to compile your code with the patched lipo binary by Matchstic (called plipo).

Sources

Disclaimer: I may be not perfectly exact on the terms I use, correct me if I'm wrong!

Update 1: clarified a bit, added double slices part, fixed typo
Update 2: fixed link
Update 3: rollback to previous system, bye "double slices"!
Update 4: mentioned "the best" solution, improved some points
Update 5: add mention of M1 Macs and link to Xcode 11 toolchain

#!/bin/sh
# This script swaps the Xcode 12 toolchain with the one of Xcode 11.
# Xcode 11.x is required for the "local" option. Tested on Catalina & Big Sur.
# DISCLAIMER: Use this at your own risks.
# beginning of setup variables
XCODE12PATH=/Applications/Xcode.app/Contents/Developer/Toolchains # path of your Xcode 12 Toolchains folder
XCODE11PATH=$(THEOS)/toolchains # path of your Xcode 11.x Toolchain
# end of setup
VERSION=$(/usr/bin/xcodebuild -version | grep Xcode | cut -d' ' -f2)
TOOLCHAIN_SOURCE=Xcode11Toolchain
echo ">> Listing toolchains"
ls $XCODE12PATH
read -rp "Press enter to continue (Ctrl+C to leave)..."
cd || exit 1
echo ">> Cleaning up..."
[ -d Xcode11Toolchain ] && rm -rf Xcode11Toolchain
echo "Import from:"
select yn in "Local" "Online"; do
case $yn in
"Local" ) # DON'T USE IF YOU ONLY HAVE XCODE 12 INSTALLED
TOOLCHAIN_SOURCE=$XCODE11PATH
break;;
"Online" )
echo ">> Downloading Xcode 11 Toolchain...";
git clone https://github.com/nahtedetihw/Xcode11Toolchain;
break;;
esac
done
echo ">> Swapping toolchains and importing the Xcode 11 one..."
sudo mv $XCODE12PATH/XcodeDefault.xctoolchain $XCODE12PATH/XcodeDefault-"${VERSION}".xctoolchain
sudo cp -r "$TOOLCHAIN_SOURCE"/XcodeDefault.xctoolchain $XCODE12PATH
if [ -d Xcode11Toolchain ]; then
echo ">> Removing downloaded files..."
rm -rf Xcode11Toolchain
fi
echo "Done."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment