We have been using lipo command to create a framework which works on both device and simulator when integrated in other project. following are the build commands used to generate device and simulator builds
xcodebuild -target SampleSDK ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" OBJROOT="${OBJROOT}/DependentBuilds"
xcodebuild -target SampleSDK ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" OBJROOT="${OBJROOT}/DependentBuilds"
after this we are copying swift modules from iphonesimulator(if it exists) to the copied framework dir
cp -R "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/Modules/SampleSDK.swiftmodule/" "${UNIVERSAL_OUTPUTFOLDER}/${PRODUCT_NAME}/Modules/${PROJECT_NAME}.swiftmodule/"
and then lipo command
lipo -create "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PRODUCT_NAME}/${PROJECT_NAME}" -output "${UNIVERSAL_OUTPUTFOLDER}/${PRODUCT_NAME}/${PROJECT_NAME}"
the above command is failing with following error
fatal error: lipo: /path/to/Library/Developer/Xcode/DerivedData/Sample-bhfmlauxsdympmdjkjyvujaljevg/Build/Products/Debug-iphonesimulator/SampleSDK.framework/SampleSDK and /Users/rramshettysiddaraju/Library/Developer/Xcode/DerivedData/Sample-bhfmlauxsdympmdjkjyvujaljevg/Build/Products/Debug-iphoneos/SampleSDK.framework/SampleSDK have the same architectures (arm64) and can't be in the same fat output file
I tried one of the answers in stackoverflow, about adding user-defined setting VALID_ARCHS and then removing it. but that didnt work
The reason for the error is that Xcode 12 includes a slice for the "arm64" architecture when building for the simulator (in addition to the usual "i386" and "x86_64" architectures for Xcode <12). This is probably for supporting the simulator on (future) Macs using Apple Silicon processors. As your device build also includes the "arm64" architecture, lipo
does not know which of the two "arm64" slices you want and refuses to create a combined fat binary framework.
As a workaround, you can either exclude the "arm64" architecture from the simulator build by appending the EXCLUDED_ARCHS
build variable:
xcodebuild -target SampleSDK ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" OBJROOT="${OBJROOT}/DependentBuilds" EXCLUDED_ARCHS="arm64"
Alternatively, use lipo -remove
to remove the "arm64" architecture from the simulator build before combining the simulator and device frameworks into one:
lipo -remove arm64 "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/${PROJECT_NAME}" -output "$BUILD_DIR/${CONFIGURATION}-iphonesimulator/${PRODUCT_NAME}/${PROJECT_NAME}"
In the long run, you might be better off building an XCFramework, which should support devices and simulators without the need for using lipo
. But I haven’t tested this yet.