Take the 2-minute tour ×

The server I want to run some code on has older versions of gcc (gmp,mpc,mpfr too) installed in the standard locations like /usr* the admin is unwilling to update but has allowed me to install a newer version of gcc in my /home/username directory. I have done this an now have g++d46 as gcc 4.6.3 installed in my home dir /home/myusername/opt2/gcc-4.6.3. I also have gmp,mpfr,mpc installed in /home/myusername/tmp/gcc/{include,lib,share}.

I have exported {LD_LIBRARY_PATH, LIBRARY_PATH,LD_RUN_PATH}=/home/myusername/tmp2/gcc/lib:/home/myusername/opt2/gcc-4.6.3/lib/gcc/x86_64-unknown-linux-gnu/4.6.3:/home/myusername/opt2/gcc-4.6.3/lib64: and PATH=/bin:/usr/bin:/home/myusername/opt2/gcc-4.6.3/bin: also {C_INCLUDE_PATH,CPLUS_INCLUDE_PATH}=/home/myusername/tmp2/gcc/include:/home/myusername/opt2/gcc-4.6.3/include/c++/4.6.3:

I then compile some test code with

g++d46 -g -O3 -I/home/myusername/tmp2/gcc/include -L/home/myusername
/tmp2/gcc/lib -Wall testMPFR3.cpp -o myBin -lgmp -lgmpxx -lmpfr

which compiles and executes OK, but upon doing ldd myBin I see that despite being mostly linked with the correct libs on my home directory, we also have:

libm.so.6 => /lib64/libm.so.6 (0x0000003917e00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003917a00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003917600000)

which are not on my home dir, how does it even know to look elsewhere, given the env vars I have exported and my -I and -L flags?

Also if I do g++ -H to see where the headers are coming from, again most (including the new gmp,mpfr thankfully) are coming from my home dir, but a few:

...... /usr/include/gnu/stubs-64.h
........ /usr/include/stdio.h
........ /usr/include/bits/wchar.h
........ /usr/include/xlocale.h
....... /usr/include/locale.h
 ..... /usr/include/ctype.h
....... /usr/include/bits/types.h
........ /usr/include/bits/typesizes.h
....... /usr/include/endian.h
........ /usr/include/bits/endian.h
........ /usr/include/pthread.h
......... /usr/include/sched.h
.......... /usr/include/time.h
......... /usr/include/signal.h
......... /usr/include/bits/pthreadtypes.h
......... /usr/include/bits/setjmp.h

I don't understand why my local gcc-4.6.3 is missing these? nor how the linker knows to revert to /usr/* if it doesn't find them on the home dir?

I could use the flag --nostdinc upon compilation perhaps, but this probably wont solve the problem that the above headers can't be found locally for some reason.

share|improve this question

1 Answer 1

up vote 4 down vote accepted

The headers you are mentioning as well as /lib64/libc.so and /lib64/libm.so belong to glibc (as the placement in /lib64 already suggests these are core system files (otherwise they would be in /usr/lib64). If you compile your own copy of it you can link your programs against it of course. But unless this is really important for you, try not to - basically everything links against libc, which means you should recompile everything (including your GCC and likely anything it depends on) to make sure you don't end up with a binary, that links with lib-xyz and your glibc installation while lib-xyz would use system glibc. That could have some nasty side-effects.

If you are interested in building a more up-to-date toolchain, it certainly can be done, yet to do it properly, you should probably take a look at Linux from scratch and rip the pieces that would apply to your use-case.

As for how the dynamic linker works - check man ld.so (as I suggested in your previous question). To find out how GCC searches for included headers, you probably want to read about -I and --sysroot in man gcc.

share|improve this answer
I see, if they are core system files, then that is probably OK, I was just worried my gcc build had missed out some headers/libs that it should have installed, as long as that's not the case, and as long as it's searching to include other (non-system) headers from my local ~/opt/gcc-4.6.3 first then I guess that is all OK. –  fpghost Dec 3 '12 at 17:42
I have another query (maybe I should put in a new thread): I am using a c++ wrapper (holoborodko.com/pavel) for the mpfr multiprecision data types. Now this wrapper has no constructor for long long int i.e. long long int i=5LL; mpreal myvar(i) shouldn't really be allowed. However on my 32 bit linux desktop, compilation of this goes through without error, and the results of execution of bin are accurate. Nevertheless this server is 64bit, and the above code does not compile saying error mpreal(long long int) ambigious –  fpghost Dec 3 '12 at 17:46
is this because of the 64bit system vs 32bit system? does 32bit system somehow just cast long long int to say long int for which a constructor is defined in the wrapper? –  fpghost Dec 3 '12 at 17:47
@fpghost Generally speaking on 32bit system a quad-word can be "interpreted" in the sense of employing a software machinery (part of GCC) instead of using a single assembly instruction - pretty much as for floating point on a CPU which lacks FPU (and which is something like GMP, just stripped down to minimum). See e.g. stackoverflow.com/questions/330374/… . –  peterph Dec 4 '12 at 0:15
@fpghost As for the result, since the value is 5, it might be casted to a double-word right away (and probably will be) - search or ask on stackoverflow, if you want to know more. From then on, all calculation is handled my MPFR, which takes care of any arithmetic on its own, and it's its main goal to give results independent of the underlying hardware architecture. –  peterph Dec 4 '12 at 0:22

Your Answer


