我们希望创建一个共享库(.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文件?
我们注意到,如果在安装了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文件?
_ZNSs7_M_copyEPcPKcm
是std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_copy(char*, char const*, unsigned long)
。 - Ali