最近在开发项目时编译三方.a时出现了冲突,原因是存在duplicate symbol。

<1>模拟器编译时,应用的即时通讯模块采用的三方库(容联云),和视频监控模块采用的三方库(海康威视)之间有冲突,无法编译通过。

<2>真机编译时,假如对other linker flags设置为-ObjC,海康威视自身的两个.a文件存在冲突,假如不设置,CorePlot框架运行时会出现“selector not recognized”然后应用崩溃。

我真是头都大了啊……

可以看到在针对模拟器架构下(x86_64)的文件会产生如下编译错误:

这种情况一般都是文件里面使用C语言定义的全局变量名或是函数名,在导入的时候因为重复产生了冲突。

解决的方法:

1.对项目buildsetting里的other linker flags进行修改。

(参考下面的博客内容)

2.假如1不行,那只能重新打包三方库了。

(删除SDK内的重复的.o重新打包,详细见:http://blog.csdn.net/djl4104804/article/details/43099061)

other linker flags:

它的设置关乎到项目编译时的链接方式。

根据一篇博客内容顺便补脑下编译过程:

“

从C代码到可执行文件经历的步骤是:源代码 > 预处理器 > 编译器 > 汇编器 > 机器码 > 链接器 > 可执行文件

在最后一步需要把.o文件和C语言运行库链接起来,这时候需要用到ld命令。源文件经过一系列处理以后,会生成对应的.obj文件,然后一个项目必然会有许多.obj文件,并且这些文件之间会有各种各样的联系,例如函数调用。链接器做的事就是把这些目标文件和所用的一些库链接在一起形成一个完整的可执行文件。Other linker flags设置的值实际上就是ld命令执行时后面所加的参数

下面逐个介绍3个常用参数:
-ObjC:加了这个参数后,链接器就会把静态库中所有的Objective-C类和分类都加载到最后的可执行文件中
-all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到-ObjC失效的情况下使用-force_load参数。
-force_load:所做的事情跟-all_load其实是一样的,但是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载

”

对于出现的问题我们一个个分析。

Q1:为什么不加-ObjC时,CorePlot会崩,出现“selector not recognized”情况?

“-Objc这个标志,和Objective-C的一个重要特性:类别(category)有关。根据这里的解释,Unix的标准静态库实现和Objective-C的动态特性之间有一些冲突:Objective-C没有为每个函数(或者方法)定义链接符号,它只为每个类创建链接符号。这样当在一个静态库中使用类别来扩展已有类的时候,链接器不知道如何把类原有的方法和类别中的方法整合起来,就会导致你调用类别中的方法时,出现"selector not recognized",也就是找不到方法定义的错误。为了解决这个问题,引入了-ObjC标志,它的作用就是将静态库中所有的和对象相关的文件都加载进来。”

简单的说就是,在没有添加-ObjC的情况下,某些静态库中的Category函数是没有被识别的,调用该函数时没找到这个函数的指针,就报错了。

Q2:真机编译,为什么加-ObjC时,海康自身的SDK会出现duplicate symbol冲突?

在加入-ObjC标志后,编译时会把所有OC文件都加载到可执行文件中,这样的情况下,假如海康有2个OC文件中都用到同一个名字命名的变量或函数,就会出现重复定义的编译错误。

Q3:如何解决有无-ObjC的矛盾?

使用-force_load加载特定的库。

所以,目前对于真机的编译问题我已经解决了,使用-force_load $(BUILT_PRODUCTS_DIR)/libCorePlot.a 以及-force_load $(PROJECT_DIR)/FuYang/Chat/YTX_iOS_IM_SDK_v5.1.6r/lib/libCCPiPhoneSDK_IMLib.a两条规则来加载特定的.a文件,防止他们的部分函数符号没建立的情况。

Q4:对于模拟器情况下两个库之间的.a文件冲突,有无解决办法?

假如对other linker flag都未设置,却出现了duplicate symbol的情况,那通过设置该标志只会让情况更糟糕。

建议对.a库重新打包,删除部分重复的symbol。

具体如何操作.a静态库可以参考这篇文章:http://blog.csdn.net/djl4104804/article/details/43099061

iOS 解决一个因三方静态库冲突产生的duplicate symbol的问题的更多相关文章

  1. 使用Reveal.app调试整个项目UI时间,增加LD指令 -Objc引起项目中多个静态库冲突问题

    今天接触到一个新的UI调试工具教程如下: iOS真机UI调试利器——Reveal 引入增加-ObjC -framework Reveal指令后,发现项目出现多重静态库冲突问题, 首先介绍一个指令: - ...

  2. iOS 中 .a 和 .framework 静态库的创建与 .bundle 资源包的使用

    iOS 中 .a 和 .framework 静态库的创建与 .bundle 资源包的使用 前言 开发中经常使用三方库去实现某特定功能,而这些三方库通常又分为开源库和闭源库.开源库可以直接拿到源码,和自 ...

  3. iOS:Xcode7下创建 .a静态库 和 .framework静态库

    Xcode7 中创建静态库:.a 和 .framework 一.简单介绍 1.什么是库? 库是程序代码的集合,是共享程序代码的一种方式 2.库的分类 根据源代码的公开情况,库可以分为2种类型 (1)开 ...

  4. iOS项目开发常用功能静态库

    YHDeveloperTools iOS项目开发常用功能静态库 查看源码 功能方法: 1.字符检查 [NSString checkStringWithType:Email andTargetStrin ...

  5. ios 静态库冲突的解决办法

    最近在做一个 iOS 的 cocos2d-x 项目接入新浪微博 SDK 的时候被“坑”了,最后终于顺利的解决了.发现网上也有不少人遇到一样的问题,但是能找到的数量有限的解决办法写得都不详细,很难让人理 ...

  6. 【原】IOS合并lib(.a)库的终极可用方法(可用于解决duplicate symbol静态库冲突)

    网上流传了太多关于合并lib库的方法,自己也尝试过,但大多失败.有感于这种急于解决问题,经过百般尝试后依旧无果的无奈心情,小翁在这里用一个实例来完整阐述如何在mac中合并lib静态库. 这里以移动广告 ...

  7. iOS开发静态库冲突——如何查看静态库(.O)中方法名

    1.bug产生 应用第三方静态库之后提示冲突错误: 2.bug分析 一般会提示哪两个库冲突: CameraShowGLView.o是自己创建的类编译生成的: libLechangeSDK.a是添加的静 ...

  8. 静态库介绍与简单演练及同名资源冲突解决(.a格式的静态库)

    1.静态库和动态库都是闭源库,不公开源代码. 静态库:.a和.framework 动态库:.dylib和.framework(iOS9取消了.dylib,使用.tbd替代) 2.静态库和动态库在使用上 ...

  9. 静态库冲突的解决办法:duplicate symbol

    昨天在做微信sdk和xmpp的集成,发现各自单独集成没问题,一起集成却总报错,百度了好一会儿才知道,这应该是库冲突造成的问题 然后参考了很多文章,跟着敲敲一遍,却发现问题多多,最后主要综合结合了这两个 ...

随机推荐

  1. Hibernate3.3.2 手动配置annotation环境

    简单记录Hibernate3.3.2如何快速配置环境 一.下载hibernate-distribution-3.3.2.GA-dist.zip文件,建立User libraries. 打开window ...

  2. 解决Kafka-1194问题

    生产环境中使用Kafka作为日志处理的中间件,系统结构是这样的.自12月上线一个多月来,系统运行稳定. 用过kafka的都知道,Kafka产生的消息全部存储到硬盘文件中,并且在消息被消费后不会被立即删 ...

  3. sublime 函数跳转插件 — ctags 安装和使用

    ctags 是 sublime 下一个函数跳转的插件,可以让你方便地从函数调用的位置跳到函数定义的位置.相对于其他插件,ctags 的安装稍微有点复杂,这里记录下备忘. 首先,假设已经安装 Packa ...

  4. JavaScript中的类型转换(一)

    前言 JavaScript是一种非常灵活的弱类型的语言,它的灵活性的一方面体现在其繁杂多样的类型转换.比如当JavaScript期望使用一个布尔值的时候(比如if语句中)你可以提供任一类型的值,Jav ...

  5. ASP.NET文件上传大小的限制解决方案

    我们大家都知道ASP.NET为我们提供了文件上传服务器控件FileUpload,默认情况下可上传的最大文件为4M,如果要改变可上传文件大小限制,那么我们可以在web.config中的httpRunti ...

  6. web文档在线阅览

    之前遇到很多各种文档在线阅览的需求,也有不少朋友经常问我这种需求的实现方案,大致试了一下网上的一些比较主流的推荐方案,但都不尽如人意,这里有一个比较全面的总结,需要的朋友可以根据自己的需求到这里查看, ...

  7. 【python游戏编程之旅】第七篇---pygame中的冲突检测技术

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 上一个博客我们一起学习了pygame中的Sprite模块和如何加载动画:http://www.cnblogs ...

  8. android之读取联系人信息

    联系人信息被存放在一个contacts2.db的数据库中 主要的两张表 读取联系人 读取联系人需要知道联系人内容提供者的地址,以及对应的操作对象.一般情况下操作对象是的命名方式和表明是一致的. 布局文 ...

  9. C# Gabbage Collecting System

    * 这个程序非常巧妙的探测了一下垃圾回收机制,发现如下结论: * 当内存紧急时,才会启动垃圾回收GC.Collect() * 从此程序的运行上来看,delete是连续出现的,这体现了垃圾回收的强度. ...

  10. PHP 文件创建/写入

    <?php /* PHP 文件创建/写入 fopen() 函数也用于创建文件.也许有点混乱, 但是在 PHP 中,创建文件所用的函数与打开文件的相同. 如果您用 fopen() 打开并不存在的文 ...