Skip to content

Instantly share code, notes, and snippets.

@KaQuMiQ
Created January 19, 2021 12:02
Show Gist options
  • Save KaQuMiQ/5c02a27c736188e75d750c630cb9eb90 to your computer and use it in GitHub Desktop.
Save KaQuMiQ/5c02a27c736188e75d750c630cb9eb90 to your computer and use it in GitHub Desktop.
Convert fat binary framework into XCFramework
#! /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
@hassanvfx
Copy link

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:
image

#! /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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment