Leap 42.1 libstdc++ devel and runtime different versions

I recently upgraded from 13.2 to Leap 42.1 and I was about committing some C++ source code to our svn-server but before that I wanted to check that the code compiled all right after some organization and clean-up. Not surprisingly, it did. What did surprise me, though, was that the executable files became much slower than they were on 13.2 and there’s no doubt the mystery lies in the build. I backed up my programs before upgrading and the old build still runs as fast as it did before. The difference in speed is huge, orders of magnitude, and I don’t understand why.

The code uses OpenMP for parallell execution of loops and utilizes GSL quadrature routines for nested integrals. At this point I see no reason to present any snippet of code as I have no clue what to show you. I started digging in the C++ development setup and to my surprise found that the devel package and runtime package of libstdc++ have different versions although consistent versions exist in the repo. Running

rpm -qa|grep c++

gives me:

libstdc++48-devel-4.8.5-18.1.x86_64
libstdc++6-32bit-5.3.1+r233831-6.1.x86_64
libstdc++6-5.3.1+r233831-6.1.x86_64
gcc-c+±4.8-8.4.x86_64
gcc48-c+±4.8.5-18.1.x86_64
libstdc+±devel-4.8-8.4.x86_64

Apparently the runtime libstdc++ has version 5.3.1+r233831 but the devel package has version 4.8.5 which is the same as the gcc and gcc-c++ version on the system. This mix of versions seems inconsistent to me but is it really? Can anyone tell me why the runtime and devel have different versions and could it have an impact on my build? Would it help if I also installed the 4.8.5 version of the runtime? Perhaps a better idea is to make the 5.3.1+r233831 installation consistent by also installing gcc5-c++ and libstdc++6-devel. Explanations and suggestions most welcome.

On this Leap 42.1 AMD 64-bit machine, also upgraded from 13.2, the C++ packages are as follows:


> rpm -qa | sort | grep 'c++'
gcc48-c++-4.8.5-18.1.x86_64
gcc5-c++-5.3.1+r233831-6.1.x86_64
gcc-c++-4.8-8.4.x86_64
libstdc++48-devel-4.8.5-18.1.x86_64
libstdc++6-32bit-5.3.1+r233831-6.1.x86_64
libstdc++6-5.3.1+r233831-6.1.x86_64
libstdc++6-devel-gcc5-5.3.1+r233831-6.1.x86_64
libstdc++6-locale-5.3.1+r233831-6.1.x86_64
libstdc++-devel-4.8-8.4.x86_64
> 

IMHO the 32.1 to Leap 42.1 upgrade possibly “missed” a couple of things, such as including gcc5:


> rpm -qa | sort | grep 'gcc5'
gcc5-5.3.1+r233831-6.1.x86_64
gcc5-c++-5.3.1+r233831-6.1.x86_64
gcc5-info-5.3.1+r233831-6.1.noarch
gcc5-locale-5.3.1+r233831-6.1.x86_64
libffi-devel-gcc5-5.3.1+r233831-6.1.x86_64
libstdc++6-devel-gcc5-5.3.1+r233831-6.1.x86_64
> 

Forgot to mention that, assuming that gcc-5 is installed parallel to gcc-48 then, “alternatives” (man 8 update-alternatives) will be needed to manage GCC 4.8 or GCC 5 compilation.

And something else: libstdc++6-gcc48-4.8.5-18.1.x86_64 conflicts with libstdc++6-5.3.1+r233831-6.1.x86_64.
(Rough translation from the German YaST output below.)


> cat conflicts.txt 
#### YaST2 conflicts list - generated 2016-06-16 17:46:49 ####

libstdc++6-gcc48-4.8.5-18.1.x86_64 conflicts with libstdc++6 offered by libstdc++6-5.3.1+r233831-6.1.x86_64

     ] Don't install libstdc++6-gcc48-4.8.5-18.1.x86_64

     ] Carry out the following actions:
De-install libstdc++6-5.3.1+r233831-6.1.x86_64
De-install libstdc++6-devel-gcc5-5.3.1+r233831-6.1.x86_64
De-install rawtherapee-4.2.922-36.1.x86_64
De-install gcc5-c++-5.3.1+r233831-6.1.x86_64



#### YaST2 conflicts list END ###
> 

Thanks for the answer. I have installed the gcc5 packages but so far have not tried it out.

