Home » Linux » Link with an older version of libstdc++

Link with an older version of libstdc++

Posted by: admin November 30, 2017 Leave a comment

Questions:

After installing a new build machine, I found out it came with 6.0.10 of the standard C++ library

-rw-r--r--  1 root root 1019216 2009-01-02 12:15 libstdc++.so.6.0.10

Many of our target machines, however, still use an older version of libstdc++, for example:

-rwxr-xr-x 1 root root  985888 Aug 19 21:14 libstdc++.so.6.0.8

Apparently the ABI changed in those last two 0.0.1’s, as trying to run a program results in

/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found

I tried explicitly installing an older version of gcc but that didn’t help.
Upgrading the target machines is out of my control, so not an option. What’s the best way to get my builds to work on machines with an older libstdc++?

I searched in apt-cache for older libstdc++ versions to install, but apparently no older versions of 6 are available?

Answers:

You don’t need to link to a different library, you need to use an older version of the compiler.

Have a look at the GNU ABI policy. The libstdc++ shared library is designed to be forward compatible. I.e. version 6.0.10 can be used if you need 6.0.8. In the policy you can read that from gcc-4.2.0 on, 6.0.9 is needed, so you need a gcc-4.1.x.

In short, that’s why there’s only one libstdc++.so.6.0.x on your system, you only need the latest.

As for setting up your build system to use only a specific version of the compiler: make sure the standard g++ can’t be used (rename the link, remove the package providing it, take it out of PATH), and start digging. Worked for me.

Questions:
Answers:

You can ship the required shared libraries with your own code (in a subdirectory for instance) and set LD_LIBRARY_PATH, as a precursor to running your application, to first search in that directory.

Shipping the specific version that you need will mean that it won’t matter which version the user has installed. You just have to make sure you ship all dependencies as well.

Questions:
Answers:

You can either “smuggle” the newer libstdc++ into client systems (into a private area) and link the programs with appropriate -rpath, or you can get an older version of libstdc++ onto your computer. It doesn’t look like you need the update, and it may be out of question for other reasons anyway.

Note: on FreeBSD, libstdc++ is coupled with the compiler (I have gcc4.2, 4.4 and 4.5 installed, each with it’s own libstc++). Try installing an older (matching the client systems) version of gcc, it might carry the older libstdc++ you’re looking for.

Questions:
Answers:

Already encountered this. I didn’t thought of any better than installing a system (virtualized?) with the same configuration as the target machines to build the distributable binaries.

Questions:
Answers:

Al alternative, which didn’t work for me, but maybe someone else will find it useful, is to statically link libgcc and libstdc++.

gcc has an option -static-libgcc, but simply using this option achieves nothing, as libstdc++ is still dynamically linked. But by making sure gcc can only find the static version of libstdc++, static linking can be achieved.

ln -s `g++ -print-file-name=libstdc++.a`
g++ -static-libgcc -L. source.cpp

Problem is, the boost libraries were built against the newer libstdc++, so while the program compiles correctly, it generates runtime errors…

Maybe this is solvable if I rebuild boost too, haven’t tried that.

(for the record, if you use any code which dynamically loads libraries, via e.g. dlopen, statically linking is all out of the question)

Questions:
Answers:

Have you tried just putting it in with the list of sources? This assumes you actually have the library installed!

g++ /usr/lib/libstdc++.so.6.0.8 source1.cpp source2.cpp