在XCode中使用静态库时,必须将二进制文件与库链接两次

时间:2012-09-07 17:07:32

标签: objective-c xcode static-libraries static-linking xcode4.4

我正在尝试在项目中使用静态库。静态库依赖于几个框架...... CoreData,CFNetwork,AddressBook等

静态库也使用类别,因此我不得不在主项目的“其他链接器设置”中使用-all_load链接器选项。当我启用它时,我得到120个错误,所有错误都与我的主项目有关,而不是与我的静态库(CoreData,CFNetwork,AddressBook等)相同的框架链接。

开发人员想要使用静态库,链接到它是非常不方便的,但仍然需要链接到库链接到的所有框架。有没有办法自动化这个过程,以便主项目自动链接到静态库链接的所有框架?

我正在使用XCode 4.4。

编辑:为了更清楚,我有以下内容:

StaticLibrary.xcodeproj
    - AFNetworking
        - files...
    - CoreData
        - categories for NSManagedObjectContext, for convenience
    - AddressBook
        - convenience methods for working with contacts

该项目的目标与Build Phases>下的必要框架相关联。链接二进制文件库。这包括CoreData.framework,AddressBook.framework等。

现在我想做的是将这个库添加到我的另一个项目中。事实上,我想将这个库添加到我从现在开始的每个新项目中,所以我总是可以轻松访问我编写的便利功能/类别。所以:我将库添加到我的项目中,然后将.a文件添加到Build Phases> Link Binary With Libraries(我的主要项目)。我还做了我所知道的其他所有必要的事情(见评论)。

我想要发生的事情:主项目现在链接到库,因此它继承了所有库的链接,因此主项目现在也链接到CoreData.framework,AddressBook.framework等。

发生了什么:主项目给了我错误,因为它没有链接到库所需的任何内容。

有没有办法自动将链接框架从静态库添加到主项目,或者我应该将库拆分为CoreDataStaticLibrary等,然后要求开发人员添加CoreData.framework以及静态库每次到项目目标?

2 个答案:

答案 0 :(得分:1)

据我了解,如果您的图书馆仅包含类别,则您只需要-all_load。否则,您可以使用-ObjC。无论如何,这就是我的用途。

此外,在构建静态库时,您只需创建已编译对象模块的存档。库中没有解析外部依赖项。实际上,您应该将其视为一堆目标代码文件的单个集合。

因此,当您最终链接可执行文件时,它将链接所有已编译的代码,以及静态库中预编译代码的存档。链接器期望解析所有符号,因此您必须告诉它在哪里找到完全解析所有符号所需的所有库(框架)。

XCode应该能够查看静态库子项目并从该项目中提取框架依赖项并将它们添加到最终项目的链接器调用中吗?当然。但是,我不知道如何自动实现这一目标。

如果需要,可以为库创建podfile,并使用CocoaPods来管理项目依赖项。

答案 1 :(得分:0)

问题是你要多次包含相同的符号。我已经多次遇到同样的问题,解决方案基本上是要理解“-all_load”标志的作用,这在SO问题中得到了很好的解释:What does the all load linked flag do

说,你永远不会以这种方式引用你的库中的框架。由于这些框架是动态链接的,因此它们并不属于您的静态库,只有引用它们的引用。

此类库的用户应负责添加必要的框架以使其正常工作。这意味着,您不必将您的库链接到这样的框架(因为这样的事情没有意义),只需将它们添加到将要使用它的项目中。 (看看Restkit看看它是如何完成的。)

另外,我认为您可以摆脱“all_load”标志并尝试将其替换为“force_load / path / to / the / library”all_load仅在您的库仅包含类别(根本没有类别)时才需要)。

让我们知道它是如何进行的和快乐的编码!