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
C/C++ Changing the Value of a Const
Error: Variable "Cannot Be Implicitly Captured Because No Default Capture Mode Has Been Specified"
C++ Remove Punctuation from String
How Portable Is End Iterator Decrement
Logical And, Or: Is Left-To-Right Evaluation Guaranteed
C++ Typedef Interpretation of Const Pointers
Avoiding the Tedium of Optional Parameters
Declare a Reference and Initialize Later
Do All Pointers Have the Same Size in C++
C++11 Static_Assert and Template Instantiation
Why Does Std::Map Operator[] Create an Object If the Key Doesn't Exist
Why Are Some Functions in <Cmath> Not in the Std Namespace
How to Make Reading from 'Std::Cin' Timeout After a Particular Amount of Time
What Happens When a Computer Program Runs