iOS开发 经典错误之 library not found for -xxxl 或'xxx.h'file not found

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发 经典错误之 library not found for -xxxl 或'xxx.h'file not found相关的知识,希望对你有一定的参考价值。

参考技术A

开发中我们经常会遇到ibrary not found for -xxxl,尤其是我们从远程仓库或者github clone下来一个项目,编译很有可能报这个错误。如下图:

library not found for - lXXX 属于ios常见错误之一 ,lXXX中的l是library(库)的简写。
这种错误一般都是 没有配置Library Search Paths 或 没有正确配置Library Search Paths 导致报错所致。
解决办法:只要正确配置Library所在的准确路径即可。

关于 Library Search Paths 添加路径想说两点
1.如果我们指定的目录和静态库的目录完全不相关,直接到Library Search Paths下添加报错 静态库的准确磁盘路径
2.如果我们指定的目录和静态库的目录有关系。即,我们指定的目录是静态库所在目录的上级目录,或者是上上级目录。这种情况下,无需指定静态库的精确的路径,只需要把 non-recursive选项修改为recursive 即可

上面讲的是当我们项目导入的是.a静态库,但因为没有在 Library Search Paths 中配置.a静态库的search路径,或者是虽然配置了路径但是路径配置错误而导致出现library not found for -xxx错误的解决办法。
但我们知道,在iOS中,静态库有两种形式:.a格式的静态库和.framework格式的静态库。
那么如果我们的项目中引入了.framework格式的静态库要不要配置search路径呢?答案是肯定的, 无论我们以什么方式导入.framework静态库(cocoapods的方式或者直接把framework静态库拖拽到项目中的方式),如果没有配置framework的search路径,同样会报错,但报的错误却是和.a格式的静态库有些不同,如果我们项目中引入了framework格式静态库也使用了静态库(所谓使用就是import了framework静态库中的某个头文件),但没有配置search路径,那么就会报 xxx.h file not found 这类错误

如果我们确认设置了了 build setting -> Framework Search Paths 的路径后还是报错xxx.h file not found,那就需要配置 build setting -> header search paths 的路径
"$(SRCROOT)/Utils/RSAEncrypt(加密)/openssl"
这个路径的意思就是openssl类库在项目中所处的位置,然后加入到这里来,后面选择non-recursive即可

我们需要做的就是
1.先检查一下 Build Phases - >Link Binary With Libraries ,对应的静态库有没有添加成功。
2.在Build Settings下,搜索search ,找到Framework Search Paths、Header Search Paths 、Library Search Paths查看对应的第三方库路径是否存在,不存在就添加
3.Command + Shift + K,重新编译即可。

iOS dyld: Library not loaded crash问题

今天在引入第三方framework时,我按照以前的方法,把framework加入到了下图的地方:

默认是required的,之后程序就crash了,报错dyld: Library not loaded,之后我把required 改成了optional,这次不crash了,但是运行时出错,库中的对象无法实例化,全部是空。

我是根据http://stackoverflow.com/questions/24333981/ios-app-with-framework-crashed-on-device-dyld-library-not-loaded-xcode-6-beta解决的,就是利用Embeded Binaries选项。 

 

先看看optional 和 required 有什么区别,如下是官方的说法:

Libraries and frameworks are designated as Required by default, but you can change this designation to Optional. Required libraries must be present on the host computer for the product to load. Optional libraries do not have to be present for the product to load. A Required framework will always be loaded into memory, but an Optional framework will be loaded only if needed. The initial load of the application will be faster if a large library that is never needed is designated as Optional.

 在看看framework的官方说明:

A framework is a hierarchical directory that encapsulates shared resources, such as a dynamic shared library, nib files, image files, localized strings, header files, and reference documentation in a single package. Multiple applications can use all of these resources simultaneously. The system loads them into memory as needed and shares the one copy of the resource among all applications whenever possible.

