From what I understood, bitcode allows to generate binaries with an intermediary binary format. So it is the step before compiling to an ARM or x64 architecture.
It is possible to create "real" .framework file for iOS since iOS 8. However, framework files are compiled for only one architecture by default (emulator, iPhone). When one wants to distribute a .framework file, it is better to provide a file compatible with the iOS emulator and also deployable to an iPhone. Different examples of scripts can be found to create such a fat file using lipo.
However, would it be possible to only distribute a .framework compiled as bitcode without having to create a fat file with different architectures?
Unfortunately, even with bitcode enabled for my .framework:
Do I misunderstand something in the concept of bitcode, or do I miss something?
I spend many hours fixing / changing the setup of xfaid's answer to have finaly a universal package with bitcode working with XCode 10.
I couldn't get the "xcodebuild archive" command work, so I used build with the settings described at this link: http://iosre.com/t/enable-bitcode-for-frameworks-in-xcode/12581
I then changed a little the script to:
# Fix for bitcode:
unset TOOLCHAINS
######################
# Options
######################
#verbose
#set -x
REVEAL_ARCHIVE_IN_FINDER=true
FRAMEWORK_NAME="${PROJECT_NAME}"
SIMULATOR_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${FRAMEWORK_NAME}.framework"
DEVICE_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphoneos/${FRAMEWORK_NAME}.framework"
UNIVERSAL_LIBRARY_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal"
FRAMEWORK="${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework"
######################
# Build Frameworks
######################
# Build for simulator
xcodebuild -target ${PROJECT_NAME} -sdk iphonesimulator -configuration ${CONFIGURATION} ARCHS="i386 x86_64" ONLY_ACTIVE_ARCH=NO clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator
# Build for device
xcodebuild -scheme ${PROJECT_NAME} -sdk iphoneos -configuration ${CONFIGURATION} ARCHS="armv7 armv7s arm64" ONLY_ACTIVE_ARCH=NO build  ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode"  OBJROOT="${OBJROOT}/DependantBuilds" CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos
######################
# Create directory for universal
######################
rm -rf "${UNIVERSAL_LIBRARY_DIR}"
mkdir "${UNIVERSAL_LIBRARY_DIR}"
mkdir "${FRAMEWORK}"
######################
# Copy files Framework
######################
cp -r "${DEVICE_LIBRARY_PATH}/." "${FRAMEWORK}"
######################
# Make an universal binary
######################
lipo "${SIMULATOR_LIBRARY_PATH}/${FRAMEWORK_NAME}" "${DEVICE_LIBRARY_PATH}/${FRAMEWORK_NAME}" -create -output "${FRAMEWORK}/${FRAMEWORK_NAME}" | echo
# For Swift framework, Swiftmodule needs to be copied in the universal framework
if [ -d "${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
cp -f ${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
fi
if [ -d "${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
cp -f ${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
fi
######################
# On Release, copy the result to release directory
######################
OUTPUT_DIR="${PROJECT_DIR}/build/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"
rm -rf "$OUTPUT_DIR"
mkdir -p "$OUTPUT_DIR"
cp -r "${FRAMEWORK}" "$OUTPUT_DIR"
if [ ${REVEAL_ARCHIVE_IN_FINDER} = true ]; then
open "${OUTPUT_DIR}/"
fi
Just in case it can helps some of you :)
You need to provide a universal flat framework. Which is created by lipo.
Targets->Build Setting->Enable Bitcode to Yes
Add build target to create universal framework
Create a Aggregate target and copy following script to Build Phrase -> Run Script:
    ######################
    # Options
    ######################
    #verbose
    set -x
    REVEAL_ARCHIVE_IN_FINDER=false
    FRAMEWORK_NAME="${PROJECT_NAME}"
    SIMULATOR_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${FRAMEWORK_NAME}.framework"
    DEVICE_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphoneos/${FRAMEWORK_NAME}.framework"
    UNIVERSAL_LIBRARY_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal"
    FRAMEWORK="${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework"
    ######################
    # Build Frameworks
    ######################
    # Build for simulator
    xcodebuild -target ${PROJECT_NAME} -sdk iphonesimulator -configuration ${CONFIGURATION} ARCHS="i386 x86_64" ONLY_ACTIVE_ARCH=NO clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator
    # Build for device
    xcodebuild -scheme ${PROJECT_NAME} -sdk iphoneos -configuration ${CONFIGURATION} ARCHS="armv7 armv7s arm64" ONLY_ACTIVE_ARCH=NO clean archive CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos
    ######################
    # Create directory for universal
    ######################
    rm -rf "${UNIVERSAL_LIBRARY_DIR}"
    mkdir "${UNIVERSAL_LIBRARY_DIR}"
    mkdir "${FRAMEWORK}"
    ######################
    # Copy files Framework
    ######################
    cp -r "${DEVICE_LIBRARY_PATH}/." "${FRAMEWORK}"
    ######################
    # Make an universal binary
    ######################
    lipo "${SIMULATOR_LIBRARY_PATH}/${FRAMEWORK_NAME}" "${DEVICE_LIBRARY_PATH}/${FRAMEWORK_NAME}" -create -output "${FRAMEWORK}/${FRAMEWORK_NAME}" | echo
    # For Swift framework, Swiftmodule needs to be copied in the universal framework
    if [ -d "${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
    cp -f ${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
    fi
    if [ -d "${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
    cp -f ${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
    fi
    ######################
    # On Release, copy the result to release directory
    ######################
    OUTPUT_DIR="${PROJECT_DIR}/build/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"
    rm -rf "$OUTPUT_DIR"
    mkdir -p "$OUTPUT_DIR"
    cp -r "${FRAMEWORK}" "$OUTPUT_DIR"
    if [ ${REVEAL_ARCHIVE_IN_FINDER} = true ]; then
    open "${OUTPUT_DIR}/"
    fi
Note
bitcode is only packed on archive build for iphoneos sdk
otool -l -arch arm64 <yourframework_binary>|grep __LLVM to check whether bitcode is included, if you don't specify the arch parameter, there will be no __LLVM, since otool just print one host arch(simulator).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With