最近接手老项目,遇到了一个很头痛的问题呢,报错信息如下:
A linker snapshot was created at:
/tmp/(项目名)-2020-00-14-141251.ld-snapshot
ld: Assertion failed: (memberIndex != 0), function makeObjectFileForMember, file /Library/Caches/com.apple.xbs/Sources/ld64/ld64-530/src/ld/parsers/archive_file.cpp, line 389.
clang: error: linker command failed with exit code 1 (use -v to see invocation)
基本这是所有有用的信息了,网上查了很多资料,基本都是clean、卸载Xcode、重新拉代码诸如此类的,可能误打误撞起了些许作用,但是无法找到问题根源所在,还是不能有效的解决此类问题。这种问题,最难的还是错误信息中没有给出明确的是哪个地方出了问题,如果是自己开发的项目,你可能轻易的知道是因为你做了某种操作后引起的,但是如果是维护别人遗留的n年前的项目,还是很能让人头痛一阵子的。
问题根源
关于archive_file.cpp
以上是archive_file.cpp的源文件,copy下来之后可以发现是makeObjectFileForMember方法中assert(memberIndex != 0)出了问题,但是由于对C++不太熟悉,没办法过多深究,有兴趣的朋友可以好好钻研下。
关于错误原因这篇可以好好看看,指出了问题所在,静态库出了问题。
解决办法
1.因为linker command failed with exit code 1基本都是由于找不到文件链接造成的,针对此问题,一般错误信息都会标明duplicate或者相关库、文件名,因此可以迅速定位。
2.可以好好检查下Build Setting ->library search path里面的路径是否能正确连接到相应文件。
3.检查所有路径之后,确定路径无误后,只有从Build Phases ->Link Binary With Libararies下手了,由于是接手的老项目,无法确定是哪个静态库出了问题,就记录下所有.a文件,然后从中删除,运行之后逐个添加,最终确定是某个静态库无法编译通过,重新下载添加对应第三方sdk后,程序便可以正常运行了。
额外
关于这个bug定位过程中,偶然试到一个方法,将Other Linker Flag里面的-ObjC删除后,程序也可以编译通过,但是程序运行起来之后会出现unrecgnized selector send to ....... 之类的错误,这是因为加上-ObjC选项的时候,链接器便会加载静态Library里面所有Objective-C实现的类和Cateogry。所以删除-ObjC后只是将有问题的静态库推迟到运行之后编译,故会产生bug修复的错觉。