I have a c++11 library ( https://github.com/matiu2/cdnalizer ). I want to distribute it on centos6 and ubuntu12.04 LTS.
It compiles happily on Ubuntu 13.10 and Gentoo.
I tried compiling with as much staticness as I could, but it still depends on a glibc that centos doesn't have:
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:
[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).
I also heard that you can't link in glibc statically because the static lib was not compiled with -fPIC.
My main question is:
- How can I distribute my c++11 shared library on centos6 ?
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) ? how ?
- Can I compile a c++11 shared library on centos6 and have it work on standard centos installs ?
(Don't worry about Apache2.2 vs 2.4 dependency .. that's the easy bit)
Can I compile a c++11 shared library on centos6 and have it work on standard centos installs ?
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.
The CentOS distro is for long term support (LTS). Critical bugs get fixed with updates, but software otherwise doesn't change, usually. This is a feature. Even with 3rd party repositories (e.g. EPEL), the available software for CentOS isn't really recent.
Can I compile a c++11 shared library on ubuntu 13.10, and have it load on centos6 (and older ubuntus) ? how ?
If you can compile it using the g++ 4.4 toolchain, sure. 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.
How can I distribute my c++11 shared library on centos6 ?
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.). 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. It's also not without problems (updates to dependencies again), but might be the best chance for your code to work on 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. So it seems you do need C++11 support up to the level of gcc 4.8 in this case.
Your problem has nothing to do with GLIBC
.
Your problem is that libstdc++.so.6
on the CentOS6 is too old.
According to distrowatch, CentOS 6.5 shipped with GCC 4.4.7. C++11
support was mostly complete in GCC 4.8, and in 4.4 had only incomplete support.
If you can build your library with GCC 4.4.7, then it should work (provided you build it on an old enough system). If you can't, then you'll have to update GCC on your target CentOS system.
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).
In short:
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.
You either need to build the compiler with C++11 support from source or install it from some repo of the distro. Prefer the latter if possible due to compatibility issues.
Any non-system library should be statically linked into your shared
library: -Wl,--static -lmylib1 -lmylib2 -Wl,--dynamic
. The important here is that -Wl,--dynamic
is at the end, after all statically linked stuff.
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).
Install devtools / Developer Toolset. 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.
Link statically all third party libraries and libstdc++
. However, do not
link glibc and other system libraries statically that are supposed to be on the target machine
anyway.
The programs that my colleague compiles this way work on my Ubuntu machine just fine. (He uses CentOS 5.10, which seems to be the oldest, still supported distro that has glibc 2.5.)
Hope this helps.