[M1]iOS编译xcframework, 模拟器支持arm64架构

先抛问题, 编译报错: binaries with multiple platforms are not supported “xxxx-ios-simulator.framwork”.

如果你能看到这篇文章,大概率是因为使用Mac的M系列芯片编译xcframework出现这个问题导致的. Mac Intel环境不会出现这个错误.

确保你的 Xcode 构建设置中的 “Build Active Architecture Only” 选项为 NO,并且构建设置中包含了所有需要的平台和架构。

废话不多说,直接上脚本, 从脚本里面看吧.

#!/bin/bash
# 检查输入的路径是否有效
if [[ ! -f "$1" && ! -d "$1" ]]; then
    echo "无效的路径,请提供正确的.xcworkspace文件路径。"
    exit 1
fi

# 获取工作区文件路径参数
WORKSPACE_PATH="$1"

# 提取文件名(不包含扩展名)作为项目名称
PROJECT_NAME=$(basename "$WORKSPACE_PATH" | sed 's/\.[^.]*$//')

# 设置其他变量
OUTPUT_DIR="output"

# 清理之前的构建
rm -rf "$OUTPUT_DIR"
mkdir -p "$OUTPUT_DIR"

# 编译 iOS 真机 Release 架构
xcodebuild archive -workspace "$WORKSPACE_PATH" -scheme "$PROJECT_NAME" -archivePath "$OUTPUT_DIR/iphoneos.xcarchive" -sdk iphoneos -configuration Release SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES

# 编译 iOS 模拟器 arm64 Release 架构
xcodebuild archive -workspace "$WORKSPACE_PATH" -scheme "$PROJECT_NAME" -archivePath "$OUTPUT_DIR/ios_sim_arm64.xcarchive" -sdk iphonesimulator -arch arm64 -configuration Release SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES

# 编译 iOS 模拟器 x86_64 Release 架构
xcodebuild archive -workspace "$WORKSPACE_PATH" -scheme "$PROJECT_NAME" -archivePath "$OUTPUT_DIR/ios_sim_x86_64.xcarchive" -sdk iphonesimulator -arch x86_64 -configuration Release SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES

# 创建 iOS 真机 framework 目录
mkdir -p "$OUTPUT_DIR/iphoneos"
cp -R "$OUTPUT_DIR/iphoneos.xcarchive/Products/Library/Frameworks/$PROJECT_NAME.framework" "$OUTPUT_DIR/iphoneos/"

# 创建 iOS 模拟器 arm64 framework 目录
mkdir -p "$OUTPUT_DIR/ios_sim_arm64"
cp -R "$OUTPUT_DIR/ios_sim_arm64.xcarchive/Products/Library/Frameworks/$PROJECT_NAME.framework" "$OUTPUT_DIR/ios_sim_arm64/"

# 创建 iOS 模拟器 x86_64 framework 目录
mkdir -p "$OUTPUT_DIR/ios_sim_x86_64"
cp -R "$OUTPUT_DIR/ios_sim_x86_64.xcarchive/Products/Library/Frameworks/$PROJECT_NAME.framework" "$OUTPUT_DIR/ios_sim_x86_64/"

# 将arm64进行模拟器arm64架构编译, 解决arm64库冲突问题
rm -rf $OUTPUT_DIR/temp
mkdir $OUTPUT_DIR/temp
cd $OUTPUT_DIR/temp

ar x "../ios_sim_arm64/$PROJECT_NAME.framework/$PROJECT_NAME"

ARM64_TO_SIM_PATH="Path/arm64-to-sim-main/.build/apple/Products/Release/arm64-to-sim"

for file in *.o; do echo processing $file && $ARM64_TO_SIM_PATH $file; done;

ar crv "../ios_sim_arm64/$PROJECT_NAME.framework/$PROJECT_NAME-sim-arm64" *.o

cd ..

# 合并x86_64与arm64
rm -rf merge
mkdir -p merge/arm64_x86_64

lipo -create ios_sim_arm64/$PROJECT_NAME.framework/$PROJECT_NAME-sim-arm64 ios_sim_x86_64/$PROJECT_NAME.framework/$PROJECT_NAME -output merge/arm64_x86_64/$PROJECT_NAME

rm -rf ios_sim_arm64/$PROJECT_NAME.framework/$PROJECT_NAME-sim-arm64

lipo -info merge/arm64_x86_64/$PROJECT_NAME

cp -R merge/arm64_x86_64/$PROJECT_NAME ios_sim_arm64/$PROJECT_NAME.framework/

lipo -info ios_sim_arm64/$PROJECT_NAME.framework/$PROJECT_NAME

rm -rf $PROJECT_NAME.xcframework

# 创建 xcframework
xcodebuild -create-xcframework \
-framework iphoneos/$PROJECT_NAME.framework \
-framework ios_sim_arm64/$PROJECT_NAME.framework \
-output $PROJECT_NAME.xcframework

rm -rf ios_sim_arm64
rm -rf ios_sim_arm64.xcarchive

rm -rf ios_sim_x86_64
rm -rf ios_sim_x86_64.xcarchive

rm -rf iphoneos
rm -rf iphoneos.xcarchive

rm -rf merge
rm -rf temp

echo "编译完成. xcframework地址: $OUTPUT_DIR/$PROJECT_NAME.xcframework"

如果你直接拷贝了脚本,那么恭喜你,会傻眼的. 继续往下看.

首先从git上下载arm64-to-sim, 根据README.md上面的领命令, 直接在终端上运行。

cd arm64-to-sim
swift build -c release --arch arm64 --arch x86_64

然后回到脚本里面, 找到ARM64_TO_SIM_PATH, 使用arm64-to-sim可执行文件的全路径替换掉内容

最后回到项目里, 在终端里面执行

sh build-workspace.sh ./Your.xcworkspace

愉快的编译吧!!!

还没完事, 发没发现脚本的名字是build-workspace,那是因为我的工程已经执行过pod生成了xcworkspace, 还有一些依赖库所以才写的这个脚本,如果你是纯framework工程,那么只需要将**-workspace** 修改为 -project, 具体还得自己调一下

参考文章:
Hacking native ARM64 binaries to run on the iOS Simulator
From Fat Frameworks to XCFrameworks, or how to support arm64 for iOS Simulators
Creating a multiplatform binary framework bundle

你可能感兴趣的:(Xcode,iOS,xcframework,cocoa,macos,objective-c)