问题背景
项目使用了ZFPlayer,其中包含了IJKMediaFramework三方库, 最后打包的时候报错
IJKMediaFramework Undefined symbols for architecture armv7
Undefined symbols for architecture armv7:
"_avio_open_dyn_buf", referenced from:
_vtbformat_init in IJKMediaFramework(IJKVideoToolBoxAsync.o)
_decode_video_internal in IJKMediaFramework(IJKVideoToolBoxAsync.o)
_vtbformat_init in IJKMediaFramework(IJKVideoToolBoxSync.o)
_decode_video_internal in IJKMediaFramework(IJKVideoToolBoxSync.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Showing first 200 notices only
命令行查看库信息:
lipo -info IJKMediaFramework.framework/IJKMediaFramework
Architectures in the fat file: IJKMediaFramework.framework/IJKMediaFramework are: armv7 i386 x86_64 arm64
解决办法
在Xcode architecture 去掉armv7的指令;
思考
为了彻底弄明白,为什么要去掉armv7 和 去掉之后带来的影响,列了几个自己疑问?
什么是ARM结构?
armv6、armv7、armv7s、arm64、arm64e、x86_64、i386 有什么区别?
Xcode中的 Architectures是什么?
不同版本Xcode配置差异?
-
ARM架构
ARM架构:进阶精简指令集机器(Advanced RISC Machine,更早称作:Acorn RISC Machine)是一个32位精简指令集(RISC)处理器架构,ARM处理器非常适用于移动通讯领域,符合其主要设计目标为低耗电的特性。
ARM和Intel处理器的第一个区别是,前者使用精简指令集(RISC),而后者使用复杂指令集(CISC)。
这里是设备对应的Achitectures指令集:
ARM CPU的不同指令集| 对应设备 armv7 iPhone 3GS,iPhone4,iPhone 4s,iPad,iPad2,iPad3(The New iPad),iPad mini,iPod Touch 3G,iPod Touch4 armv7s iPhone5, iPhone5C,iPad4,iPod5 arm64 iPhone5s,iPhone6、7、8,iPhone6、7、8 Plus,iPhone X,iPad Air,iPad mini2(iPad mini with Retina Display), arm64e XS/XS Max/XR/ iPhone 11, iPhone 11 pro x86_64 模拟器64位处理器 i386 模拟器32位处理器测试
armv6|armv7|armv7s|arm64 | arm64e 都是ARM处理器的指令集,这些指令集都是向下兼容的,例如armv7指令集兼容armv6,只是使用armv6的时候无法发挥出其性能,无法使用armv7的新特性,从而会导致程序执行效率没那么高。
Architectures是什么?
iOS项目打包或者只是在项目里面调用第三方静态库抑或是自己新建一个静态库,就要无可避免的和Architectures打交道。
什么是Architectures?
architectures:n. 建筑;架构(architecture的复数)。
关于Xcode中的Architectures 和 Valid Architectures
Architectures 指定工程支持的指令集的集合,如果设置多个architecture,则生成的二进制数据包会包含多个指令集代码,体积会变大。
Valid Architectures 有效的指令集集合,Architectures与Valid Architectures 的交集来确定最终的数据包包含的指令集代码。 Xcode9.1创建的工程,Valid Architectures默认有这几个:armv7 armv7s arm64,说明目前默认最低支持到iPhone5,也就是iOS8(iPhone5才能使用iOS8)
二者的区别和联系:
Valid Architectures表示的是你的项目所支持的处理器架构列表,是一个大的集合,而Architectures表示的是你的项目编译的时候最终生成的二进制文件包含的处理器架构集合。
不同版本Xcode 怎么配置?
-
Build Settings -> Architectures,Release下设置为arm64
Architectures指定工程被编译成可支持哪些指令集类型,支持的指令集越多,就会编译出多个指令集代码的数据包,ipa包就会变大。默认的standard architectures(armv7,arm64) 参数,打的包里面有32位、64位两份指令集。如果不需要32位的,可以在other中更改支持的指令集,从而使ipa包变小。
❝
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: XS/XS Max/XR/ iPhone 11, iPhone 11 pro x86_64: 模拟器64位处理器 i386: 模拟器32位处理器
注意:Xcode 12之后,没有了Valid Architectures选项的设置。另:如果把Architectures从standard architectures(armv7,arm64)改为arm64,则会发现target无法选择模拟器运行了,所以建议Debug模式下修改为arm64、x86_64或者不修改,Release下设置为arm64。
更新:经朋友指点,这个地方Architectures的设置,还有另外一种设置方法,Architectures不修改,Excluded Architectures中设置Release模式下 Any iOS SDK -> armv7,也可以实现同样的效果。设置了之后,就是Release下把armv7的指令集排除在外。选中target会发现默认设置了 Any iOS Simulator SDK -> arm64,意思是模拟器的时候排除arm64指令集。
如下:
重点建议查看这篇文章:作者通过优化从22MB降低到13.2M ,后续通过资源图片优化降低到10.3M 直接减少一半多;
jishuin.proginn.com/p/763bfbd5b… (App瘦身之Xcode打包配置调优)
参考链接
cloud.tencent.com/developer/a…
jishuin.proginn.com/p/763bfbd5b… (App瘦身之Xcode打包配置调优)