整理一下脑子里混乱的Architectures

6,357 阅读4分钟

while.png

前言

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

image.png

这个EXCLUDED_ARCHSExcluded 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的:

image.png

要解决这个问题,我们需要将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支持。

image.png

是不是很简单?只要理解了几个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