ObjC:如何编译包含依赖于第三方库的可选类的静态库

时间:2012-09-27 21:18:07

标签: objective-c linker static-libraries static-linking

我正在尝试找到打包静态库(让我们称之为Lib1)的最佳方法,该静态库包含一个可选类(比如ClassA),它本身需要第二个静态库(Lib2)。换句话说,只有在项目代码中引用ClassA时才需要Lib2。事情似乎工作正常,除非Lib1用于不使用ClassA的项目(因此不包括Lib2),但需要-ObjC链接器标志(因为其他项目依赖项,而不是我的)。

我正在尝试为以下三种情况提出一个简单的解决方案:
1)项目包括我的静态lib,不使用可选类,不指定-ObjC标志
2)项目包括我的静态lib,不使用可选类,但需要-ObjC标志
3)项目包括我的静态lib +第二个静态库,并且DOES使用可选类(此时我们不关心-ObjC标志)

是否有一个链接器标志可以将我的可选类从最终项目应用程序中删除,这样它就不需要第二个静态库?我想我的其他选择是发布我的静态库的多个版本,一个包含选项类(标准选项),一个不包含(替代,对于具有-ObjC要求的项目),或者可能提供存根文件,提供第二个静态库所需的所有类的空实现?这似乎可能是静态库世界中的常见问题......这种情况是否有最佳实践?

谢谢!


解决方案:

1)建议我的-ObjC用户使用-force_load。 (谢谢罗!)
2)对于不能做1的用户,我将有一个不包含ClassA

的备用版本

1 个答案:

答案 0 :(得分:6)

最佳做法是始终将最终二进制链接所需的所有静态库。您永远不应将一个静态库捆绑到另一个静态库绝对不要将一个众所周知的(即开源)静态库捆绑到您发布的静态库中。这可能会给最终消费者带来令人难以置信的麻烦,因为他们可以使用相同代码的多个版本。追踪可能来自此的错误是非常困难的。如果他们很幸运,他们只会遇到令人困惑的编译器错误。如果它们运气不好,它们的代码将以不可预测的方式运行并随机崩溃。

单独发送所有静态库。告诉您的客户他们需要链接哪些链接以进行各种配置。试图避免这种情况只会让他们的生活变得困难。

其他一些可能有用的讨论:


-ObjC标志应该阻止ClassA完全自动剥离,无论是否使用(详见TN1490)。

如果从未使用ClassA,除非在某些情况下并且您希望节省空间,您应该将ClassA移动到其自己的静态库中。或者使用#ifdef有条件地编译它。

或者,您可以删除-ObjC标志并使用-force_load分别加载任何仅限类别的编译单元(这是-ObjC用于解决的问题)。