问题
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
:
- different files are created by default according to the targeted architecture
- even if the "archive" menu seems to be enabled for a framework target, I cannot find the result, even in my Organizer view
Do I misunderstand something in the concept of bitcode, or do I miss something?
回答1:
You need to provide a universal flat framework. Which is created by lipo
.
- Enable Bitcode,
Targets->Build Setting->Enable Bitcode
toYes
Add build target to create universal framework
Create a
Aggregate
target and copy following script toBuild 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 sdkotool -l -arch arm64 <yourframework_binary>|grep __LLVM
to check whether bitcode is included, if you don't specify thearch
parameter, there will be no__LLVM
, sinceotool
just print one host arch(simulator).
回答2:
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 :)
来源:https://stackoverflow.com/questions/35586516/is-it-possible-to-create-a-universal-ios-framework-using-bitcode