Xcode 4中的“bad codegen,pointer diff”链接器错误

时间:2011-03-12 22:11:54

标签: xcode ios linker linker-errors xcode4

使用Xcode 4重新编译C ++ iPhone应用程序我收到了这个讨厌的链接器错误:

ld: bad codegen, pointer diff in __static_initialization_and_destruction_0(int, int)
to global weak symbol vmml::Vector2<float>::ZERO for architecture armv6

任何人都知道这意味着什么?如何让它消失当然也会很好:)

应用编译&amp;在Xcode 3中无错误地链接。

编辑:解决方案是在项目中所有目标的所有构建设置中将默认隐藏的符号设置为。仍然没有更明智的实际问题是什么。

5 个答案:

答案 0 :(得分:18)

解决方案是在项目中所有目标的所有构建设置中将Symbols Hidden By Default设置为。仍然没有更明智的实际问题是什么。

答案 1 :(得分:5)

我遇到了同样的问题,最后调整了可见性设置。然而,我只是在摆弄符号可见性而不理解问题时感到紧张,所以我做了一些调查。

如果像我一样,你正在使用Pete Goodliffe的脚本/包来构建boost作为框架,那么脚本会将默认可见性设置为hidden(== yes)。可见性选项更改编译器标记符号的方式(默认,隐藏,内部)。在创建共享对象elf(共享库)时,链接器使用该信息。它不应该适用于此,所以我怀疑这是一个链接器错误。在boost库中,您有一个标记为隐藏的弱符号,然后在您的项目/另一个库中,标记为默认的相同符号。链接器很混乱?

对于XCode 3与4,可能3中的默认值是隐藏符号吗?

在任何情况下,将默认可见性更改为隐藏应该对仅涉及静态库无效,因此我觉得采用这种方法更安全。

我已经在blog entry中为感兴趣的人发布了一些细节。

答案 2 :(得分:4)

我在尝试将boost库包含在我的项目中时遇到了这个问题。找到此帖后,将Symbols Hidden By Default设置为Yes也为我解决了这个问题。而且我还必须在每个依赖项目中进行相同的设置,以完全摆脱错误。

仅供参考 - 这只发生在我使用clang ++堆栈的目标上。 GCC和LLVM + GCC目标似乎没有受到影响。

答案 3 :(得分:2)

基本上您链接到的库中的任何符号&amp;您自己的代码,需要使用相同的可见性级别,即如果您包含的库中的所有符号都被隐藏,您需要确保引用项目中的符号的包含文件不会尝试将其设置为可见。最安全的方法是在整个项目中保持一定的默认可见性,对我而言,这只会成为优化问题。

答案 4 :(得分:1)

也许您正在使用具有隐藏符号信息的库。如果尚未从库中导出符号,并且您尝试在外部使用它,则会导致类似的链接器错误。正确的解决方案似乎是找到一种方法,通过GCC宏定义使该符号对外界“可见”和/或修改库本身,以确保该特定符号真正“隐藏”在外部世界 - - 即它不是在头文件中使用或暴露的东西。

但是,请谨慎行事:根据Apple文档,出于多种原因,您不应隐藏某些符号信息;下面列出的这个似乎是最惊人的一群:

  

如果符号使用另一个库中定义的对象的运行时类型标识(RTTI)信息,异常或动态强制转换,则如果符号需要处理由其他库启动的请求,则该符号必须可见。例如,如果为C ++标准库中的类型定义catch处理程序,并且希望捕获C ++标准库抛出的该类型的异常,则必须确保typeinfo对象可见。

来源:http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html

因此,如果您想要从您链接的库中捕获异常,隐藏符号信息似乎是一个糟糕的选择。正确的解决方案是取消隐藏您链接到的任何库的符号。这可以通过省略以下GCC编译器标志来完成:

-fvisibility=hidden --fvisibility-inlines-hidden

(默认可见性应该足够),或者还有允许您执行此操作的编译器编译指示。请参阅:http://gcc.gnu.org/wiki/Visibility