Linking G++ 4.8 to Libstdc++

Linking g++ 4.8 to libstdc++

When you link with your own gcc you need to add an extra run-time linker search path(s) with -Wl,-rpath,$(PREFIX)/lib64 so that at run-time it finds the shared libraries corresponding to your gcc.

I normally create a wrapper named gcc and g++ in the same directory as gcc-4.8 and g++-4.8 which I invoke instead of gcc-4.8 and g++-4.8, as prescribed in Dynamic linker is unable to find GCC libraries:

#!/bin/bash
exec ${0}SUFFIX -Wl,-rpath,PREFIX/lib64 "$@"

When installing SUFFIX and PREFIX should be replaced with what was passed to configure:

cd ${PREFIX}/bin && rm -f gcc g++ c++ gfortran
sed -e 's#PREFIX#${PREFIX}#g' -e 's#SUFFIX#${SUFFIX}#g' gcc-wrapper.sh > ${PREFIX}/bin/gcc
chmod +x ${PREFIX}/bin/gcc
cd ${PREFIX}/bin && ln gcc g++ && ln gcc c++ && ln gcc gfortran

(gcc-wrapper.sh is that bash snippet).


The above solution does not work with some versions of libtool because g++ -Wl,... -v assumes linking mode and fails with an error.

A better solution is to use specs file. Once gcc/g++ is built, invoke the following command to make gcc/g++ add -rpath to the linker command line (replace ${PREFIX}/lib64 as necessary):

g++ -dumpspecs | awk '/^\*link:/ { print; getline; print "-rpath=${PREFIX}/lib64", $0; next } { print }' > $(dirname $(g++ -print-libgcc-file-name))/specs

How to configure libstdc++ with GCC 4.8?

You need to tell your dynamic linker (it's executed when you run your program) where to find the library. Set LD_LIBRARY_PATH to the path of the library (probably somewhere under /app/gcc/4.8.0/lib or something).

Use find /app/gcc/4.8.0 -name "libstdc++.so.6". Add the directory to your LD_LIBRARY_PATH. e.g with the path I mentioned:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/app/gcc/4.8.0/lib (if you're using a bourne-like shell which the default on Linux).

Then try to run your program.

If it works, you'll probably want to configure your dynamic linker to look in the directory without using LD_LIBRARY_PATH. See man ld.so for details about how to configure the path.

New version of g++ with an older version of libstdc++

Is there a way to use g++ 7.1.0 and still use the standard library (both headers and libstdc++.so) from g++ 4.8.5 installed with CentOS?

Don't do that (the ABI of libstdc++ from GCC 4.8 & GCC 7 are likely to be different). Instead consider perhaps linking the C++ standard library (from GCC 7.1) statically (and other libraries dynamically, notably those in C including libc.so, not C++).

BTW, how did you get  g++-7.1? You could consider compiling GCC 7 (from its source code) on your CentOS 7 (or get some packaged version of it), then you'll have the right libstdc++

Read more about shared libraries, e.g. read Drepper's paper How To Write Shared Libraries and learn more about the -rpath option passed to ld (often using -Wl,-rpath to g++).

Why g++ tries to link against the wrong libstdc++.so library?

/opt/rh/devtoolset-7

devtoolset-7 :

/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/libstdc++.so

...... is a 210B text file :

/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-x86-64)
INPUT ( /usr/lib64/libstdc++.so.6 -lstdc++_nonshared )

/usr/lib64/libstdc++.so.6 will be used.


"Other extra gcc/g++" for EL7 : how to install gcc 4.9.2 on RHEL 7.4

C++ project compiled with modern compiler, but linked against outdated libstdc++

Anyway, the resulting artifacts appear to be linked with system default version of libstdc++:

Yes. The devtoolset-6-gcc-c++ package provides a custom version of GCC that uses a special linker script instead of a dynamic library for libstdc++.so. That means the binaries it produces do not depend on the newer libstdc++.so.6 and can be run on other CentOS machines that don't have devtoolset installed (i.e. they only have the older libstdc++ library from GCC 4.8).

Is this build environment configuration valid?

Yes. What you're seeing is completely normal, and how it's supposed to work.

The pieces of the newer C++ runtime from GCC 6.4.0 get statically linked into your binary, and at runtime it only depends on the old libstdc++.so which every CentOS system has installed.

That's the whole point of the devtoolset version of GCC.

GCC not linking against libstdc++?

tl;dr: Invoke g++ rather than gcc to avoid this problem

(based on @SergeyA's comment)

GCC behaves differently depending on whether you run it as the gcc or the g++ binary. Specifically, it apparently won't automatically link against its bundled C++ standard library, libstdc++. I'm guessing it will link against its C standard library - which doesn't help you much.

So just use the appropriate binary for your language; specifying --std=c++whatever isn't enough.



Related Topics



Leave a reply



Submit