Skip to content

Instantly share code, notes, and snippets.

@Shehryar
Created April 9, 2019 13:45
Show Gist options
  • Save Shehryar/0c29cce7eead9c724b4c16b018bab63f to your computer and use it in GitHub Desktop.
Save Shehryar/0c29cce7eead9c724b4c16b018bab63f to your computer and use it in GitHub Desktop.
Fix for creating a fat framework using lipo in Xcode 10.2
#!/bin/sh
if [ -z "$XCODE_VERSION_CORRECT" ]
then
export SUDO_ASKPASS="${PROJECT_DIR}/../scripts/askpass.sh"
fi
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 1. Build Device and Simulator versions
# add BITCODE_GENERATION_MODE=bitcode to support bitcode
echo "Building for devices"
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphoneos ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# add BITCODE_GENERATION_MODE=marker to support bitcode
echo "Building for simulators"
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
echo "Copying framework structure"
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
echo "Copying simulator Swift modules"
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi
# Step 4. Create new combined simulator and device swift header file
COMBINED_PATH="${BUILD_DIR}/iOS + iOS Simulator/${PROJECT_NAME}-Swift.h"
mkdir -p "${BUILD_DIR}/iOS + iOS Simulator/"
touch "${COMBINED_PATH}"
echo "#if TARGET_OS_SIMULATOR" >> "${COMBINED_PATH}"
cat "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Headers/${PROJECT_NAME}-Swift.h" >> "${COMBINED_PATH}"
echo "#else" >> "${COMBINED_PATH}"
echo "//Start of iphoneos" >> "${COMBINED_PATH}"
cat "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/Headers/${PROJECT_NAME}-Swift.h" >> "${COMBINED_PATH}"
echo "#endif" >> "${COMBINED_PATH}"
# Step 5. Create universal binary file using lipo and place the combined executable in the copied framework directory
echo "Creating universal binary using lipo"
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
# Step 6. Overwrite generated -Swift.h file with combined -Swift.h file -- Kknown Issue with XCode 10.2 https://developer.apple.com/documentation/xcode_release_notes/xcode_10_2_release_notes#3141454
cat "$COMBINED_PATH" > "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Headers/${PROJECT_NAME}-Swift.h"
# Step 7. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}/../package/"
# Step 8. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}/../package/"
@juandavidcardona
Copy link

thank you very much!!!!

@iva1ex
Copy link

iva1ex commented May 26, 2020

Hi @Shehyar, thanks for the build script :D

Anyway, i'm encountered some issue which "TARGET_OS_SIMULATOR" always false on my swift framework header as i'm using simulator to runs the app.
So, my workaround was adding "#include <TargetConditionals.h>" in first line of the header.

My workaround :

Step 4. Create new combined simulator and device swift header file

COMBINED_PATH="${BUILD_DIR}/iOS + iOS Simulator/${PROJECT_NAME}-Swift.h"
mkdir -p "${BUILD_DIR}/iOS + iOS Simulator/"
touch "${COMBINED_PATH}"
echo "#include <TargetConditionals.h>" >> "${COMBINED_PATH}"
echo "#if TARGET_OS_SIMULATOR" >> "${COMBINED_PATH}"
cat "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Headers/${PROJECT_NAME}-Swift.h" >> "${COMBINED_PATH}"
echo "#else" >> "${COMBINED_PATH}"
echo "//Start of iphoneos" >> "${COMBINED_PATH}"
cat "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/Headers/${PROJECT_NAME}-Swift.h" >> "${COMBINED_PATH}"
echo "#endif" >> "${COMBINED_PATH}"

Lastly, not sure this just happens to me and i hope this can solve for those encounter this issue.

Thanks! It worked for me 👍

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