Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have custom built gcc-4.7.2 in my environment. The system gcc is gcc-4.3.4.

I have patched the DT_RUNPATH for all my custom gcc's binaries and shared libraries using patchelf --set-rpath

However, when I run ldd on my 4.7.2 cc1 it picks up the system libstdc++ instead of the one pointed to by the DT_RUNPATH:

$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/4.7.2/cc1
        libcloog-isl.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libcloog-isl.so.1 (0x00007f072dce8000)
        ...
        libc.so.6 => /lib64/libc.so.6 (0x00007f072bfe0000)
   -->  libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f072bcd5000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f072babe000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f072df0d000)

As can be seen the DT_RUNPATH specifies the gcc-4.7.2 library locations:

$ readelf -a /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/4.7.2/cc1 | grep PATH
 0x000000000000001d (RUNPATH)            Library runpath: \
    [/sdk/x86_64/2.11.1/gcc-4.7.2/lib64: \
     /sdk/x86_64/2.11.1/gcc-4.7.2/lib: \
     /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/lib64: \
     /sdk/x86_64/2.11.1/gcc-4.7.2/lib/gcc/x86_64-suse-linux/4.7.2]

I know that libstdc++.so.6 exists in the first entry in the DT_RUNPATH:

$ ls -l /sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so*
lrwxrwxrwx .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so -> libstdc++.so.6.0.17
lrwxrwxrwx .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6 -> libstdc++.so.6.0.17
-rwxr-x--- .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6.0.17
-rwxr-x--- .../sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6.0.17-gdb.py

I don't have an LD_LIBRARY_PATH set in my environment:

$ echo $LD_LIBRARY_PATH

$

If I do set LD_LIBRARY_PATH then it finds the correct library:

export LD_LIBRARY_PATH=/sdk/x86_64/2.11.1/gcc-4.7.2/lib64: \
    /sdk/x86_64/2.11.1/gcc-4.7.2/lib: \
    /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/lib64: \
    /sdk/x86_64/2.11.1/gcc-4.7.2/lib/gcc/x86_64-suse-linux/4.7.2

$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/libexec/gcc/x86_64-suse-linux/4.7.2/cc1
        libcloog-isl.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libcloog-isl.so.1 (0x00007f072dce8000)
        ...
        libc.so.6 => /lib64/libc.so.6 (0x00007f072bfe0000)
   -->  libstdc++.so.6 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libstdc++.so.6 (0x00007fdf4e560000)
        libgcc_s.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib64/libgcc_s.so.1 (0x00007fdf4e34b000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f072df0d000)
  • How come it doesn't pick up the library found in DT_RUNPATH?
  • How can I force it to use the gcc-4.7.2 libraries without having to use LD_LIBRARY_PATH?
share|improve this question
add comment

1 Answer

The problem is that one of the prerequisites (libppl.so) also imports libstdc++. That prerequisite was built using the system gcc, and therefore finds /usr/lib64/libstdc++.so.6

$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libppl.so
        linux-vdso.so.1 =>  (0x00007fffd10db000)
        libgmpxx.so.4 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmpxx.so.4 (0x00007f4716f92000)
        libgmp.so.10 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmp.so.10 (0x00007f4716d26000)
    --> libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f4716a25000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f47167a0000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f4716441000)
        libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007f471622c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f47174b4000)

Once a library has been located by the dynamic linker once, it will no longer be searched for; that location will be used for any subsequent requirements.

I resolved this by rebuilding the prerequisites with the new gcc.

$ ldd /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libppl.so
        linux-vdso.so.1 =>  (0x00007fffd10db000)
        libgmpxx.so.4 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmpxx.so.4 (0x00007f4716f92000)
        libgmp.so.10 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/libgmp.so.10 (0x00007f4716d26000)
    --> libstdc++.so.6 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/../lib64/libstdc++.so.6 (0x00007f4716a25000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f47167a0000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f4716441000)
        libgcc_s.so.1 => /sdk/x86_64/2.11.1/gcc-4.7.2/lib/../lib64/libgcc_s.so.1 (0x00007f471622c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f47174b4000)

I'm thinking the final step is to now rebuild gcc with the newly build prerequisites.

  • build prerequisites with system gcc
  • build new gcc
  • rebuild prerequisites with new gcc
  • rebuild gcc with rebuilt prerequisites

Whether the final step is necessary I'm not sure.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.