By the way, it was not really an upgrade. It was a fresh install and the old system was 13.1. I had to trash the hard drive with the 13.1 installation because it got corrupt so the system would hang within minutes of starting.This was due to hardware errors so I bought a new hard drive. By booting Linux Mint from a USB stick I could save all data that hadn’t been backed up, though. Luckily only the system partition was broken as it seems.

Didn’t see your heads up about the conflict as I was editing my own reply. I didn’t install the older runtime but I’ll bear it in mind in case the gcc5 builds don’t come out well.

Curiously, update-alternatives cannot be used to manage gcc/g++ as it seems. This is what I get:

gostal@ki003685:~> update-alternatives --config gcc
update-alternatives: error: no alternatives for gcc

and

gostal@ki003685:~> update-alternatives --config g++
update-alternatives: error: no alternatives for g++

whereas for java I get:

gostal@ki003685:~> update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).

Selection Path Priority Status

  • 0 /usr/lib64/jvm/jre-1.8.0-openjdk/bin/java 1805 auto mode
    1 /usr/lib64/jvm/jre-1.7.0-openjdk/bin/java 1705 manual mode
    2 /usr/lib64/jvm/jre-1.8.0-openjdk/bin/java 1805 manual mode

and there are no gcc symlinks in /etc/alternatives. On purpose or missed?

Seems I have to edit my makefiles to do gcc5-builds.

Another post:

https://forums.opensuse.org/showthread.php/446392-on-gcc-installation

suggests gcc/g++ needs to be set up for update-alternatives.

I’m in the middle of removing gcc-5 – only needed it for a RawTherapee dependency (I’m not using RawTherapee at the moment) . . .
Following gcc-4.8 (left - mostly) versus gcc-5 (right) conflicts need to be observed:

  • libatomic1-gcc48 :: libatomic1
  • libffi4-gcc48 :: libffi4 also libffi-devel-gcc5 ]
  • libgcc_s1-gcc48 :: libgcc_s1 also libgcc_s1-gcc48-32bit ]
  • libgfortran3-gcc48 :: libgfortran3
  • libgomp1-gcc48 :: libgomp1
  • libitm1-gcc48 :: libitm1
  • libquadmath0-gcc48 :: libquadmath0
  • libstdc++6-gcc48 :: libstdc++6 also libstdc++6-devel-gcc5 ]
  • libstdc++6-gcc48-locale :: libstdc++6-locale
  • libtsan0-gcc48 :: libtsan0

Following have to be also not forgotten (install/remove):

  • gcc48-locale
  • cpp5
  • gcc5
  • gcc5-c++
  • gcc5-info
  • gcc5-locale

Leap 42.1: with gcc-48 “pure” it boots slower than when the gcc-5 runtime libraries (v5.xxx) were present.

  • I may possibly move back to a gcc-5 environment . . .

Quite a list of conflicts to bear in mind …

gcc/g++ needs to be set up for update-alternatives

After reading through the manual: there is apparently a risk that a setup of my making will be broken due to system updates. That and the hazzle of setting it up correctly suggests to me that it will be easier and more robust to control the gcc/g++ alternatives using variables in the makefiles if I choose not to set these variables to symlinks but rather the files themselves.

That should perhaps be environment variables and perhaps also exporting them by sourcing flles in which they are set. If i decide to stay with gcc5 and relatives I can always export them in .bashrc or .profile to avoid system wide changes.

Boot-time effects of using the GCC 4.8 (v4.8.5) libraries in stead of the GCC 5 (v5.3.1) libraries:

systemd-analyze with GCC 4.8 libraries:Startup finished in 6.067s (firmware) + 9.165s (loader) + 3.613s (kernel) + 6.858s (initrd) + 34.908s (userspace) = 1min 611ms

systemd-analyze with GCC 5 libraries:Startup finished in 2.487s (firmware) + 9.034s (loader) + 3.628s (kernel) + 5.378s (initrd) + 12.309s (userspace) = 32.838s
[HR][/HR]KDE Plasma 5 also behaves better with the v5 libraries . . .

IMHO, GCC 4.8 application development is better served with a 13.2 machine; Leap 42.1 is suitable for GCC 5 application development.

This may very well be the reason why my out-of-the-box installation had GCC 5 version of libstdc++ paired with GCC 4.8 C_C++ development environment, the latter probably being due to the conservative inheritance from SLE. The out-of-the-box presence of gcc5 indicates perhaps that some system-critical things hinge on GCC 5.

