iOS上动态库依赖避免符号和版本冲突问题
今天交付了一个功能库,但是同事反馈运行时有崩溃
dyld[33893]: Library not loaded: @rpath/eslog.framework/eslog
Referenced from: <EF42CD7A-4A3B-3413-9661-928323F63135> /private/var/containers/Bundle/Application/CE99316C-B01C-472D-8C1E-B62B490C5284/iOSDemo.app/Frameworks/MHUltrasound.framework/MHUltrasound
Reason: tried: '/private/var/containers/Bundle/Application/CE99316C-B01C-472D-8C1E-B62B490C5284/iOSDemo.app/Frameworks/eslog.framework/eslog' (no such file), '/private/var/containers/Bundle/Application/CE99316C-B01C-472D-8C1E-B62B490C5284/iOSDemo.app/Frameworks/MHUltrasound.framework/Frameworks/eslog.framework/eslog' (code signature invalid in <D800E115-8EEC-34BE-8DCA-4849B3C88C41> '/private/var/containers/Bundle/Application/CE99316C-B01C-472D-8C1E-B62B490C5284/iOSDemo.app/Frameworks/MHUltrasound.framework/Frameworks/eslog.framework/eslog' (errno=1) sliceOffset=0x00000000, codeBlobOffset=0x0008B1D0, codeBlobSize=0x00006540), '/private/var/containers/Bundle/Application/CE99316C-B01C-472D-8C1E-B62B490C5284/iOSDemo.app/Frameworks/eslog.framework/eslog' (no such file), '/private/var/containers/Bundle/Application/CE99316C-B01C-472D-8C1E-B62B490C5284/iOSDemo.app/Frameworks/eslog.framework/eslog' (no such file), '/private/var/containers/Bundle/Application/CE99316C-B01C-472D-8C1E-B62B490C5284/iOSDemo.app/Frameworks/eslog.framework/eslog' (no such file), '/private/var/containers/Bundle/Application/CE99316C-B01C-472D-8C1E-B62B490C5284/iOSDemo.app/Frameworks/eslog.framework/eslog' (no such file), '/System/Library/Frameworks/eslog.framework/eslog' (no such file, not in dyld cache)
注意看报错(code signature invalid in <D800E115-8EEC-34BE-8DCA-4849B3C88C41>
我这里给出去的是A库,但是A库下面动态链接了B库,一开始我考虑为了方便,把B库Embed & sign in到A库中,然后就出现了上面的签名问题。
并且从上面的报错可以看到,除非强指定rpath搜索路径,不然它会默认从app的Frameworks目录下开始搜索。
这里其实暴露了两个问题
- 如何解决该签名问题
解决方式是把B库暴露在和A库同一级目录下,为了达到这个目的,我们可以在podspec中加上如下代码
spec.vendored_frameworks = 'B.framework'
这样cocoapods在安装时会把他们作为同一级目录安装,到时候在app的产物目录下也会出现在Frameworks同一级目录。
- 引申问题,假设B库作为一个基础库,后续被开发同事在引用其他库时也用到了,比如现在导入C库,C库也引用到了B库,A和C同时依赖了B,如果不把B库推到线上统一管理,那么A和C依赖的B库版本不一致,很可能后面会出现一些奇奇怪怪的符号崩溃问题或者ABI不稳定出现链接问题。