CentOS: 使用devtoolset中的GCC 4.7导致链接libstdc ++不正确(未定义符号)

7

我正在使用devtoolset-1.0来升级CentOS 6.3的GCC版本。虽然现在我能够编译我的C++应用程序,但最终二进制文件缺少一些符号:

$ ldd -d -r myapp
$     [..]
$     libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x0000003216e00000)
$     [..]
$ undefined symbol: _ZNSt8__detail15_List_node_base11_M_transferEPS0_S1_    (./myapp)
$ undefined symbol: _ZNSt8__detail15_List_node_base7_M_hookEPS0_      (./myapp)
$ undefined symbol: _ZNSt8__detail15_List_node_base9_M_unhookEv (./myapp)

我发现这些是一些新功能,在“旧”的libstdc++中找不到,但在更新的libstdc++中可以找到。在我的系统上,安装了libstdc++(默认版本为4.4.7)和devtoolset-1.0-libstdc++-devel(通过devtoolset安装的4.7)。有趣的是,来自devtoolset的libstdc++链接到旧版本的libstdc++。

$ cat /opt/centos/devtoolset-1.0/root/usr/lib/gcc/x86_64-redhat-linux/4.7.0/libstdc++.so
$ /* GNU ld script
$    Use the shared library, but some functions are only in
$    the static library, so try that secondarily.  */
$ OUTPUT_FORMAT(elf64-x86-64)
$ INPUT ( /usr/lib64/libstdc++.so.6 -lstdc++_nonshared )

我实际想要的是替换libstdc++绑定,但我不知道如何做到。我已经尝试过设置LD_LIBRARY_PATH并指向devtoolset目录,但是libstdc++仍然设置为旧位置。另外,符号链接也没有成功,因为它是一个ld脚本而不是实际共享库。

1
你有没有找到解决这个问题的办法?另外,我很好奇在调试版本和发布版本中是否有不同的缺失符号,这是我也观察到的情况。 - Mike Ellery
2个回答

2
最终的二进制文件缺少一些符号。这看起来像是devtoolset-1-gcc中的一个错误,我认为在更近期的devtoolset版本中已经修复了它。
有趣的是,来自devtoolset的libstdc++再次链接到旧的库。
是的,这就是devtoolset gcc应该工作的方式(有关更多详细信息,请参见此答案)。
实际上我想要的是替换libstdc++绑定,但我不知道如何实现。
你无法使用GCC的devtoolset来做到这一点,因为它甚至没有一个新的libstdc++.so库。正如你发现的那样,该文件实际上是一个链接器脚本,将你的二进制文件链接到libstdc++_nonshared.a /usr/lib64/libstdc++.so。
由于没有新的libstdc++.so,所以你无法链接到它。

1
GCC编译器及其库(特别是g++和对应的libstdc++运行时)需要匹配。使用更新的编译器进行编译将会生成无法与旧库一起使用的二进制文件(如果支持新版本语言,则几乎可以保证)。旧的二进制文件可能可以与更新的库一起使用,但这里不能保证。

1
这通常是正确的,但在这里并不相关,因为问题是关于使用特殊链接模型避免该问题的devtoolset。 - Jonathan Wakely

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