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

我有一个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 

build造线:

 /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不会跨库边界引发exception)。

我也听说你不能静态连接glibc,因为静态库没有用-fPIC编译。


我的主要问题是:

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

我的小问题是:

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

(不要担心Apache2.2 vs 2.4依赖..这是容易的一点)

Solutions Collecting From Web of "如何在centos6上分发c ++ 11共享库"

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

如果你不能用标准的CentOS 6 g ++ / glibc / libstdc ++来编译你的代码,那么不会,它不会在标准的CentOS 6安装上运行。

CentOS发行版是为了长期支持(LTS)。 重要的错误可以通过更新得到修复,但软件通常不会改变。 这是一个功能 。 即使有第三方存储库(例如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 )需要随库一起提供,并安装在一些奇怪的位置,伴随着头痛( LD_LIBRARY_PATH ,会发生什么到任何其他C ++插件等)。 并在某些时候更新。

一些企业用户会反对这样的事情,主要是因为它与现有的操作系​​统不兼容。

依赖关系中的静态链接(如Ali的答案与下面的Developer Toolset)也可以工作。 这也不是没有问题(再次更新依赖关系),但可能是您的代码在CentOS 6上工作的最佳机会。

我从评论中看到阿里的回答, devtools 1 (gcc 4.7.0)没有工作,使devtools 1.1不太可能工作。 所以在这种情况下,你似乎需要 C ++ 11的支持达到gcc 4.8的水平。

你的问题与GLIBC

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

根据distrowatch ,CentOS 6.5与GCC 4.4.7一起发货。 C++11支持大部分在GCC 4.8中完成,而在4.4中只有不完全的支持。

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

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

简而言之:

  1. 事情只能向下兼容。 您需要选择您想要支持的发行版本中最早的发行版本。 该发行版的更高版本很可能会向后兼容,因此您的共享库在稍后的发行版上可以做得很好。

  2. 您可能需要从源代码构建支持C ++ 11的编译器,或者从发行版的某些回购库安装它。 如果可能的话,由于兼容性问题,最好选择后者。

  3. 任何非系统库都应静态链接到共享库中: -Wl,--static -lmylib1 -lmylib2 -Wl,--dynamic 。 这里重要的是-Wl,--dynamic是最后的,毕竟静态链接的东西。


我没有尝试过,但是我的同事经常这么说:

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

  • 安装devtools / Developer Toolset 。 兼容性问题应该通过开发人员工具的特殊补丁版本来解决。 开发者工具集2.1测试版附带gcc 4.8。

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

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

希望这可以帮助。