简体   繁体   English

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

[英]How to distribute c++11 shared library on centos6

I have a c++11 library ( https://github.com/matiu2/cdnalizer ). 我有一个c ++ 11库( https://github.com/matiu2/cdnalizer )。 I want to distribute it on centos6 and ubuntu12.04 LTS. 我想在centos6和ubuntu12.04 LTS上分发它。

It compiles happily on Ubuntu 13.10 and Gentoo. 它可以在Ubuntu 13.10和Gentoo上愉快地编译。

I tried compiling with as much staticness as I could, but it still depends on a glibc that centos doesn't have: 我尝试使用尽可能多的静态性进行编译,但它仍然取决于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 line: 构建线:

/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 

I have tried compiling gcc-4.8.2 on centos, but the binaries it produces have similar glibc dependencies: 我曾尝试在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)

I heard that you can't escape glibc dependencies for shared libraries because c++ throws excoptions and so needs the shared libstdc++ (but my lib doesn't throw exceptions across the library boundary). 我听说您无法逃避共享库的glibc依赖关系,因为c ++会抛出异常,因此需要共享的libstdc ++(但我的lib不会跨库边界抛出异常)。

I also heard that you can't link in glibc statically because the static lib was not compiled with -fPIC. 我还听说您无法静态链接glibc,因为静态库不是使用-fPIC编译的。


My main question is: 我的主要问题是:

  • How can I distribute my c++11 shared library on centos6 ? 如何在centos6上分发我的c ++ 11共享库?

My sub questions are: 我的子问题是:

  • Can I compile a c++11 shared library on ubuntu 13.10, and have it load on centos6 (and older ubuntus) ? 我可以在ubuntu 13.10上编译一个c ++ 11共享库,并在centos6(和较旧的ubuntus)上加载它吗? how ? 怎么样 ?
  • Can I compile a c++11 shared library on centos6 and have it work on standard centos installs ? 我可以在centos6上编译一个c ++ 11共享库,并且可以在标准centos安装上运行吗?

(Don't worry about Apache2.2 vs 2.4 dependency .. that's the easy bit) (不用担心Apache2.2 vs 2.4的依赖..这很容易)

Can I compile a c++11 shared library on centos6 and have it work on standard centos installs ? 我可以在centos6上编译一个c ++ 11共享库,并且可以在标准centos安装上运行吗?

If you can't build your code with the standard CentOS 6 g++/glibc/libstdc++, then no, it's not going to run on standard CentOS 6 installs. 如果您无法使用标准CentOS 6 g ++ / glibc / libstdc ++构建代码,则不会,它不会在标准CentOS 6安装中运行。

The CentOS distro is for long term support (LTS). CentOS发行版提供长期支持(LTS)。 Critical bugs get fixed with updates, but software otherwise doesn't change, usually. 关键错误会通过更新得到修复,但是软件通常不会更改。 This is a feature . 这是一个功能 Even with 3rd party repositories (eg EPEL), the available software for CentOS isn't really recent. 即使有了第三方存储库(例如EPEL),可用于CentOS的软件并不是真正的最新版本。

Can I compile a c++11 shared library on ubuntu 13.10, and have it load on centos6 (and older ubuntus) ? 我可以在ubuntu 13.10上编译一个c ++ 11共享库,并在centos6(和较旧的ubuntus)上加载它吗? how ? 怎么样 ?

If you can compile it using the g++ 4.4 toolchain, sure. 如果可以使用g ++ 4.4工具链进行编译,请确保。 In this case, you cannot use a more advanced compiler. 在这种情况下,您不能使用更高级的编译器。 A quick search on Ubuntu's 12.04 LTS package list shows libstdc++6-4.5-dbg using a version of libstdc++.so.6 which would be backward incompatible, based on error messages above. 在Ubuntu 12.04 LTS软件包列表中进行的快速搜索显示使用libstdc++.so.6的版本的libstdc++.so.6 6-4.5-dbg,基于上述错误消息,该版本向后不兼容。

How can I distribute my c++11 shared library on centos6 ? 如何在centos6上分发我的c ++ 11共享库?

As you've shown above, you'll have at least one updated dependency ( libstdc++.so.6 ) that you'll need to ship with your library, and install in some odd location, with it's attendant headaches ( LD_LIBRARY_PATH , what happens to any other C++ plugins, etc.). 如上所示,您将至少拥有一个更新的依赖项( libstdc++.so.6 ),您需要libstdc++.so.6依赖项随库一起提供,并安装在某个奇怪的位置,这会带来很多麻烦( LD_LIBRARY_PATH ,会发生什么情况)到任何其他C ++插件等)。 And update at some point. 并在某个时候进行更新。

Some enterprise users would object to something like this, mainly because it doesn't mesh well with the existing OS. 一些企业用户会反对这样的事情,主要是因为它与现有的操作系​​统不兼容。

