Linking g++ 4.8 to libstdc++

10,082

Solution 1

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

Solution 2

I just had the same problem when building gcc-4.8.2. I don't have root access on that machine and therefore need to install to my home directory. It took several attempts before I figured out the magic required to get this to work so I will reproduce it here so other people will have an easier time. These are the commands that I used to configure gcc:

prefix=/user/grc/packages

export LDFLAGS=-Wl,-rpath,$prefix/lib
export LD_RUN_PATH=$prefix/lib
export LD_LIBRARY_PATH=$prefix/lib

../../src/gmp-4.3.2/configure  --prefix=$prefix
../../src/mpfr-2.4.2/configure --prefix=$prefix
../../src/mpc-0.8.1/configure  --prefix=$prefix --with-mpfr=$prefix --with-gmp=$prefix
../../src/gcc-4.8.2/configure  --prefix=$prefix --with-mpfr=$prefix --with-gmp=$prefix --with-mpc=$prefix --enable-languages=c,c++

That got me a working binary but any program I built with that version of g++ wouldn't run correctly unless I built it with the -Wl,-rpath,$prefix/lib64 option. It is possible to get g++ to automatically add that option by providing a specs file. If you run

strace g++ 2>&1 | grep specs

you can see which directories it checks for a specs file. In my case it was $prefix/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/specs so I ran g++ -dumpspecs to create a new specs file:

cd $prefix/lib/gcc/x86_64-unknown-linux-gnu/4.8.2
$prefix/bin/g++ -dumpspecs > xx
mv xx specs

and then edited that file to provide the -rpath option. Search for the lines like this:

*link_libgcc:
%D

and edit to add the rpath option:

*link_libgcc:
%D -rpath /user/grc/packages/lib/%M

The %M expands to either ../lib or ../lib64 depending on whether you are building a 32-bit or a 64-bit executable.

Note that when I tried this same trick on an older gcc-4.7 build it didn't work because it didn't expand the %M. For older versions you can remove the %M and just hardcode lib or lib64 but that is only a viable solution if you only ever build 32-bit executables (with lib) or only ever build 64-bit executables (with lib64).

Solution 3

gcc -print-search-dirs will tell you where your compiler is looking for runtime libraries, etc. You can override this with the -B<prefix> option.

Share:
10,082
cjordan1
Author by

cjordan1

Updated on July 17, 2022

Comments

  • cjordan1
    cjordan1 almost 2 years

    I downloaded and built gcc 4.8.1 on my desktop, running 64-bit Ubuntu 12.04. I built it out of source, like the docs recommend, and with the commands

    ../../gcc-4.8.1/configure --prefix=$HOME --program-suffix=-4.8
    make
    make -k check
    make install
    

    It seemed to pass all the tests, and I installed everything into my home directory w/ the suffix -4.8 to distinguish from the system gcc, which is version 4.6.3.

    Unfortunately when I compile c++ programs using g++-4.8 it links to the system libc and libstdc++ rather than the newer ones compiled from gcc-4.8.1. I downloaded and built gcc 4.8 because I wanted to play around with the new C++11 features in the standard library, so this behaviour is definitely not what I wanted. What can I do to get gcc-4.8 to automatically link to the standard libraries that came with it rather than the system standard libraries?

  • Jonathan Wakely
    Jonathan Wakely almost 11 years
    GCC will look for the right libraries automatically at link-time, the problem is that the dynamic linker doesn't use the same paths at run-time, and using -B can't change that
  • Jonathan Wakely
    Jonathan Wakely almost 11 years
    As well as that FAQ entry see How do I insure that the dynamically linked library will be found? and Finding Dynamic or Shared Libraries ... turns out RTFM answers this question :)
  • Brett Hale
    Brett Hale almost 11 years
    @JonathanWakely - well, the OP claims otherwise: "Unfortunately when I compile c++ programs using g++-4.8 it links to the system libc and libstdc++..." - you'll have to clarify it with him.
  • Jonathan Wakely
    Jonathan Wakely almost 11 years
    See the links in my comment on the other answer, this is a FAQ. The compiler links to the right libraries at link-time, but it's up to the user to ensure the same libraries are used again at run-time.
  • Maxim Egorushkin
    Maxim Egorushkin almost 11 years
    @JonathanWakely I would really like to see instructions how to modify the spec file so that gcc adds rpath automatically. Modifying LD_LIBRARY_PATH is too manual and unreliable for me.
  • Brett Hale
    Brett Hale almost 11 years
    @JonathanWakely - ah. I see what you mean. Without -rpath options, it will just look for the first libstdc++.x.so in the ld.so cache, or LD_LIBRARY_PATH right? If I spend too long on SO, I tend to get tunnel vision.
  • Jonathan Wakely
    Jonathan Wakely almost 11 years
    IIRC Nasanov is the man to ask, I think he does that when building gcc from pkgsrc. It's quite simple for a non-multilib gcc, but is trickier when you want it to add lib or lib64 depending on the multilib target. I'll dig out some relevant links and email you later ...
  • Jonathan Wakely
    Jonathan Wakely almost 11 years
    Exactly right, and if that libstdc++.so is not the one the binary was originally linked to it'll fail to run
  • Jonathan Wakely
    Jonathan Wakely almost 11 years
    See gcc.gnu.org/bugzilla/show_bug.cgi?id=53002 for the solution to the multilib problem and gcc.gnu.org/bugzilla/show_bug.cgi?id=45508#c10 for a possible future solution
  • cjordan1
    cjordan1 almost 11 years
    @JonathanWakely RTFM is right. Unfortunately the manual is huge, I missed the relevant FAQ, and I didn't realize it was the dynamic linker that was giving me the problems. Also, stackoverflow.com/questions/16826585/… and stackoverflow.com/questions/5718753/… ask essentially the same question.
  • Maxim Egorushkin
    Maxim Egorushkin almost 11 years
    @JonathanWakely Thanks a lot Jon, the first link looks promising, I'll play with it. I already patch gold to support LD_RUN_PATH when building my toolchain, so adding another patch is easy, but I digress.
  • David Doria
    David Doria over 7 years
    @Maxim Egorushkin So is the idea that that g++ -dumpspecs command only applies the path to that particular g++ versus applying it to any g++ on the system if you had set it in LD_LIBRARY_PATH?
  • Maxim Egorushkin
    Maxim Egorushkin over 7 years
    @DavidDoria Not sure I understand your question. The idea is to add -rpath to linker commands of this gcc. Only the binaries produced by this gcc are affected.
  • David Doria
    David Doria over 7 years
    @Maxim Egorushkin I'm just trying to underand if this "non-system wide" behavior is the advantage of the -dumpspecs method vs other methods of getting this to work (like LD_LIBRARY_PATH: stackoverflow.com/a/16826679/284529)
  • Maxim Egorushkin
    Maxim Egorushkin over 7 years
    @DavidDoria It is the correct way of specifying non-standard paths to shared libraries, unlike LD_LIBRARY_PATH. gms.tf/ld_library_path-considered-harmful.html
  • Jonathan Wakely
    Jonathan Wakely almost 6 years
    You're making your life unnecessarily complicated installing gmp, mpfr and mpc manually and then having to set LD_LIBRARY_PATH to find them, see stackoverflow.com/a/10662297/981959
  • Glenn Coombs
    Glenn Coombs almost 6 years
    Thanks for that information. I must have missed that nugget 4.5 year's ago in the gcc build instructions. Nice to know for future reference.