如何避免“重复符号”共享静态库的 xcode 中出现错误?
我将静态库 A、B 和 C 组织到 Xcode 项目中。 A 和 B 依赖于 C。当我构建依赖于 A 和 B 的 iPhone 项目时,我收到链接器错误,指出在 A 和 B 中检测到重复符号(来自 C)。我如何组织这三个静态库,以便我可以将它们包含在其他 Xcode 项目中而不会遇到此错误吗?
I have static libraries A, B and C organized into Xcode projects. A and B depend on C. When I build an iPhone project that depends on A and B, I get a linker error that a duplicate symbol (from C) was detected in A and B. How can I organize these three static libraries so I can include them in other Xcode projects without experiencing this error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Carl 的答案是正确的,但原因是错误的:将静态库链接在一起实际上没有任何问题,正如我们使用 Carl 自己的示例所看到的那样。设置 Carl 的示例代码,然后执行以下操作:(我使用 libtool,因为 XCode 使用的是 libtool)
这将 a2.a 和 b2.a 与 main.o 链接。根据 Carl 的说法,这是 OP 问题的根源,app2 不应该链接。但当然是这样。链接器足够聪明,可以忽略同一文件的两个实例。我们可以看到 a2.a 和 b2.a 都包含 co:
但它链接得很好。
我认为,问题与通用二进制文件有关,无论是 PPC/x86 通用二进制文件,还是 armv6/armv7 iPhone 通用二进制文件。这里的问题是 类别 存在错误,并且该修复(将 -all_load 添加到链接器标志)是仅适用于单一体系结构的修复。使用 -all_load 会破坏链接器忽略为多个体系结构定义的符号的能力,并且您会遇到重复符号错误。
我写了关于它这里 包括比使用 -all_load 更好的解决方案。
Carl's answer is right, but for the wrong reasons: there's actually nothing wrong with linking static libraries together, as we can see using Carl's own sample. Set-up Carl's sample code and then do this: (I use libtool because that is what XCode uses)
This links a2.a and b2.a with main.o. According to Carl, this is the source of OPs problem, and app2 shouldn't link. But of course it does. The linker is smart enough to ignore two instances of the same file. We can see that both a2.a and b2.a contain c.o:
Yet it links fine.
The problem is, I believe, linked to Universal Binaries, either PPC/x86 universal binaries, or armv6/armv7 iPhone universal binaries. The problem here is that there is a bug with categories and the fix (add -all_load to the linker flags) is a fix that only works for single architectures. Using -all_load breaks the linkers ability to ignore symbols that are defined for multiple architectures, and you have your duplicate symbol error.
I wrote about it here including a better solution than using -all_load.
使用
-all_load
的替代方法是仅对需要的库使用-force_load
“path_to_lib”。例如,您可以使用类似以下内容的内容:-force_load "$(PROJECT_DIR)/libname"
。这避免了您需要对 Jamie 的解决方案执行的操作,该解决方案需要您修改实现文件。
这是 Three20 项目采用的解决方案:http://groups。 google.com/group/third20/browse_thread/thread/ec208be4ff8b4dcb/0dccf992a26850df
编辑:从 Xcode 4.3 开始,需要
-all_load
和-force_load
已被删除。现在只需要-ObjC
。有关更多详细信息,请参阅 https://stackoverflow.com/a/2615407/211292。A alternative to using
-all_load
is to use-force_load
"path_to_lib" just for the libraries where it is needed. For example, you can use something like:-force_load "$(PROJECT_DIR)/libname"
.This avoids what you need to do for Jamie's solution which requires you to modify implementation files.
This is the solution adopted by the three20 project: http://groups.google.com/group/three20/browse_thread/thread/ec208be4ff8b4dcb/0dccf992a26850df
edit: as of Xcode 4.3 the need for
-all_load
and-force_load
has been removed. Now only-ObjC
is needed. See https://stackoverflow.com/a/2615407/211292 for more details.这个问题不一定与 Xcode 或 Objective-C 相关。不要将库链接/归档到其他库中。 A& B 仅在最终链接时依赖于 C,而不是在构建时依赖于 C。您想要:
这是我用来演示的示例项目:
Makefile:
ac:
bc:
cc:
main.c:
Build and run log:
This problem isn't necessarily Xcode or Objective-C related. Don't link/archive libraries into other libraries. A & B only depend on C at final link time, not when they're built. You want:
Here's an example project I made to demonstrate:
Makefile:
a.c:
b.c:
c.c:
main.c:
Build and run log: