xcframework - ShenYj/ShenYj.github.io GitHub Wiki
.xcframework
- 2019年推出 优化不同架构的处理
-
XCFramework
是XCode11
中提出的一个新特性,是由XCode
创建的一个可分发的二进制包,它包含了framework
或library
的一个或多个变体,因此可以在多个平台(iOS
、macOS
、tvOS
、watchOS
) 上使用,包括模拟器。XCFramework
可以是静态的,也可以是动态的。xcframework
的好处就是用Xcode
发布的时候,Xcode
会自动选用正确的指令集Frameworks
,省去了手动移除动态库中的模拟器指令集的工作。
- 可以用单个
.xcframework
文件提供多个平台的分发二进制文件 - 与
Fat Header
相比,可以按照平台划分,可以包含相同架构的不同平台的文件 - 在使用时,不需要在通过 lipo 去剥离不需要的架构体系
- 并且mac下
arm64
和iphonearm64
是无法直接合并在一起的,这也使用是Carthage
常遇到的一个问题
- 并且mac下
xcodebuild -help / xcodebuild -create-xcframework -help
可以获取帮助信息
-
脚本
#!/bin/bash set -euo pipefail PROJECT_DIR=$(dirname "$PWD") echo -e "项目资源目录: ${PROJECT_DIR}" pushd $PROJECT_DIR PROJECT_NAME=DashLine BUILD_DIR="build" ARCHIVE_PATH="${BUILD_DIR}/${PROJECT_NAME}" rm -rf $BUILD_DIR clear echo -e "当前路径 '$(pwd)'" # Generate iOS framework xcodebuild archive -project ${PROJECT_NAME}.xcodeproj -scheme $PROJECT_NAME -configuration Release -sdk iphoneos -archivePath "${ARCHIVE_PATH}-iphoneos.xcarchive" -destination "generic/platform=iOS" SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE=YES | xcpretty --color --simple # Generate iOS Simulator framework xcodebuild archive -project ${PROJECT_NAME}.xcodeproj -scheme $PROJECT_NAME -configuration Release -sdk iphonesimulator -archivePath "${ARCHIVE_PATH}-iossimulator.xcarchive" -destination "generic/platform=iOS Simulator" SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES OTHER_CFLAGS="-fembed-bitcode" BITCODE_GENERATION_MODE="bitcode" ENABLE_BITCODE=YES | xcpretty --color --simple echo -e "当前路径 "$(pwd)"" echo -e "归档路径: ${ARCHIVE_PATH}" # Generate XCFramework pushd $BUILD_DIR clear echo "$PWD" echo "$(ls -lh)" function GetUUID() { # dwarfdump output: # UUID: FFFFFFF-AAAAA-BBBB-CCCC-DDDDDDDDDD (arm64) PATH_TO_ARCHIVE/FRAMEWORK.framework-ios-arm64.xcarchive/Products/Library/Frameworks/FRAMEWORK.framework/FRAMEWORK local arch=$1 local binary=$2 local dwarfdump_result=$(dwarfdump -u ${binary}) local regex="UUID: (.*) \((.*)\)" if [[ $dwarfdump_result =~ $regex ]]; then local result_uuid="${BASH_REMATCH[1]}" local result_arch="${BASH_REMATCH[2]}" if [ "$result_arch" == "$arch" ]; then echo $result_uuid fi fi } # First, find UUID for BCSymbolMaps of our binary, because these are randomly generated. The dSYM path is always the same so that one is manually added # Simulator-targeted archives don't generate BCSymbolMap files, so this is only needed for iphone target BCSYMBOLMAP_UUID=$(GetUUID "arm64" "${PROJECT_NAME}-iphoneos.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework/${PROJECT_NAME}") if [[ -n $BCSYMBOLMAP_UUID && $BCSYMBOLMAP_UUID != "" ]]; then echo -e ">>>> Finded out UUID: <${BCSYMBOLMAP_UUID}>" xcodebuild -create-xcframework \ -framework "${PROJECT_NAME}-iphoneos.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ -debug-symbols "$PWD/${PROJECT_NAME}-iphoneos.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ -debug-symbols "$PWD/${PROJECT_NAME}-iphoneos.xcarchive/BCSymbolMaps/${BCSYMBOLMAP_UUID}.bcsymbolmap" \ -framework "${PROJECT_NAME}-iossimulator.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ -debug-symbols "$PWD/${PROJECT_NAME}-iossimulator.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ -allow-internal-distribution \ -output "${PROJECT_NAME}.xcframework" popd # Zip it! echo -e "Zip: $(PWD)" zip -r "./$BUILD_DIR/${PROJECT_NAME}.xcframework.zip" "./$BUILD_DIR/${PROJECT_NAME}.xcframework" else echo -e "获取失败" fi popd echo -e "回到脚本所在路径: $PWD"
-
SKIP_INSTALL=NO
: 一定不能缺少,并且为NO
,否则在归档文件Products
中不会包含framework
-
-debug-symbols
: 必须使用绝对路径 -
-allow-internal-distribution
: 最初准备脚本调试期间一直失败,查看帮助看到这么个参数,加上就成功创建了 -
dSYMs
: 提供给 SDK 使用者用于调试,方便恢复整个调用栈 -
.bcsymbolmap
:bitcode
文件,默认debug
下不会开启bitcode
,所以模拟器下不会产生
示例脚本和项目工程在下方资料链接中查看
-
将生成的xcframework
集成入项目中直接使用即可,架构、符号都不需要再次干预,Xcode在编译的时候会自动根据架构选择处理