Created
January 19, 2021 12:02
-
-
Save KaQuMiQ/5c02a27c736188e75d750c630cb9eb90 to your computer and use it in GitHub Desktop.
Convert fat binary framework into XCFramework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/bash | |
mkdir ./arm64 | |
mkdir ./x86_64 | |
find "./" -name '*.framework' -type d | while read -r FRAMEWORK | |
do | |
echo "Preparing framework: $FRAMEWORK" | |
FRAMEWORK_EXECUTABLE_NAME=$(/usr/libexec/PlistBuddy -c "Print CFBundleExecutable" "$FRAMEWORK/Info.plist") | |
echo "Preparing arm64 framework" | |
cp -R "$FRAMEWORK" "./arm64/$FRAMEWORK_EXECUTABLE_NAME.framework" | |
rm "./arm64/$FRAMEWORK_EXECUTABLE_NAME.framework/$FRAMEWORK_EXECUTABLE_NAME" | |
$(/usr/libexec/PlistBuddy -c "Set CFBundleSupportedPlatforms iPhoneOS" "./arm64/$FRAMEWORK_EXECUTABLE_NAME.framework/Info.plist") | |
echo "Extracting arm64 from $FRAMEWORK_EXECUTABLE_NAME" | |
lipo -extract "arm64" "$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME" -o "./arm64/$FRAMEWORK_EXECUTABLE_NAME.framework/$FRAMEWORK_EXECUTABLE_NAME" | |
echo "Preparing x86_64 framework" | |
cp -R "$FRAMEWORK" "./x86_64/$FRAMEWORK_EXECUTABLE_NAME.framework" | |
rm "./x86_64/$FRAMEWORK_EXECUTABLE_NAME.framework" | |
$(/usr/libexec/PlistBuddy -c "Set CFBundleSupportedPlatforms iPhoneSimulator" "./x86_64/$FRAMEWORK_EXECUTABLE_NAME.framework/Info.plist") | |
echo "Extracting x86_64 from $FRAMEWORK_EXECUTABLE_NAME" | |
lipo -extract "x86_64" "$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME" -o "./x86_64/$FRAMEWORK_EXECUTABLE_NAME.framework/$FRAMEWORK_EXECUTABLE_NAME" | |
xcodebuild -create-xcframework -framework "./arm64/$FRAMEWORK_EXECUTABLE_NAME.framework" -framework "./x86_64/$FRAMEWORK_EXECUTABLE_NAME.framework" -output "$FRAMEWORK_EXECUTABLE_NAME.xcframework" || exit -1 | |
done | |
rm -r ./arm64 | |
rm -r ./x86_64 |
I can't remember if I had such a case but I believe you should make one by hand inside (skip plist step and make it manually after merge). I am not sure if that also applies to static binaries, those could have no plist, so it should work without it.
Hello there, so I recently had to convert openCV2
ncnn
and openmp
and I ended up creating a new working script, it looks like this:
#! /bin/bash
find "." -name '*.framework' -type d | while read -r FRAMEWORK
do
echo "-----------------------"
FRAMEWORK_NAME=$(echo "$FRAMEWORK" | sed 's/\.\/\(.*\)\.framework/\1/')
FRAMEWORK_BUNDLE_NAME=$(/usr/libexec/PlistBuddy -c "Print CFBundleName" "$FRAMEWORK/Resources/Info.plist") || exit
XCFRAMEWORK_ROOT="./_$FRAMEWORK_NAME.xcframework"
XCTEMP_IPHONE_ROOT="$XCFRAMEWORK_ROOT/iphoneos"
XCTEMP_SIMULATOR_ROOT="$XCFRAMEWORK_ROOT/iphonesimulator"
TEMP_IPHONE_ROOT="$XCFRAMEWORK_ROOT/iphoneos/$FRAMEWORK_NAME.framework"
TEMP_SIMULATOR_ROOT="$XCFRAMEWORK_ROOT/iphonesimulator/$FRAMEWORK_NAME.framework"
echo "Bundle Name: $FRAMEWORK_NAME"
xcrun lipo -i "$FRAMEWORK/$FRAMEWORK_NAME"
echo "Creating new $XCFRAMEWORK_ROOT"
rm -rf "$XCFRAMEWORK_ROOT"
mkdir "$XCFRAMEWORK_ROOT"
echo "Creating new $XCTEMP_IPHONE_ROOT"
echo "Creating new $XCTEMP_SIMULATOR_ROOT"
mkdir -p "$XCTEMP_IPHONE_ROOT"
mkdir -p "$XCTEMP_SIMULATOR_ROOT"
echo "cp -r $FRAMEWORK $TEMP_IPHONE_ROOT"
echo "cp -r $FRAMEWORK $TEMP_SIMULATOR_ROOT"
cp -r "$FRAMEWORK" "$TEMP_IPHONE_ROOT"
cp -r "$FRAMEWORK" "$TEMP_SIMULATOR_ROOT"
declare -a ARCH_REMOVE_IPHONE=("i386" "x86_64")
declare -a ARCH_REMOVE_SIM=("i386" "arm64" "arm64e" "armv7" "armv7s")
echo "******************"
for ARCH in "${ARCH_REMOVE_IPHONE[@]}"
do
echo "Remove $ARCH from device slice of the xcframework"
xcrun lipo -remove "$ARCH" "$TEMP_IPHONE_ROOT/$FRAMEWORK_NAME" -o "$TEMP_IPHONE_ROOT/tmp" &&
rm "$TEMP_IPHONE_ROOT/$FRAMEWORK_NAME" &&
mv "$TEMP_IPHONE_ROOT/tmp" "$TEMP_IPHONE_ROOT/$FRAMEWORK_NAME"
done
echo "Confirm the DEVICE binary has the proper (arm64) slice"
xcrun lipo -i "$TEMP_IPHONE_ROOT/$FRAMEWORK_NAME"
echo "******************"
for ARCH in "${ARCH_REMOVE_SIM[@]}"
do
echo "Remove $ARCH from sim slice of the xcframework"
xcrun lipo -remove "$ARCH" "$TEMP_SIMULATOR_ROOT/$FRAMEWORK_NAME" -o "$TEMP_SIMULATOR_ROOT/tmp" &&
rm "$TEMP_SIMULATOR_ROOT/$FRAMEWORK_NAME" &&
mv "$TEMP_SIMULATOR_ROOT/tmp" "$TEMP_SIMULATOR_ROOT/$FRAMEWORK_NAME"
done
echo "Confirm the SIM binary has the proper (x86_64) slice."
xcrun lipo -i "$TEMP_SIMULATOR_ROOT/$FRAMEWORK_NAME"
echo "Create xcframework from the platform slices"
echo "xcodebuild -create-xcframework -framework $TEMP_IPHONE_ROOT -framework $TEMP_SIMULATOR_ROOT -output ./$FRAMEWORK_NAME.xcframework"
xcodebuild -create-xcframework -framework "$TEMP_IPHONE_ROOT" -framework "$TEMP_SIMULATOR_ROOT" -output "$FRAMEWORK_NAME.xcframework"
rm -rf "$XCFRAMEWORK_ROOT"
done
Expected sample output:
Frameworks ./convertFrameworks.sh
-----------------------
Bundle Name: openmp
Architectures in the fat file: ./openmp.framework/openmp are: armv7 i386 x86_64 arm64 arm64e
Creating new ./_openmp.xcframework
Creating new ./_openmp.xcframework/iphoneos
Creating new ./_openmp.xcframework/iphonesimulator
cp -r ./openmp.framework ./_openmp.xcframework/iphoneos/openmp.framework
cp -r ./openmp.framework ./_openmp.xcframework/iphonesimulator/openmp.framework
******************
Remove i386 from device slice of the xcframework
Remove x86_64 from device slice of the xcframework
Confirm the DEVICE binary has the proper (arm64) slice
Architectures in the fat file: ./_openmp.xcframework/iphoneos/openmp.framework/openmp are: armv7 arm64 arm64e
******************
Remove i386 from sim slice of the xcframework
Remove arm64 from sim slice of the xcframework
Remove arm64e from sim slice of the xcframework
Remove armv7 from sim slice of the xcframework
Remove armv7s from sim slice of the xcframework
fatal error: /Applications/Xcode14.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: -remove armv7s specified but fat file: ./_openmp.xcframework/iphonesimulator/openmp.framework/openmp does not contain that architecture
Confirm the SIM binary has the proper (x86_64) slice.
Architectures in the fat file: ./_openmp.xcframework/iphonesimulator/openmp.framework/openmp are: x86_64
Create xcframework from the platform slices
xcodebuild -create-xcframework -framework ./_openmp.xcframework/iphoneos/openmp.framework -framework ./_openmp.xcframework/iphonesimulator/openmp.framework -output ./openmp.xcframework
xcframework successfully written out to: /Users/hassan/projects/FaceKit/Sources/FaceKit/Frameworks/openmp.xcframework
-----------------------
Bundle Name: opencv2
Architectures in the fat file: ./opencv2.framework/opencv2 are: armv7 armv7s i386 x86_64 arm64
Creating new ./_opencv2.xcframework
Creating new ./_opencv2.xcframework/iphoneos
Creating new ./_opencv2.xcframework/iphonesimulator
cp -r ./opencv2.framework ./_opencv2.xcframework/iphoneos/opencv2.framework
cp -r ./opencv2.framework ./_opencv2.xcframework/iphonesimulator/opencv2.framework
******************
Remove i386 from device slice of the xcframework
Remove x86_64 from device slice of the xcframework
Confirm the DEVICE binary has the proper (arm64) slice
Architectures in the fat file: ./_opencv2.xcframework/iphoneos/opencv2.framework/opencv2 are: armv7 armv7s arm64
******************
Remove i386 from sim slice of the xcframework
Remove arm64 from sim slice of the xcframework
Remove arm64e from sim slice of the xcframework
fatal error: /Applications/Xcode14.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: -remove arm64e specified but fat file: ./_opencv2.xcframework/iphonesimulator/opencv2.framework/opencv2 does not contain that architecture
Remove armv7 from sim slice of the xcframework
Remove armv7s from sim slice of the xcframework
Confirm the SIM binary has the proper (x86_64) slice.
Architectures in the fat file: ./_opencv2.xcframework/iphonesimulator/opencv2.framework/opencv2 are: x86_64
Create xcframework from the platform slices
xcodebuild -create-xcframework -framework ./_opencv2.xcframework/iphoneos/opencv2.framework -framework ./_opencv2.xcframework/iphonesimulator/opencv2.framework -output ./opencv2.xcframework
xcframework successfully written out to: /Users/hassan/projects/FaceKit/Sources/FaceKit/Frameworks/opencv2.xcframework
-----------------------
Bundle Name: ncnn
Architectures in the fat file: ./ncnn.framework/ncnn are: armv7 i386 x86_64 arm64 arm64e
Creating new ./_ncnn.xcframework
Creating new ./_ncnn.xcframework/iphoneos
Creating new ./_ncnn.xcframework/iphonesimulator
cp -r ./ncnn.framework ./_ncnn.xcframework/iphoneos/ncnn.framework
cp -r ./ncnn.framework ./_ncnn.xcframework/iphonesimulator/ncnn.framework
******************
Remove i386 from device slice of the xcframework
Remove x86_64 from device slice of the xcframework
Confirm the DEVICE binary has the proper (arm64) slice
Architectures in the fat file: ./_ncnn.xcframework/iphoneos/ncnn.framework/ncnn are: armv7 arm64 arm64e
******************
Remove i386 from sim slice of the xcframework
Remove arm64 from sim slice of the xcframework
Remove arm64e from sim slice of the xcframework
Remove armv7 from sim slice of the xcframework
Remove armv7s from sim slice of the xcframework
fatal error: /Applications/Xcode14.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: -remove armv7s specified but fat file: ./_ncnn.xcframework/iphonesimulator/ncnn.framework/ncnn does not contain that architecture
Confirm the SIM binary has the proper (x86_64) slice.
Architectures in the fat file: ./_ncnn.xcframework/iphonesimulator/ncnn.framework/ncnn are: x86_64
Create xcframework from the platform slices
xcodebuild -create-xcframework -framework ./_ncnn.xcframework/iphoneos/ncnn.framework -framework ./_ncnn.xcframework/iphonesimulator/ncnn.framework -output ./ncnn.xcframework
xcframework successfully written out to: /Users/hassan/projects/FaceKit/Sources/FaceKit/Frameworks/ncnn.xcframework
What when the framework contains resources? Are they also transferred to the XCFramework? Cannot see any references.
@Blackjacx I have the same question, is there any way to convert the fat binary with resources to XCFramework including arm64-simulator slice?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Do you know what I can do if the framework doesn't have an Info.plist file?