美文网首页
记一次特殊的duplicate symbol报错,以及c++头文

记一次特殊的duplicate symbol报错,以及c++头文

作者: 小小外星人 | 来源:发表于2018-01-08 10:32 被阅读206次

    这次在集成第三方sdk的时候遇到的duplicate symbol报错十分诡异,当我的项目中有一个.mm文件的时候,再新建一个.mm文件都会有这样的报错。

    一、通常一般遇到这种错误都是由一下这几点引起的:

    1.在使用import 引入头文件时,由于疏忽,误引入.m 文件
    2.在两个文件中存在相同的C语言定义的全局变量名或是函数名
    3.在build phases里的compile sources里面有重复的文件 
    4.引入的多个库文件中有相同的部分
    

    二、针对上面的几点,分别有以下改正的方法:

    1.将import的.m文件改为 import相应的头文件即.h文件
    2.将相同的全局变量改为不同的名字  将重名的函数改为不同的名字
    3.将compile sources里面的重复文件删除多余的,只保留一个
    

    针对上面的第四点,可以采取将多个库文件合并,或者将库文件中有重复的部门删除掉,只保留一份

    比如我遇到了下面的错误:

    duplicate symbol _OBJC_IVAR_$_SSKeychainQuery._service in:
        /Users/xxx/Desktop/Desk/项目/xxx/XunFang_branch3.0/Vendors/haikang/SDK/VMSNetSDK/lib/libXCUtilityStatic.a(SSKeychainQuery.o)
        /Users/xxx/Library/Developer/Xcode/DerivedData/Fieldworks-dqsfehkzzjszdiegdupnszgaazsk/Build/Products/Debug-iphoneos/libXBIMKit.a(SSKeychainQuery.o)
    duplicate symbol _OBJC_IVAR_$_SSKeychainQuery._passwordData in:
        /Users/xxx/Desktop/Desk/项目/xxx/XunFang_branch3.0/Vendors/haikang/SDK/VMSNetSDK/lib/libXCUtilityStatic.a(SSKeychainQuery.o)
        /Users/xxx/Library/Developer/Xcode/DerivedData/Fieldworks-dqsfehkzzjszdiegdupnszgaazsk/Build/Products/Debug-iphoneos/libXBIMKit.a(SSKeychainQuery.o)
    duplicate symbol _OBJC_CLASS_$_DDAbstractDatabaseLogger in:
        /Users/xxx/Desktop/Desk/项目/xxx/XunFang_branch3.0/Vendors/haikang/SDK/VMSNetSDK/lib/libXCUtilityStatic.a(DDAbstractDatabaseLogger.o)
        /Users/xxx/Library/Developer/Xcode/DerivedData/Fieldworks-dqsfehkzzjszdiegdupnszgaazsk/Build/Products/Debug-iphoneos/libXBIMKit.a(DDAbstractDatabaseLogger.o)
    duplicate symbol _OBJC_METACLASS_$_DDAbstractDatabaseLogger in:
        /Users/zhaotian/Desktop/Desk/项目/xxx/XunFang_branch3.0/Vendors/haikang/SDK/VMSNetSDK/lib/libXCUtilityStatic.a(DDAbstractDatabaseLogger.o)
        /Users/zhaotian/Library/Developer/Xcode/DerivedData/Fieldworks-dqsfehkzzjszdiegdupnszgaazsk/Build/Products/Debug-iphoneos/libXBIMKit.a(DDAbstractDatabaseLogger.o)
    ld: 81 duplicate symbols for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    Showing first 200 warnings only
    

    1.根据错误的信息来看,两个静态库文件中有重复的类。我这里解决的办法是将其中一个静态库中把重复的类删除掉。

    2.使用lipo -info命令来查看静态库支持的指令集


    支持的指令集

    由于我现在xcode9.2打出的包都是 armv7 arm64的,所以这里只需要针对这两个指令集来分别操作

    3.先将库文件拆分成不同指令集的


    ADB24C48-6100-4478-B7DA-708C25FDCAA9.png

    4.然后分别删除armv7指令集 和 arm64指令集下重复的文件
    使用Ar -dv xxx(库文件) xxx.o(重复的文件) 命令来删除

    删除重复部分

    想查看库文件中有哪些文件可以使用 ar - t 命令

    5.合并静态库


    合并静态库

    然而我遇到的duplicate symbol错误都不是上面的原因造成的,最开始我在报错的类里面搜索“duplicate symbol _StartTime in”中的StartTime这个关键词的时候,没有搜索到有这个关键词。而且奇怪的是当我项目中有一个.mm文件的时候,再新建一个.mm文件都会有这样的报错。真是很诡异!

    报错信息

    duplicate symbol _StartTime in:
        /Users/xxxx/Library/Developer/Xcode/DerivedData/Fieldworks-dqsfehkzzjszdiegdupnszgaazsk/Build/Intermediates.noindex/Fieldworks.build/Debug-iphoneos/Fieldworks.build/Objects-normal/arm64/FWtest1.o
    /Users/xxxx/Library/Developer/Xcode/DerivedData/Fieldworks-dqsfehkzzjszdiegdupnszgaazsk/Build/Intermediates.noindex/Fieldworks.build/Debug-iphoneos/Fieldworks.build/Objects-normal/arm64/FWtest2.o
    ld: 1 duplicate symbol for architecture arm64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    

    在困扰了很久之后我开始在项目中搜索StartTime这个关键词,我发现在很多类中都有这个关键词,然后一个个的排查。终于在一个类中找到了一个可以的地方。有个相同名称的全局变量,在被其他类使用的时候,没有使用extern来声明可以被其他的类使用,最后在.h文件中在该变量前面加上FOUNDATION_EXTERN关键字后这个问题才被解决😄

    此外,在这次集成三方sdk时候,由于三方sdk是用oc和c++混编的。集成的时候很容易报错,比如说下面这个报错:


    320F8D67-3E7B-420B-8F20-B79BFAFD7BC9.png

    报错的信息显示找不到c++文件"sstream"。首先明确的一点就是编译器会去识别.mm文件是oc与c++混编的,oc与c++混编不需要什么特殊的设置,在这里加载c++的头文件是没有问题的。但是需要注意一点的是在加在c++的库文件的时候,需要在所有使用到包含了这个头文件的类文件都要使用.mm后缀。
    比如我项目中有一个叫tom的类,在该类中引用类头文件"sstream",这时候tom的.m文件后缀应该改为.mm。有一个jerry的类,引用了tom这个类,那么这时候jerry的.m文件应该改为.mm文件。

    相关文章

      网友评论

          本文标题:记一次特殊的duplicate symbol报错,以及c++头文

          本文链接:https://www.haomeiwen.com/subject/gnzugxtx.html