Would be nice if someone created a gcc update-alternatives…
I don’t have the deep understanding how gcc fully works and its dependencies to do it right, and I doubt that it would be as simple as the referenced thread in gostal’s post.
I already submitted a feature request for this about a year ago specifically to address Tumbleweed’s problems since it’ always installing the bleeding edge of gcc.

I’ve posted about this several times in the Virtualization forum,
Without a working update-alternatives, unless you want to specifically identify a non-default gcc by full path and name, most people will find it easier to just uninstall the default gcc and install the gcc they want, for example

zypper -n rm gcc && zypper -n in gcc5

Since the above can be run very quickly whenever you wish, you may want to simply save as a script and another version of the script that reverses.
Also, since AFAIK once something is compiled it’s not affected by a change in compiler so it’s conceivable to have your system boot up with modules compiled using GCC6, then switch installed compilers and run apps in GCC5 until you reboot (and then your new boot would use whatever GCC is default and active at the time).

I’d also caution against analyzing the effect on boot and believing that has any relationship to how anything else might run, there is not likely any relationship and if there is any similar effect, that might be co-incidental. You can only test your app to know the effect on your app.

IMO,
TSU

Need to differentiate between run-time libraries and the (include) libraries used by the compiler.
Unfortunately, GNU’s Compiler Collection and/or the RPM packages (don’t know how other packet managers handle this situation) blur the distinction.

  • In the case of GCC, every supported compiler (language) would have to split out the run-time libraries and the include libraries.
  • Which is in fact what cross-compilers do . . .

[HR][/HR]To do: need to investigate the issues around running different GCC versions as cross-compilers on the openSUSE platform.

The GCC FAQs have an entry dealing with installing multiple GCC versions: <https://gcc.gnu.org/faq.html#multiple>.
Haven’t fully checked it out but, I’m sceptical with respect to the issues around the (include) libraries used by the compiler(s).

I’m not sure how the methods described in that FAQ are supposed to work…

Seems to describe installing multiple gcc versions side by side, and then in the case of creating symlinks, links the default gcc (in the system path) to both gcc versions (apparently you also need to symlink the supporting libraries). This is more or less how update-alternatives works without switching.

But, without a switching mechanism, when something is symlinked to two different binaries how is the correct binary chosen and executed? Are both tried so at least one succeeds and the errors in the log relating to the failed binary are to be ignored?

Also, if that is all that needs to be done then it seems to me that by simply installing the “other” gcc packages, then scripts which require one or the other gcc should automatically work if the symlinks are installed by the package(s) (I’ve tried, that doesn’t work)?

TSU

Sorry, I didn’t have time to post this yesterday evening:
Assuming that one is using CMake the following inserted into the “Master/Top” ‘CMakeLists.txt’ before any “project”, “include_directories” or “add_executable” commands, seems to work on a Leap 42.1 system (GCC versions 4.8 and 5):


message( STATUS "Default C Compiler: ${CMAKE_C_COMPILER}" )
set( CMAKE_C_COMPILER /usr/bin/gcc-4.8 )
message( STATUS "Default C++ Compiler: ${CMAKE_CXX_COMPILER}" )
set( CMAKE_CXX_COMPILER /usr/bin/g++-4.8 )
message( STATUS "Project C Compiler: ${CMAKE_C_COMPILER}" )
message( STATUS "Project C++ Compiler: ${CMAKE_CXX_COMPILER}" )

The “message” commands are for trouble-shooting and debugging only.
Due to the “auto-magically” behaviour of CMake, I’ve absolutely no idea if this will work for other make environments.

In addition: one needs to take care with the ‘/usr/include/c++/’ files in the libstdc++48-devel package:

  • On this system ‘/usr/include/c++/’ has two sub-directories: '4.8
    ’ and ‘5’. - The '5
    ’ files are in the libstdc++6-devel-gcc5 package.

Assuming that an IDE such as KDevelop is being used, then in the project-specific settings this issue needs to be addressed to ensure that the “include” paths are correctly set-up.

I haven’t yet discovered any “nasties” with respect to the runtime libraries: on this Leap 42.1 system ‘/usr/lib64/libstdc++.so.6’ is linked to ‘/usr/lib64/libstdc++.so.6.0.21’ which was installed from the package libstdc++6.