Statically linking in dependencies (like in Ali's answer with the Developer Toolset below) could work also. 静态链接依赖项(例如在Ali的下面带有Developer Toolset 的答案中)也可以工作。 It's also not without problems (updates to dependencies again), but might be the best chance for your code to work on CentOS 6. 它也不是没有问题(再次更新到依赖项),但是可能是您的代码在CentOS 6上运行的最佳机会。

I see from comments to Ali's answer, that devtools 1 (gcc 4.7.0) didn't work, making it unlikely that devtools 1.1 would work. 从对阿里答案的评论中可以看出, devtools 1 (gcc 4.7.0)无法正常工作,因此devtools 1.1不太可能正常工作。 So it seems you do need C++11 support up to the level of gcc 4.8 in this case. 因此,在这种情况下,您似乎确实需要达到gcc 4.8级别的C ++ 11支持。

Your problem has nothing to do with GLIBC . 您的问题与GLIBC

Your problem is that libstdc++.so.6 on the CentOS6 is too old. 您的问题是libstdc++.so.6上的libstdc++.so.6太旧了。

According to distrowatch , CentOS 6.5 shipped with GCC 4.4.7. 根据发行商的说法 ,CentOS 6.5随GCC 4.4.7一起提供。 C++11 support was mostly complete in GCC 4.8, and in 4.4 had only incomplete support. 在GCC 4.8中,对C++11支持大部分已完成,而在4.4中,该支持才不完整

If you can build your library with GCC 4.4.7, then it should work (provided you build it on an old enough system). 如果您可以使用GCC 4.4.7构建您的库,那么它应该可以工作(前提是您在足够老的系统上构建它)。 If you can't, then you'll have to update GCC on your target CentOS system. 如果不能,则必须在目标CentOS系统上更新GCC。

Alternatively, you can distribute a newer version of libstdc++.so.6 (one from GCC 4.8), install it in non-default location, and ask your customers to link against that newer version (either via LD_LIBRARY_PATH , or better by supplying appropriate -Wl,-rpath=... option at link time). 另外,您可以分发libstdc ++。so.6的较新版本(GCC 4.8中的一个),将其安装在非默认位置,然后要求您的客户链接到该较新版本(通过LD_LIBRARY_PATH ,或者通过提供适当的-Wl,-rpath=...链接时显示-Wl,-rpath=...选项)。

In short: 简而言之:

  1. Things are only backward compatible. 事物仅向后兼容。 You need to pick the oldest release of the distro you want to support and build on that. 您需要选择要支持的发行版的最旧发行版,并以此为基础。 The later releases of that distro will most likely be backward compatible so your shared library will do just fine on later releases. 该发行版的更高版本很可能是向后兼容的,因此您的共享库将在更高版本上正常运行。

  2. You either need to build the compiler with C++11 support from source or install it from some repo of the distro. 您或者需要从源代码构建带有C ++ 11支持的编译器,或者从发行版的某些存储库中安装它。 Prefer the latter if possible due to compatibility issues. 由于兼容性问题,请尽可能使用后者。

  3. Any non-system library should be statically linked into your shared library: -Wl,--static -lmylib1 -lmylib2 -Wl,--dynamic . 任何非系统库都应静态链接到共享库中: -Wl,--static -lmylib1 -lmylib2 -Wl,--dynamic The important here is that -Wl,--dynamic is at the end, after all statically linked stuff. 在这里重要的是,在所有静态链接的内容之后, -Wl,--dynamic最后是。


I haven't tried it myself but my colleague who does this routinely says: 我自己还没有尝试过,但是经常这样做的同事说:

  • Use CentOS 6.5 (the latest of the 6.x versions as of writing). 使用CentOS 6.5 (撰写本文时,最新的6.x版本)。

  • Install devtools / Developer Toolset . 安装devtools /开发人员工具集 The compatibility issues are supposed to be resolved by special, patched version of the developer tools. 兼容性问题应该由开发人员工具的特殊修补版本解决。 Developer Toolset 2.1 Beta comes with gcc 4.8. Developer Toolset 2.1 Beta随附gcc 4.8。

  • Link statically all third party libraries and libstdc++ . 静态链接所有第三方库和libstdc++ However, do not link glibc and other system libraries statically that are supposed to be on the target machine anyway. 但是,无论如何都不要静态链接应该在目标计算机上的glibc和其他系统库。

The programs that my colleague compiles this way work on my Ubuntu machine just fine. 我的同事以这种方式编译的程序可以在我的Ubuntu计算机上正常工作。 (He uses CentOS 5.10, which seems to be the oldest, still supported distro that has glibc 2.5.) (他使用CentOS 5.10,它似乎是最老的,仍受支持的具有glibc 2.5的发行版。)

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM