10

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?

cjordan1
  • 277
  • 1
  • 4
  • 11
  • libc is nothing to do with GCC, so there is no "newer one compiled with gcc-4.8.1", it's supposed to link to the system libc. Presumably when you say it links to the system libstdc++ you mean it links correctly but fails to run, due to incorrect libstdc++ version? – Jonathan Wakely Jun 21 '13 at 08:01
  • @JonathanWakely Yes, that's correct. – cjordan1 Jun 21 '13 at 18:44

3 Answers3

16

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
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 3
    As well as that FAQ entry see [How do I insure that the dynamically linked library will be found?](http://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.how_to_set_paths) and [Finding Dynamic or Shared Libraries](http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html#manual.intro.using.linkage.dynamic) ... turns out RTFM answers this question :) – Jonathan Wakely Jun 20 '13 at 23:21
  • @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. – Maxim Egorushkin Jun 21 '13 at 09:03
  • 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 Jun 21 '13 at 16:02
  • See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53002 for the solution to the multilib problem and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45508#c10 for a possible future solution – Jonathan Wakely Jun 21 '13 at 16:25
  • @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, http://stackoverflow.com/questions/16826585/how-to-configure-libstdc-with-gcc-4-8?rq=1 and http://stackoverflow.com/questions/5718753/custom-built-gcc-4-6-0-on-ubuntu-11-04-links-wrong-libstdc?rq=1 ask essentially the same question. – cjordan1 Jun 21 '13 at 18:47
  • @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. – Maxim Egorushkin Jun 21 '13 at 19:12
  • @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`? – David Doria Dec 01 '16 at 14:11
  • @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. – Maxim Egorushkin Dec 01 '16 at 14:45
  • @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: http://stackoverflow.com/a/16826679/284529) – David Doria Dec 01 '16 at 16:49
  • 1
    @DavidDoria It is the correct way of specifying non-standard paths to shared libraries, unlike `LD_LIBRARY_PATH`. https://gms.tf/ld_library_path-considered-harmful.html – Maxim Egorushkin Dec 01 '16 at 17:01
6

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).

Glenn Coombs
  • 153
  • 2
  • 11
  • 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 https://stackoverflow.com/a/10662297/981959 – Jonathan Wakely Jul 02 '18 at 13:06
  • 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. – Glenn Coombs Jul 04 '18 at 11:55
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.

Brett Hale
  • 21,653
  • 2
  • 61
  • 90
  • 2
    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 Jun 20 '13 at 23:19
  • @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. – Brett Hale Jun 20 '13 at 23:44
  • 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. – Jonathan Wakely Jun 21 '13 at 08:00
  • @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. – Brett Hale Jun 21 '13 at 10:58
  • Exactly right, and if that libstdc++.so is not the one the binary was originally linked to it'll fail to run – Jonathan Wakely Jun 21 '13 at 16:03