Apple M1设备使用fastlane运行iOS单元测试报Alamofire缺失问题
问题根因
该问题本质是Apple Silicon(M1)设备上Xcode GUI启动模式与命令行执行环境的架构不匹配,导致依赖模块找不到:
- 本地勾选Xcode「Open using Rosetta」时,Xcode进程、xcodebuild调用、DerivedData下的编译产物全部按x86_64架构生成,因此构建、测试都能正常跑
- Gitlab Runner默认以原生arm64架构启动进程,调用
fastlane ios test时未走Rosetta转译,依赖搜索路径下找不到对应arm64架构的Alamofire编译产物,就会抛出no such module 'Alamofire'错误 - 构建环节能正常通过,是因为
ios buildlane大概率自定义了架构参数,或者主target构建设置默认兼容双架构,但test target的架构配置、依赖链接规则没有和主target对齐。
排查思路
- 先在CI流水线脚本最前端加
arch命令打印当前执行环境架构,同时执行xcode-select -p确认调用的Xcode路径和本地开Rosetta使用的Xcode完全一致 - 确认依赖管理方式:如果用CocoaPods,检查Podfile是否存在强制限定架构的配置;如果用SPM,查看DerivedData下Alamofire的编译产物,确认是否包含当前执行环境对应架构的二进制slice
- 对比fastlane中
ios build和ios test两个lane的配置,检查build lane里是否通过xcargs传入了指定架构的参数,而test lane遗漏了相同配置 - 检查单元测试target的Build Settings,确认
Excluded Architectures、VALID_ARCHS、Framework Search Paths三项配置和主App target完全一致
解决方案
按落地成本从低到高排序,优先试第一种:
方案1:对齐本地Rosetta执行环境(无项目侵入,最快解决)
完全复现本地勾选Rosetta跑通的环境,不需要改项目代码配置:
- 如果是用launchd托管Gitlab Runner,直接修改Runner启动的plist配置,在启动参数前加
arch -x86_64强制进程以x86_64架构运行:
<key>ProgramArguments</key> <array> <string>arch</string> <string>-x86_64</string> <string>/bin/bash</string> <string>/path/to/your/gitlab-runner/start.sh</string> </array>
修改后执行launchctl unload、launchctl load重启Runner生效。
2. 如果不想修改全局Runner配置,直接在fastlane的test lane中给scan传入架构参数,强制编译x86_64版本:
lane :test do scan( xcargs: "ARCHS=x86_64 ONLY_ACTIVE_ARCH=YES VALID_ARCHS=x86_64", destination: "platform=iOS Simulator,name=iPhone 15,OS=latest" ) end
如果你用CocoaPods管理依赖,建议在Podfile末尾加post_install钩子,统一给所有Pod target设置相同架构,避免依赖和主工程架构不一致:
post_install do |installer| installer.pods_project.targets.each do |target| target.build_configurations.each do |config| config.build_settings['ARCHS'] = 'x86_64' config.build_settings['ONLY_ACTIVE_ARCH'] = 'YES' config.build_settings['VALID_ARCHS'] = 'x86_64' end end end
加完后记得重新执行pod install再跑流水线。
方案2:全流程适配原生arm64架构(无Rosetta依赖,长期方案)
如果不想依赖Rosetta转译,要全链路跑原生arm64,按以下步骤调整:
- 关闭Xcode的Rosetta选项,执行
rm -rf ~/Library/Developer/Xcode/DerivedData/*清空所有历史编译缓存 - 重新执行依赖安装命令(CocoaPods就跑
pod install,SPM就在Xcode里Reset Package Caches),确保所有依赖编译出arm64模拟器对应的二进制slice - 检查所有target(主App、单元测试、所有第三方依赖target)的Build Settings:
- 删除
Excluded Architectures配置下「Any iOS Simulator SDK」对应的arm64排除规则(多数老项目会加这个规则,导致模拟器编译时找不到arm64依赖) - 将Debug配置下的
Build Active Architecture Only设为YES
- 删除
- 先在本地不开Rosetta的Xcode里确认单元测试能正常跑通,再把对应配置同步到CI的fastlane脚本中。
方案3:临时验证方案
如果需要快速验证流水线逻辑,可以在执行fastlane ios test前通过命令修改Xcode的Rosetta默认启动配置,测试完成后再改回:
# 开启Xcode Rosetta模式 defaults write com.apple.dt.Xcode Rosetta -bool YES # 执行测试 fastlane ios test # 关闭Rosetta模式 defaults write com.apple.dt.Xcode Rosetta -bool NO
内容的提问来源于stack exchange,提问作者Giribabu
相关产品推荐
相关产品推荐

