Xcode 4 的“代码生成错误,指针差异”链接器错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5285844/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
"bad codegen, pointer diff" linker error with Xcode 4
提问by Rob Agar
Recompiling a C++ iPhone app with Xcode 4 I get this nasty linker error:
使用 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
Anyone know what it means? How to make it go away would be nice too of course :)
有谁知道是什么意思?如何让它消失当然也很好:)
The app compiled & linked without error in Xcode 3.
该应用程序在 Xcode 3 中编译和链接没有错误。
Edit: the solution is to set Symbols Hidden By Defaultto Yesin all the build settings of all targets in the project. Still none the wiser what the actual problem was.
编辑:该解决方案是一套隐藏的默认符号来是在项目中的所有目标的所有生成设置。仍然没有更明智的实际问题是什么。
回答by Rob Agar
The solution is to set Symbols Hidden By Default
to Yesin all the build settings of all targets in the project. Still none the wiser what the actual problem was.
解决方法是在项目中所有目标的所有构建设置中都设置Symbols Hidden By Default
为是。仍然没有更明智的实际问题是什么。
回答by Tyler Daniel
I had the same problem and also ended up adjusting the visibility settings. However, I was nervous just fiddling with symbol visibility and not understanding the problem, so I did a little more investigation.
我遇到了同样的问题,最终还调整了可见性设置。然而,我只是摆弄符号可见性而不理解问题,我很紧张,所以我做了更多的调查。
If, like me, you're using Pete Goodliffe's script/package to build boost as a framework, the script sets default visibility to hidden (== yes). The visibility options change how symbols are marked by the compiler (default, hidden, internal). That information is used by the linker when making shared object elfs (shared libraries). It shouldn't apply here, so I suspect that this is a linker bug. Inside the boost library you have a weak symbol marked as hidden, and then in your project/another library, the same symbol marked as default. The linker is confused?
如果像我一样,您使用 Pete Goodliffe 的脚本/包来构建 boost 作为框架,则该脚本会将默认可见性设置为隐藏(== 是)。可见性选项改变了编译器标记符号的方式(默认、隐藏、内部)。链接器在创建共享对象精灵(共享库)时使用该信息。它不应该在这里适用,所以我怀疑这是一个链接器错误。在 boost 库中,您有一个弱符号标记为隐藏,然后在您的项目/另一个库中,标记为默认的相同符号。链接器混淆了?
As for XCode 3 vs. 4, perhaps the default in 3 was to hide symbols?
至于 XCode 3 与 4,也许 3 中的默认值是隐藏符号?
In any case, changing default visibility to hidden should really have no effect with only static libs involved, so I feel a lot safer taking this route.
在任何情况下,将默认可见性更改为 hidden 应该对仅涉及静态库没有影响,所以我觉得走这条路要安全得多。
I've posted a few more details in a blog entryfor those interested.
我已经在博客条目中为感兴趣的人发布了更多详细信息。
回答by zim
I ran into this problem while trying to include the boost libraries one of my projects. After finding this post, setting Symbols Hidden By Default
to Yes
also solved this issue for me. And I also had to make the same setting in each of the dependent projects to completely get rid of the error.
我在尝试将 boost 库包含在我的项目中时遇到了这个问题。找到这篇文章后,设置Symbols Hidden By Default
为Yes
也为我解决了这个问题。而且我还必须在每个依赖项目中进行相同的设置才能完全摆脱错误。
Just FYI - This only happened on my targets that were using the clang++ stack. GCC and LLVM+GCC targets do not seem to be affected.
仅供参考 - 这仅发生在我使用 clang++ 堆栈的目标上。GCC 和 LLVM+GCC 目标似乎没有受到影响。
回答by Andrew Haining
Basically any symbols in a library you link to & your own code, need to use the same visibility level, i.e. if all the symbols in a library you include are hidden you need make sure the include files referencing the symbols in your project don't try and set it to visible. the safest way to do this is to have a constant level of default visibility across your project, for me it only became a problem with optimisations on.
基本上,您链接到的库中的任何符号和您自己的代码都需要使用相同的可见性级别,即如果您包含的库中的所有符号都被隐藏,则需要确保引用项目中符号的包含文件没有尝试将其设置为可见。最安全的方法是在整个项目中保持恒定的默认可见性,对我来说这只是优化的问题。
回答by markshiz
Perhaps you are using a library that has hidden symbol information. If a symbol has not been exported from your library, and you attempt to use it externally, it results in a similar linker error. The correct solution would seem to be to find a way to make that symbol "visible" to the outside world via GCC macro definitions and/or modify the library itself to make sure that that particular symbol is truly "hidden" from the outside world --i.e. it isn't something that is ever used or exposed in a header file.
也许您正在使用具有隐藏符号信息的库。如果符号尚未从您的库中导出,而您尝试在外部使用它,则会导致类似的链接器错误。正确的解决方案似乎是找到一种方法,通过 GCC 宏定义使该符号对外界“可见”和/或修改库本身以确保该特定符号真正对外界“隐藏”- - 即它不是在头文件中使用或公开的东西。
However, proceed with caution: according to Apple documentation, you should not hide some symbol information for a number of reasons; this one listed below seems to be the most alarming of the bunch:
但是,请谨慎操作:根据 Apple 文档,出于多种原因,您不应隐藏某些符号信息;下面列出的这个似乎是最令人震惊的:
If your symbol uses runtime type identification (RTTI) information, exceptions, or dynamic casts for an object that is defined in another library, your symbol must be visible if it expects to handle requests initiated by the other library. For example, if you define a catch handler for a type in the C++ standard library, and you want to catch exceptions of that type thrown by the C++ standard library, you must make sure that your typeinfo object is visible.
如果您的符号使用其他库中定义的对象的运行时类型标识 (RTTI) 信息、异常或动态强制转换,则您的符号在希望处理其他库发起的请求时必须是可见的。例如,如果您为 C++ 标准库中的某个类型定义了一个捕获处理程序,并且您想要捕获 C++ 标准库抛出的该类型的异常,您必须确保您的 typeinfo 对象是可见的。
来源:http: //developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html
Thus, if you want to catch an exception from the library you're linking against, hiding symbol information appears to be a bad choice. The correct solution would be to unhidethe symbols of whatever library you're linking to. This can either be done by omittingthe following GCC compiler flags:
因此,如果您想从所链接的库中捕获异常,隐藏符号信息似乎是一个糟糕的选择。正确的解决方案是取消隐藏您链接到的任何库的符号。这可以通过省略以下 GCC 编译器标志来完成:
-fvisibility=hidden --fvisibility-inlines-hidden
-fvisibility=hidden --fvisibility-inlines-hidden
(the default visibility should be sufficient), or there are also compiler pragmas that allow you to do this. See: http://gcc.gnu.org/wiki/Visibility
(默认可见性应该足够了),或者也有编译器 pragma 允许您执行此操作。请参阅:http: //gcc.gnu.org/wiki/Visibility