在Linux上编译一个共享库以针对所有发行版

5
我们希望创建一个共享库(.so)以针对所有Linux发行版,包括旧版本。代码是用C++编写的,使用了C++11特性,因此编译器必须至少是gcc 4.7。
我们注意到,如果在安装了gcc 4.7.2的Linux机器上编译我们的代码(例如Ubuntu 12.10),那么产生的.so文件将具有“version 1(GNU/Linux)”,而在旧操作系统(例如CentOS 5.6)上版本为“version 1(SYSV)” - 带有GNU/Linux新版本的库无法在旧操作系统上使用。
所以我们尝试在CentOS 5.6机器上安装gcc 4.7,并使用这个编译器编译我们的代码并静态链接libstdc++(-static-libstdc ++) - 这样产生的.so可在我们找到的每个Linux上使用。
这对32位来说效果很好。然而,在64位操作系统(CentOS)上遵循相同的方法时,会出现错误,即我们尝试链接的现有libstdc++.a是未使用-fPIC编译的。
因此,我们尝试使用“-with-pic”选项编译gcc 4.7.2源代码,但我们无法链接到新的libstdc++.a - 错误如下:
/opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/ld:/usr/local/lib/libFoo.so:找不到符号_ZNSs7_M_copyEPcPKcm@GLIBCXX_3.4的版本节点 /opt/centos/devtoolset-1.1/root/usr/libexec/gcc/x86_64-CentOS-linux/4.7.2/ld:无法设置动态部分大小:坏值 collect2:错误:ld返回了1个退出状态
我们搜索得知,使用-fPIC编译libstdc++可能会有问题,但为什么32位可以而64位不能?是否有其他建议的方法来创建适用于所有Linux发行版的.so文件?

这个怎么可能行得通? - mjs
很好的研究问题!错误可能不是你的错:我谷歌搜索“failed to set dynamic section sizes: Bad value”,只看到了错误报告。顺便说一下,错误信息中的_ZNSs7_M_copyEPcPKcmstd::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_copy(char*, char const*, unsigned long) - Ali
2个回答

2

1
我遇到了同样的问题,我可以确认升级到4.7.3(从4.6.3)确实解决了我的问题。相关问题:http://stackoverflow.com/questions/28593592/how-to-link-with-libstdc-pic-a-with-gcc/28625188#28625188 - Edward

-1

不应该静态链接到libc/libstdc++,即使它能工作!这是非常危险的,因为许多安全方面都需要对libc进行更新。如果静态链接没有更新,那么漏洞就无法填补。

我无法相信存在适用于所有Linux平台的'通用' libc。 libc是与安装的系统接口,这个系统是差异性很大的池塘。一个库怎么可能适用于所有呢?

在链接过程中,您可以尝试以下方法:

-static-libstdc++ -static-libgcc

可能作为ld的选项,这或许会有帮助。但是我永远不会这样做!

他并没有试图静态链接libc库,请重新阅读问题。 - Ali
谢谢!他试图构建一个可以在多个平台上运行的库。因此,我相信libstdc++需要libgcc。抱歉给出这个提示 :-) - Klaus
即使你静态链接了libstdc++,我认为也没有必要静态链接libc。你的回答并没有回答他的问题:“为什么32位系统可以工作而64位系统不行?有没有其他建议的方法来创建一个适用于所有Linux发行版的.so文件?”因此我不能取消我的踩票,抱歉。 - Ali

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