如何在centos6上分发c ++ 11共享库

时间:2014-03-01 04:03:11

标签: linux gcc c++11 linker

我有一个c ++ 11库(https://github.com/matiu2/cdnalizer)。我想在centos6和ubuntu12.04 LTS上发布它。

它在Ubuntu 13.10和Gentoo上愉快地编译。

我尝试尽可能多地使用静态编译,但它仍然取决于centos没有的glibc:

matiu@matiu-laptop:~/projects/cdnalizer/build/src/apache$ readelf -d mod_cdnalizer.so | grep NEED
 0x0000000000000001 (NEEDED)             Shared library: [libapr-1.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000006ffffffe (VERNEED)            0xd520
 0x000000006fffffff (VERNEEDNUM)         3

构建线:

/usr/bin/g++  -fPIC -I/usr/local/include -I/usr/include -I/usr/include/x86_64-linux-gnu -I/usr/include/x86_64-linux-gnu/c++/4.8 -Wall -Wextra -g   -shared -Wl,-soname,mod_cdnalizer.so -o mod_cdnalizer.so CMakeFiles/mod_cdnalizer.dir/mod_cdnalizer.cpp.o CMakeFiles/mod_cdnalizer.dir/config.cpp.o CMakeFiles/mod_cdnalizer.dir/filter.cpp.o ../libbase.a -lapr-1 

我尝试在centos上编译gcc-4.8.2,但它生成的二进制文件具有类似的glibc依赖项:

[root@matt src]# ./test_config 
./test_config: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by ./test_config)
./test_config: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./test_config)

我听说你无法逃避共享库的glibc依赖,因为c ++会抛出excoptions,因此需要共享libstdc ++(但我的lib不会在库边界引发异常)。

我还听说你无法静态链接glibc,因为静态库没有用-fPIC编译。


我的主要问题是:

  • 如何在centos6上分发我的c ++ 11共享库?

我的子问题是:

  • 我可以在ubuntu 13.10上编译一个c ++ 11共享库,并将它加载到centos6(以及更旧的ubuntus)吗?怎么样?
  • 我可以在centos6上编译c ++ 11共享库并让它在标准的centos安装上运行吗?

(不要担心Apache2.2与2.4的依赖关系......这很容易)

3 个答案:

答案 0 :(得分:4)

  

我可以在centos6上编译c ++ 11共享库并让它在标准的centos安装上运行吗?

如果您无法使用标准的CentOS 6 g ++ / glibc / libstdc ++构建代码,那么不,它不会在标准的CentOS 6安装上运行。

CentOS发行版是为了长期支持(LTS)。通过更新修复关键错误,但通常情况下软件不会更改。 This is a feature。即使使用第三方存储库(例如EPEL),CentOS的可用软件也不是最新的。

  

我可以在ubuntu 13.10上编译一个c ++ 11共享库,并将它加载到centos6(以及更旧的ubuntus)吗?怎么样?

如果你可以使用g ++ 4.4工具链编译它,当然。在这种情况下,您不能使用更高级的编译器。快速搜索Ubuntu的12.04 LTS包列表显示libstdc ++ 6-4.5-dbg使用libstdc++.so.6版本,这将基于上面的错误消息向后不兼容。

  

如何在centos6上发布我的c ++ 11共享库?

正如您上面所示,您将至少有一个更新的依赖项(libstdc++.so.6),您需要随库一起提供,并安装在一些奇怪的位置,伴随着随之而来的头痛({ {1}},任何其他C ++插件会发生什么,等等。并在某个时候更新。

一些企业用户会反对这样的事情,主要是因为它与现有操作系统不能很好地融合。

依赖关系中的静态链接(如Ali's answer与下面的Developer Toolset一样)也可以。它也不是没有问题(再次更新依赖项),但可能是您的代码在CentOS 6上运行的最佳机会。

我从评论中看到阿里的答案,devtools 1(gcc 4.7.0)不起作用,使得devtools 1.1不太可行。因此,在这种情况下,您似乎需要 C ++ 11支持最高级别为gcc 4.8。

答案 1 :(得分:3)

您的问题与GLIBC无关。

你的问题是CentOS6上的libstdc++.so.6太旧了。

根据distrowatch,CentOS 6.5附带GCC 4.4.7。 C++11支持在GCC 4.8中基本完成,而4.4仅支持incomplete

如果您可以使用GCC 4.4.7构建您的库,那么它应该可以工作(前提是您在足够老的系统上构建它)。如果你不能,那么你将不得不在目标CentOS系统上更新GCC。

或者,您可以分发较新版本的libstdc ++。so.6(一个来自GCC 4.8),将其安装在非默认位置,并要求您的客户链接到较新版本(通过LD_LIBRARY_PATH或者通过在链接时提供适当的-Wl,-rpath=...选项来提高效率。)

答案 2 :(得分:0)

简而言之:

  1. 事物只能向后兼容。你需要挑选最老的 发布您想要支持和构建的发行版 那。该发行版的后期版本很可能是落后的 兼容,因此您的共享库将在以后的版本中正常运行。

  2. 您需要从源代码构建具有C ++ 11支持的编译器,或者从发行版的某些repo中安装它。如果可能,由于兼容性问题,请更喜欢后者。

  3. 任何非系统库都应静态链接到您的共享库中 图书馆:-Wl,--static -lmylib1 -lmylib2 -Wl,--dynamic。这里重要的是-Wl,--dynamic在所有静态链接的东西之后结束。


  4. 我自己没有尝试过,但我的同事经常这样说:

    • 使用CentOS 6.5(撰写时最新的6.x版本)。

    • 安装devtools / Developer Toolset。兼容性问题应该由开发人员工具的特殊修补版本解决。 Developer Toolset 2.1 Beta附带gcc 4.8。

    • 静态链接所有第三方库和libstdc++。但是, 将glibc和其他系统库静态链接到目标机器上 反正。

    我的同事以这种方式编译的程序在我的Ubuntu机器上工作就好了。 (他使用的是CentOS 5.10,它似乎是最古老的,仍然支持glibc 2.5的发行版。)

    希望这有帮助。