我有一个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编译。
我的主要问题是:
我的子问题是:
(不要担心Apache2.2与2.4的依赖关系......这很容易)
答案 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)
简而言之:
事物只能向后兼容。你需要挑选最老的 发布您想要支持和构建的发行版 那。该发行版的后期版本很可能是落后的 兼容,因此您的共享库将在以后的版本中正常运行。
您需要从源代码构建具有C ++ 11支持的编译器,或者从发行版的某些repo中安装它。如果可能,由于兼容性问题,请更喜欢后者。
任何非系统库都应静态链接到您的共享库中
图书馆:-Wl,--static -lmylib1 -lmylib2 -Wl,--dynamic
。这里重要的是-Wl,--dynamic
在所有静态链接的东西之后结束。
我自己没有尝试过,但我的同事经常这样说:
使用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的发行版。)
希望这有帮助。