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

时间:2014-05-21 05:13:48

标签: c++ linux gcc static-linking libstdc++

我们想要创建一个共享库(.so)来定位所有发行版,包括旧发行版。代码用C ++编写并使用C ++ 11特性,因此编译器必须至少为gcc 4.7。 我们注意到,如果我们在安装了gcc 4.7.2的Linux机器上编译我们的代码(例如,Ubuntu 12.10),那么.so生产的版本1(GNU / Linux),而在较旧的OS(例如,CentOS 5.6)上版本是“版本1(SYSV)” - 具有GNU / Linux更新版本的库不能在旧版操作系统上使用。

所以我们尝试了在CentOS 5.6机器上安装gcc 4.7的方法,使用这个编译器编译我们的代码并与libstdc ++(-static-libstdc ++)静态链接 - 这产生了一个可以在我们找到的每个linux上使用的.so。

这适用于32位。但是,当我们在64位操作系统(CentOS)上遵循相同的方法时,由于我们尝试链接到的现有libstdc ++。的错误在没有-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?

2 个答案:

答案 0 :(得分:2)

我在https://gcc.gnu.org/ml/libstdc++/2014-05/msg00107.html

处回答了此问题
  

这看起来像https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54482所以可能会在GCC 4.7.3中修复(但我不确定)

...

  

对于x86和x86_64,PIC的实现方式不同,因为64位模式   内置了对它的支持。

答案 1 :(得分:-1)

不应该静态链接到libc / libstdc ++,即使它有效!这是非常危险的,因为许多安全方面需要更新libc。如果静态链接在没有更新可以填补漏洞。

我无法相信存在适用于所有Linux平台的'通用'libc。 libc是已安装系统的接口,这是差异的重要组成部分。一个lib应该如何适合所有人?

连接时可以尝试

-static-libstdc++ -static-libgcc

作为ld的选项。也许这有帮助。但我永远不会那样做!