M系Mac集成三方框架跑模拟器遇到的问题

引用一些三方库后,如果是模拟器运行在编译过程中可能会遇找不到对应指令集文件的错误,以创蓝闪验的SDK为例:


image.png

先说解决方案,再说这个错误的原因

如果想继续用模拟器跑项目,就需要用Rosetta版本的模拟运行,打开Rosetta模拟器显示:

image.png

模拟器选择Rosetta版本:

image.png

这个时候就能成功编译并运行项目了。

但是刚开始运行,除了列表滑动没有惯性交互外没什么大问题,但修改几行代码或者过段时间Command + R,模拟器就会卡死并黑屏,XCode也一直转圈,最终只能重新启动模拟器。

image.png

造成这个现象的原因是因为XCode和模拟器运行在不同的指令集下,两者之间通信通过Rosetta转义。

接着再说说上面编译报错的原因,在M系Mac之前,由于用的Intel芯片,模拟器是x86架构,所以在制作静态库时,会编译x86和arm两个指令集版本的二进制文件,并用lipo命令合并成.a或.framework文件。通过lipo -info或file命令查看上述SDK的mach-O文件信息如下:


image.png

说明这个SDK同时包含arm64和x86_64两个架构的指令集,这在Intel芯片下跑模拟器是没问题的,但是M系Mac本身是arm架构,所以模拟器版本的SDK就会编译报错(理论上既然包含arm64的文件,M1芯片下的xcode直接去找arm64的文件应该是可以的,所以猜测真机下的arm64跟模拟器下的arm64是不是有区别)

我通过新建一个framework项目,并编译模拟器的静态库:


image.png

然后再Products目录下查看framwork文件夹下的二进制文件结构信息如下:


image.png

这里看到的信息是跟上面SDK的信息是一样的。

开始动歪脑筋:是不是可以将SDK的arm架构单独抽出一个framework,将arm的framework和包含arm和x86的famework同时打成一个xcframework,就能解决最初的问题?答案是行不通。

由于用lipo命令查看SDK的二进制文件和我测试生成的静态库的二进制文件信息一样,于是尝试直接将SDK打成xcframework,却得到一个错误:

image.png

意思二进制文件不能包含多个平台,我自己编译的x86、arm64的二进制是针对模拟器平台,SDK的x86、arm64是模拟器和真机平台的

我用测试静态库生成xcframework,再将测试静态库的二进制文件的arm64抽离成单独的framework,同时生成xcframework,两个文件夹的目录结构分别如下:

image.png
image.png

生成的文件夹都包含了simulator关键字

而将SDK的二进制的arm64抽离成单独的framework并生成xcframework,文件夹的目录如下:

image.png

说明真机和模拟器的arm64架构还不一样?所以想让只支持x86_64模拟器的静态库通过xcframework去兼容M系模拟器想法破灭了=。=

总结:要想静态库支持M系模拟器,必须在静态库出厂的时候编译好所有架构模拟器的静态库,要不然接入方就只能真机调试,或者用Rosetta版本的模拟器(忍受性能损耗和两个架构系统之间通信的bug)。

感谢以下文章的帮助:
M1设备的Xcode编译问题深究
iOS开发 XCFramework
iOS开发之--Architectures详解

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容