如何正确地链接具有公共静态库的静态库?

6
我正在开发一个名为Silicon的静态库,用于我所有的iOS应用程序。
因为我不想创建一个可能难以维护的庞大静态库,所以我创建了许多较小的静态库作为子模块附加。
截至本文撰写时,Silicon的依赖树如下:

硅谷
|
|==> FDKeychain
|==> FDDataClient
        |
        |=> FDRequestClient
                |
                |=> FDFoundationKit
|==> FDSQLiteDatabase
        |
        |=> FDFoundationKit

正如您所看到的,FDRequestClient和FDSQLiteDatabase都有一个共同的静态库FDFoundationKit。

似乎发生的情况是,当使用Silicon构建项目时,它会将所有Silicon目标依赖项构建到项目的构建目录中。FDDataClient和FDSQLiteDatabase也会发生同样的事情。因此,在某个时刻,来自FDRequestClient的FDFoundationKit被构建并复制到构建目录中,以及来自FDSQLiteDatabase的FDFoundationKit。无论哪一个最后被构建,都会覆盖之前的那个。
仅仅凭借运气,FDFoundationKit没有以任何严重的方式发生变化,这样FDRequestClient和FDSQLiteDatabase就可以始终使用相同的版本,但我不能保证它会一直像这样。
我正在尝试找出是否有一种方法让Silicon指定要使用的FDFoundationKit版本,这样Silicon就需要负责确保所使用的版本适用于FDRequestClient、FDSQLiteDatabase以及未来添加的任何其他依赖项。
我知道CocoaPods试图解决这个问题,但我不想让别人为了让我的库工作而设置所有这些。如果我能找到某种方式让Silicon定义要使用的FDFoundationKit版本,那么一切都将完美地运行。

你不想使用CocoasPods,因为你“不想让别人为了让我的库工作而设置所有这些”。我相信大多数其他用户提出的建议会比你进行一次私有CocoaPods的设置更耗费时间和精力。 - Emilie
2
但对于使用Silicon的用户来说,不需要进行任何设置。他们只需链接静态库,一切都可以正常工作。如果我转向CocoaPods,那么想要使用这个库的每个人都需要拥有它。我正在努力为这个库做前期工作,以确保如果您链接它,它将正确构建。 - Reid Main
2个回答

0

您可以(就像我们一样)将所有库放入框架中,因为框架支持版本控制。框架只是按照通用方式配置的目录树。Xcode不直接支持创建框架,因此您必须在脚本中创建它们,通常作为构建阶段的最后一步。一个示例(感谢jverkoey)可以在IOS- framework找到。

在框架内,您可以存储每个静态库的所有版本。

myLibrary.framework->Versions->n.n folders. 

myLibary.framework->Versions->Current 是指向最新版本文件夹的链接。

由于您正在使用静态库,因此 Silicon 本身无法指定版本(这需要动态库),但用于构建 Silicon 的构建器、链接器或环境标志可以。

通过这种方式,默认情况下,应用程序将始终使用库的最新版本,但在构建时实际链接的版本可以轻松地被链接器标志覆盖。此外,所有用户都将像任何其他框架一样简单地将 Silicon 框架包含在其项目中,因此对开发人员来说非常简单。


2
我认为问题不在于版本控制,而在于当相同符号在多个静态库(存档)中可见时出现重复符号的情况,无论您如何构造这些存档。动态链接库没有这个问题。 - CouchDeveloper
OP只提到版本控制是问题。 - Some Developer
我已经将Silicon从静态库切换到框架,并且@CouchDeveloper是正确的,我确实希望确保没有重复的符号。我的理想情况是,对于我所有的开源项目,我可以使一个依赖于另一个,但如果有人使用了我两个具有相同依赖项的框架,他们不会发生冲突。 - Reid Main

0

这个问题似乎只有两个答案:

1)使用像CocoaPods或Carthage这样的依赖管理器。

2)您发布的任何静态库或框架都不应具有任何目标依赖项。 它们应链接到您拥有的任何依赖项,整合您的库的责任也是整合所需依赖项的人的责任。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接