前言
Xcode的BuildSetting
里,关于Architectures的选项一直都比较复杂,参数名称也很容易混淆,相信不少开发同学都有这样的感觉。日常开发或者升级Xcode的过程中,偶尔也会遇到Could not find module 'xxxxxxx' for target 'arm64-apple-ios-simulator
这样的问题,这种问题,基本都是Architectures配置不当导致的。
所以,这篇文章将对Architecture参数进行逐一整理,避免类似问题再次困扰我们。
一、各个Architecture参数的含义
1、Architectures
当前设备环境下支持的指令架构。真机环境下是armV7、arm64。模拟器环境下是X86_64、i386、arm64(m1设备)。
2、Build Active Architecture Only
是否只编译当前设备的指令架构。值是YES或者NO。一般Debug环境下,为了提高编译速度,会选择YES,表示只编译当前设备的指令架构。Release环境下,选择NO,编译所有类型设备的指令架构。
3、Excluded Architecture
排除的架构。排除的架构将不参与编译。例如:这里选择了arm64,编译产物将不会包含arm64指令架构。
4、VALID_ARCHS
用户自己设置的可用架构。这个选项在User-Defind
里面,它的优先级是最高的。如果Architectures
支持了很多架构,但是VALID_ARCHS
只填写了一小部分,那么实际上支持的架构也是这一小部分。所以VALID_ARCHS
的值一般和Architectures
保持一致。
5、EXCLUDED_ARCHS
在Xcode12的release note中,VALID_ARCHS
已经不推荐使用了(deprecate),我们应该使用EXCLUDED_ARCHS
:
这个EXCLUDED_ARCHS
和Excluded Architecture
是同一个意思,所以我们使用Excluded Architecture
就好了。
当然,你继续使用VALID_ARCHS
也没有什么问题。测试发现,修改VALID_ARCHS
仍然会影响编译结果。
二、iOS设备支持的指令架构
这里列举了常用iOS设备的指令架构:
armv6
iPhone, iPhone 3G, iPod 1G/2G
armv7
iPhone 3GS, iPhone 4, iPhone 4S, iPod 3G/4G/5G, iPad, iPad 2, iPad 3, iPad Mini
armv7s
iPhone 5, iPhone 5c, iPad 4
arm64
iPhone X,iPhone 8(Plus),iPhone 7(Plus),iPhone 6(Plus),iPhone 6s(Plus), iPhone 5s, iPad Air(2), Retina iPad Mini(2,3)
arm64e
iPhoneX及以上新机型
x86_64
对应64位电脑处理器的模拟器
i386
对应32位电脑处理器的模拟器
注意💡:
1、从Xcode12开始,如果你是m1设备,模拟器也支持arm64指令集。
2、不管是arm64还是arm64e,这些称呼都是ABI(Application Binary Interface),编译后对应的指令集架构(Instruction Set Architecture)都是armV8.X系列。
三、如何分离SDK指令架构
有些第三方SDK包,除了包含真机的arm架构外,还包含了模拟器的架构,对于这种类型的SDK包,是不允许提交AppStore的:
要解决这个问题,我们需要将SDK里的模拟器指令架构剥离。
下面列举了操作.a
文件指令集的常用命令:
查看.a
文件支持的指令集:
lipo -info xxx.a
合并两个.a
文件:
lipo -create xxx.a ooo.a -output hebing.a
移除某个指令集:
lipo -remove i386 xxx.a -output noi386.a
抽取某个指令集:
lipo -thin arm64 xxx.a -output onlyArm64.a
假设AipBase.a
文件包含了i386 x86_64 armv7 armv7s arm64指令架构,我们需要将其中的armv7、arm7s、arm64架构分离:
1、新建三个文件夹
mkdir armv7
mkdir armv7s
mkdir arm64
2、单独抽离指令架构
lipo ../AipBase.framework/AipBase -thin armv7 -output ./armv7/AipBase
lipo ../AipBase.framework/AipBase -thin armv7s -output ./armv7s/AipBase
lipo ../AipBase.framework/AipBase -thin arm64 -output ./arm64/AipBase
3、将多个指令架构合并
lipo -create ../armv7/AipBase ../armv7s/AipBase ../arm64/AipBase -output ../AipBase.framework/AipBase
4、再次检查合并后的指令架构是否符合你的要求
lipo -info ../AipBase.framework/AipBase
四、总结
再次回到开始说的问题:Could not find module 'xxxxxxx' for target 'arm64-apple-ios-simulator
。
1、如果你此时准备在arm64模拟器上运行,这说明你的编译产物没有arm64指令集支持,检查Buind Setting
中是否把arm64的支持去掉了。
2、如果你并没有在arm64模拟器上运行,你只是在运行某些检测工具,这说明工具在帮你使用arm64模拟器环境测试你的代码。鉴于你不想在arm64模拟器上运行代码,你可以取消模拟器的arm64支持。
是不是很简单?只要理解了几个Architecture参数的意思,解决类似问题不过是参数的增删改😄
五、参考链接
ARM处理器內核列表
Apple A15
Xcode arm64 Vs arm64e
你们说的ABI,Application Binary Interface到底是什么东西?
Submit to App Store issues: Unsupported Architecture x86
Unsupported Architectures when uploading to App Store