是否可以使用位码创建通用 iOS 框架?
Posted
技术标签:
【中文标题】是否可以使用位码创建通用 iOS 框架?【英文标题】:Is it possible to create a universal iOS framework using bitcode? 【发布时间】:2016-02-23 19:33:09 【问题描述】:据我了解,bitcode 允许生成具有中间二进制格式的二进制文件。所以这是编译到 ARM 或 x64 架构之前的步骤。
从 ios 8 开始,可以为 iOS 创建“真实的”.framework
文件。但是,默认情况下,框架文件仅针对一种架构(模拟器、iPhone)进行编译。当一个人想要分发.framework
文件时,最好提供一个与iOS 模拟器兼容并且也可以部署到iPhone 的文件。可以找到不同的脚本示例来使用lipo
创建这样的胖文件。
但是,是否可以只分发编译为位码的.framework
而不必创建具有不同架构的胖文件?
不幸的是,即使为我的.framework
启用了位码:
我对bitcode的概念有什么误解,还是我错过了什么?
【问题讨论】:
【参考方案1】:您需要提供一个通用的平面框架。由lipo
创建。
Targets->Build Setting->Enable Bitcode
到 Yes
添加构建目标以创建通用框架
创建一个Aggregate
目标并将以下脚本复制到Build Phrase -> Run Script
:
注意
bitcode 仅打包在archive
iphoneos sdk 构建上
otool -l -arch arm64 <yourframework_binary>|grep __LLVM
检查是否包含bitcode,如果不指定arch
参数,则不会有__LLVM
,因为otool
只打印一个主机arch(模拟器)。
【讨论】:
请再读一遍问题。这正是我想避免的(我在我的问题中提到了lipo
)。如果我无论如何都需要创建通用二进制文件,我不明白将某些东西编译为位码的目的。而且我找不到使用archive
构建创建的框架文件。
bitcode 是由 Xcode 编译的中间 LLVM IR,并且依赖于 arch,不像 java 字节码,因此每个 slice 都需要自己的 bitcode 部分。既然是中间代码,所以苹果以后不用上传新版本就可以用它优化到最终的机器码,这是主要目的
并且使用脚本中的archive
创建的框架位于$DEVICE_LIBRARY_PATH/Modules/$FRAMEWORK_NAME
上,参见here
非常感谢这个脚本!还应添加“跳过安装 = 是”以避免从 Build/Products/Release-iphoneos 中删除设备版本【参考方案2】:
我花了很多时间修复/更改 xfaid 答案的设置,最终获得了一个带有位码的通用包,可与 XCode 10 一起使用。
我无法让“xcodebuild archive”命令工作,所以我使用了以下链接中描述的设置:http://iosre.com/t/enable-bitcode-for-frameworks-in-xcode/12581
然后我将脚本稍微更改为:
# 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
以防万一它可以帮助你们中的一些人:)
【讨论】:
以上是关于是否可以使用位码创建通用 iOS 框架?的主要内容,如果未能解决你的问题,请参考以下文章
pod install 后 iOS 通用框架编译器版本发生变化