注意,根据上面的介绍,看起来framework中只能包含 dynamic shared library 2进制文件,其实不是,framework 中也可以包含静态库2进制文件!通过下面这个参数来指定:

这里如果指定为 Static Library(framework中包含的2进制文件就是个静态库),那么当这个framework就可以只加入Linked Frameworks and Libraries 选项卡中,系统会自动识别它的类型,并链接入目标文件。而如果指定为Dynamic Library(framework 中包含的2进制文件就是个动态库) ,那么,加入到 Linked Frameworks and Libraries 选项卡中是不够的,而是需要加入到Embeded Binaries选项卡中,加入后系统会自动为你在Linked Frameworks and Libraries选项卡里加入相同framework,打开对应的ipa,会看到 framework在单独的一个文件夹中。我这里的理解是,Linked Frameworks and Libraries表示连接,动态连接也算连接,所以Embeded Binaries选项卡中中的项目也会出现在Linked Frameworks and Libraries选项卡中。

另外,如果framework中包含的2进制文件是个静态库,而我们把这个framework当成一个包含动态库的framework,添加到了Embeded Binaries选项卡中,那么程序无法通过编译,会报错的。

如何看一个framework中的2进制文件是一个静态库还是一个动态库呢?使用file 命令。

见下面的截图,一个动态库,一个静态库:

 

看到这里可以明白了,framework就是把以前的.a 和 .so 文件又包装了一层目录,加入了些其他必要的文件,比如以前用.a时需要单独引入的一系列.h文件,这样看起来更规范一些!

 

这里还有一篇好的博文 http://www.cnblogs.com/huizhang212/p/lipolib.html,说的是如何从.a除去不要的.o文件。

 

 

就是说,如果引入了第三方的动态库,这个包含动态库的framework就需要添加到 ipa包中,加载的时机看参数,如果是required,那么程序载入时就加载,如果是optional,那么是使用到时,才加载。如果引入了静态库,这个.a的链接也看参数?不都是需要把部分2进制代码链接入目标文件吗?有什么区别吗?不太明白。我觉得当使用静态库时,这个required 和 optional就没什么用了。

关于创建自定义framework,需要仔细研究一下这篇文章 http://www.cocoachina.com/ios/20141126/10322.html

 


 

又遇到了一个问题,用embeded 方式加入 lumberjack framework 后,运行时总出如下警告:

objc[2738]: Class DDTTYLogger is implemented in both /private/var/containers/Bundle/Application/621285FC-47C0-4631-A664-2764018435AD/Gamification.app/Frameworks/CocoaLumberjack.framework/CocoaLumberjack and /var/containers/Bundle/Application/621285FC-47C0-4631-A664-2764018435AD/Gamification.app/Gamification. One of the two will be used. Which one is undefined.

我搜索了工程源码,没有发现其他定义这个类的地方,之后,为了测试,我删掉了 lumberjack framework ,直接加入了lumberjack.a 进行编译,这次直接报错了!这次错误就写的很明白了,原来是工程引入的另一个.a中已经包括了lumberjack的源码,我又没有这个.a的源码,所以在工程中就搜索不到另一个定义。

这也是解决这种类似问题的小技巧吧。

以上是关于iOS开发 经典错误之 library not found for -xxxl 或'xxx.h'file not found的主要内容,如果未能解决你的问题,请参考以下文章

ios dyld: Library not loaded: @rpath/xxx.framework/xxx 之根本原因

XML 解析错误:“Not well-formed (invalid token)”,f***g/xmpp PHP library package with xmpp openfire

归档 IOS 应用程序以响应本机错误时出错:ld: library not found for -lFBReactNativeSpec

ios开发使用cocoapods倒入一堆的三方库之后开始崩溃了。发觉是导入极光引用的iOS10UserNotifications.framework导致的问题 Reason: image not f

iOS dyld: Library not loaded crash问题

ios开发之--解决“Could not insert new outlet connection”的问题。