23

I'm using Intel's C++ compiler, which on Linux relies on the GNU-supplied libc.so and libstdc++.so.

Here's my problem. To have access to some of the newest C++11 features, I need to use the libstdc++ which ships with GCC 4.7 or higher. But I'm stuck using CentOS 6.4.

On CentOS 6.4, the native version of GCC is 4.4. But using a RedHat thing called "SCL" and a package named "devtoolset-1.1", I'm able to get GCC 4.7 installed under "/opt".

I set things up to be using GCC 4.7 in the manner mentioned above, I can use the newer C++11 features.

So here's my question: If a user runs my program with only the GCC 4.4 versions of libc.so / libstdc++.so in the library path, is there a risk that my program will have bugs due to some mismatch between the 4.4 and 4.7 versions of those libraries?

If there is a potential problem, can I work around it by statically linking in GCC 4.7's versions of libc and libstdc++? Or is that setting myself up for other problems if/when other libraries that my code dynamically loads pick up the older libc / libstdc++ supplied by the system-wide GCC 4.4 package?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Christian Convey
  • 1,202
  • 11
  • 19

1 Answers1

28

As Praetorian pointed out in the comments below, the use of devtoolset actually solves the problem I originally described in this answer. I've corrected the answer.

is there a risk that my program will have bugs due to some mismatch between the 4.4 and 4.7 versions of those libraries?

Yes. Linking against a newer libstdc++.so and then trying to run against and older one is 100% not supported. If any object in your program or any libraries it uses is compiled with GCC 4.7 and linked to the libstdc++.so from 4.7 then you need to use the libstdc++.so from 4.7 (or newer) at runtime. It probably won't even run, but if it does there may be silent bugs due to incompatibilities. But that's not a problem in your case, because you're not linking to GCC 4.7's libstdc++.so, see below.

can I work around it by statically linking in GCC 4.7's versions of libc and libstdc++?

1) You would only need to do that for libstdc++, because there is no such thing as "GCC 4.7's version of libc". Glibc is a completely separate project from GCC. When you are using GCC 4.7 you're not using a different libc, you're still using the system libc from CentOS 6.4. (As an aside, be aware that statically linking glibc is strongly advised against by the glibc maintainers, and some features of glibc will not work when statically linked.)

2) Statically linking libstdc++ would work around the problem, but you don't need to, because that's what the Red Hat Developer Toolset (devtoolset) does for you anyway. The whole point of devtoolset is that it allows you to use a newer GCC and newer libstdc++ but without creating any run-time dependencies on the newer libstdc++ library. The compiled executables only need the system version of libstdc++.so that is always present on RHEL/CentOS, even systems without devtoolset installed. (What devtoolset does is package all the new libstdc++ features in a static library, called libstdc++_nonshared.a so that all the pieces not present in the system libstdc++.so get statically linked in, and everything else will come from the system libstdc++.so).

If you weren't using devtoolset then another option instead of statically linking libstdc++ would be to ship the newer libstdc++.so with your code and ensure it is found first (e.g. by linking your code with an RPATH that refers to the newer libstdc++.so). But with devtoolset that's not necessary.

Or is that setting myself up for other problems if/when other libraries that my code dynamically loads pick up the older libc / libstdc++ supplied by the system-wide GCC 4.4 package?

There will be no such problems when using devtoolset, because you're always using the older libstdc++, and so there is never a conflict.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • Thanks. So it's really as simply as ensuring that libstdc++.so from GCC 4.7 is in my LD_LIBRARY_PATH before any other version of libstdc++.so, when running a program that was built against libstdc++? Wouldn't that cause problems if one of the other .so files my program uses has a dynamic link dependency against libstdc++.so, but that other shared object was built against an earlier version of GCC? (It's not necessarily the end of the world if that's the case, because my program has very few (direct) dependencies on other other libraries.) – Christian Convey Mar 24 '13 at 20:39
  • No, it will work fine. libstdc++.so is backwards compatible, so the `libstdc++.so.6.0.17` from 4.7 can be used by anything compiled with 4.7 or older (back to GCC 3.4.0, anyway) but it's **not** forwards compatible, so `libstdc++.so.6.0.13` from 4.4 cannot be used by something compiled with 4.7 – Jonathan Wakely Mar 24 '13 at 21:35
  • N.B. there are currently no guarantees of compatibility for C++11 features between libstdc++ releases, so if the other libraries your code loads use C++11 features then they should be recompiled with 4.7 too, but if they only use C++03 features then the newer libstdc++.so will work fine. – Jonathan Wakely Mar 24 '13 at 21:38
  • Thanks Jonathan. I'm starting to be very annoyed with Intel's decision to make their C++ compiler use Gnu's libstdc++.so. – Christian Convey Mar 25 '13 at 13:02
  • Thanks Jonathan. I'm starting to be very annoyed with Intel's decision to make their C++ compiler use Gnu's libstdc++.so. It's making it seriously difficult to use it on an older Linux version (CentOS 6.4) without major "DLL"-hell headaches. – Christian Convey Mar 25 '13 at 13:02
  • CentOS 6.4 is about two weeks old, your problem is the "stable" set of packages used on Enterprise distros, not the age of the distro. Intel's alternative would be to develop their own entire stdlib (a huge undertaking) and then code compiled with ICC would not be compatible with any system libs that were built with GCC ... which would be far more annoying. – Jonathan Wakely Mar 25 '13 at 13:51
  • 3
    Jon, I found this while trying to answer the same question as the OP, only difference being I'm using devtoolset-3. Your answer is correct in general of course, but not for devtoolset. Page 26 of [this PDF](https://www.redhat.com/summit/2012/pdf/2012-DevDay-How-To-Toolset-Newsome.pdf) explains that devtoolset ships with all new libstdc++ and libgcc features in a static lib. So your application still links to the system default version at runtime. [Here's](http://pastebin.com/Jyv7G9ze) what my new libstdc++.so contains. Am I missing something? (cc @ChristianConvey) – Praetorian Dec 17 '15 at 17:39
  • @Praetorian, you're absolutely right. I wrote this answer before joining the team at Red Hat that produces the devtoolset, and I clearly didn't know what I was talking about! The whole point of devtoolset is to support this workflow. It's still not safe to link to the GCC 4.7 libstdc++.so and use a different one at run-time, but the point is that when you use devtoolset you never link to the GCC 4.7 libstdc++.so, only to libstdc++_nonshared.a -- I'll update the answer (or feel free to add your own answer). – Jonathan Wakely Dec 17 '15 at 18:46
  • Please go ahead and update your answer, clearly at least 6 other people have found this information useful, and it'll be good to have it corrected. – Praetorian Dec 17 '15 at 20:50
  • 2
    Updated link to that PDF with page 26 (mentioned by Praetorian): http://kr.redhat.com/summit/2012/pdf/2012-DevDay-How-To-Toolset-Newsome.pdf – jfritz42 Jan 21 '16 at 17:27
  • both links to the pdf are broken. :-(. Thanks for your comments! – rboc Aug 03 '18 at 10:32