静态库在特定项目中使用框架

Thy*_*hys 19 xcode objective-c ios

我创建了一个包含所有泛型类的静态库.其中一些类使用框架.

现在我有两个项目,一个使用一些使用框架的类,另一个不使用任何使用框架的类.

因为静态库不支持包含框架(如果我是正确的).我必须在使用它们的项目中包含框架.但是,当我编译不使用任何框架类的项目时,编译器会中断,因为它仍然需要框架.现在我知道它试图从库中编译所有(未使用的)类,因为我使用链接器标记'-ObjC'来防止'无法识别的选择器'错误.

有谁知道如何只为每个项目编译所需的源文件?并且防止所有框架必须包含在使用我的静态库的所有项目中?

ser*_*gio 15

首先,你是对的,静态库不能包含任何框架或其他静态库,它只是构成该特定静态库的所有目标文件(*.obj)的集合.

有谁知道如何只为每个项目编译所需的源文件?

默认情况下,链接器仅链接来自包含应用程序引用的符号的静态库的目标文件.因此,如果您有两个文件a.m并且b.m在静态库中并且只使用a.m主程序中的符号,那么b.o(从中生成的目标文件b.c)将不会出现在最终的可执行文件中.作为子案例,如果b.m使用c仅声明(未实现)的函数/类,则不会出现任何链接器错误.只要b.m在程序中包含一些符号,b.o也会链接,并且由于缺少实现,您将收到链接器错误c.

如果您希望这种选择发生在符号而不是对象级粒度,请在Xcode中启用死代码剥离.这对应于项目的"构建设置信息"窗格中的gcc选项-Wl,-dead_strip(=链接器选项-dead_strip).这将确保进一步优化.

但是,在您的情况下,正如您所说的那样,使用"-ObjC"链接器标志会破坏此机制.所以这实际上取决于你.如果删除-Objc标志,则可以免费获得您喜欢的行为,同时对选择器进行更严格的检查.

并且防止所有框架必须包含在使用我的静态库的所有项目中?

Xcode/GCC支持一种称为" 弱链接 " 的链接选项,它允许懒惰地加载框架或静态库,即,仅当实际使用其中一个符号时."弱链接"可以通过链接器标志(参见上面的Apple文档)或通过Xcode UI(目标 - >信息 - >常规 - >链接库)启用.

无论如何,框架或库在编译/链接时必须在所有情况下都可用:"弱"选项仅影响框架在运行时首次加载的时刻.因此,我不认为这对您有用,因为您无论如何都需要在所有项目中包含框架,这是您不想要的.

作为旁注,weak_linking当使用仅在较新的SDK版本(例如,4.3.2)上提供的功能时,这个选项最有意义,同时还支持在较旧的SDK版本(例如,3.1.3)上进行部署.在这种情况下,您依赖于以下事实:较新的SDK框架将在较新的部署设备上实际可用,并且您有条件地编译需要它的功能,以便在旧设备上不需要它们(并且不会因此而产生)尝试加载更新版本的框架和崩溃).


更糟糕的是,GCC不支持与Microsoft编译器称为"自动链接"的功能,允许通过源文件中的#pragma注释指定要链接的库.这可以提供一种解决方法,但不存在.


所以,我很遗憾不得不说你应该使用一种同样满足你需求的不同方法:

  1. 删除-ObjC标志;

  2. 根据外部框架的依赖关系将静态库拆分为两个或多个部分;

  3. 诉诸于直接包含源文件.


Vin*_*rci 5

在问题的第二部分,您可以将链接框架标记为Optional: 可选框架

关于第一部分,我不清楚你打算做什么:

  • 在项目中声明的库
  • 一个项目,声明编译了哪些文件(通过目标>构建阶段>编译源)
  • 除非设置复杂的构建规则以包含或不包含文件,如果我记得很清楚可以使用.xcconfig文件完成,除了拆分库之外我没有看到任何其他解决方案.我会推荐,因为它很容易.你甚至应该在同一个项目中做几个目标...你也可以使用预编译器MACROS(#ifdef...)但这取决于你想做什么.