32位构建中出现“bad codegen,指针差异在boost中”错误。

5
在Mac OS X 10.6下,我正在构建一个链接到boost 1.46的C++共享库。我正在使用安装在Xcode 4.0中的命令行工具。64位版本可以正常工作。当构建32位版本时,在链接时会收到以下错误消息:
ld: bad codegen, pointer diff in boost::detail::sp_counted_base::sp_counted_base()to global weak symbol vtable for boost::detail::sp_counted_basefor architecture i386

我找到的唯一解决方法是使用 g++-4.0 进行32位构建。我尝试过的其他编译器(g++-4.2、llvm-g++-4.2 和 clang++)都会产生上述错误。

5个回答

5
问题很可能是您在静态链接两个具有不同默认可见性值(-fvisibility)的库。您可以确保为boost和您的项目使用相同的可见性标志,或者使用显式导出符号文件。

2
你可能正在链接一个使用gcc 4.0编译的库,它与gcc 4.2和clang不兼容。你应该重新构建所有使用gcc 4.2或clang编译的库,并使用与主应用程序相同的编译器选项(特别注意选项“C++标准库类型”,也称为STANDARD_C_PLUS_PLUS_LIBRARY_TYPE,应在所有库中一致地设置为“静态”或“动态”)。另一个有用的选项是“默认隐藏符号”,但要注意,启用此选项会隐藏那些在使用不同选项/编译器编译的库之间传递C++对象时会出现的麻烦错误。

Boost是使用gcc 4.2作为通用二进制文件和动态libstdc++构建的。除了我使用相同的32位和64位设置之外,这些错误不应该在64位构建中也出现吗? - sakra
1
我猜有两个原因:要么有一个选项使您的代码与64位架构不兼容,该选项不受支持,要么64位ABI不会破坏兼容性。从外观上看,与您的代码冲突的不一定是boost本身,而可能是使用boost的另一个库(因此使用不同选项编译boost头文件):除了boost之外,您是否链接了其他二进制库? - pqnet
Boost有一堆sp_counted_base类的变体,适用于不同的架构...它们正在执行一些特定于CPU的操作来进行原子操作,因此在一个架构上可能存在某些问题,在另一个架构上则不会出现。 顺便说一句,我们实验室的某个人在尝试修复其他可见性错误后遇到了相同的错误,我们对客户端代码(Ogre3D)进行了干净的构建,然后问题就解决了。 耸肩 - Ethan

2

注意: 在XCode中,可见性设置在代码生成中 > 内联方法隐藏和符号默认隐藏

将它们设置为NO可以解决此问题。

这对应于gcc的-fvisibility-inlines-hidden和-fvisibility标志。 您可以使用它们来仅调整代码的设置,而不是搞乱boost。


我是新手,请原谅我的无知 - 在xcode 4.3.2中,我应该如何做到这一点? - Pete_ch

1

问题似乎已经在安装有XCode 4.2的链接器中得到解决。现在,在链接时我收到的是一个警告而不是错误信息:

ld: warning: direct access in __ZN5boost6detail15sp_counted_baseC2Ev to global weak symbol __ZTVN5boost6detail15sp_counted_baseE means the weak symbol cannot be overridden at runtime. This was likely caused by different translation units being compiled with different visibility settings.

@StéphanePéchard,不,我没有成功消除警告。我认为只有在使用完全相同的可见性设置编译库(例如boost)时才能消除它。然而,这似乎对于系统范围的第三方库来说并不实用。 - sakra

1

此处所述:

如果多个项目都包含了boost,则每个项目必须具有相同的值

 Symbols Hidden by Default
 Inline Methods Hidden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接