2013-06-17 10 views
2

У меня есть пользовательский построенный gcc-4.7.2 в моей среде. Система gcc равна gcc-4.3.4.библиотеки, которые существуют в двоичном эльфе RUNPATH, не используются?

Я залатал RUNPATH для бинарных файлов все моего пользовательского ССАГПЗА и разделяемые библиотеки, используя patchelf --set-rpath

Однако, когда я бег ldd на моем 4.7.2 cc1 он поднимает систему libstdc++ вместо один указал на по 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) 

Как можно видеть, RUNPATH задающее gcc-4.7.2 библиотека места:

$ 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: \ 
    /hostname/sig/lib64: \ 
    /hostname/sig/lib] 

Я знаю, что libstdc++.so.6 существует в первой записи в 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 

не имеет LD_LIBRARY_PATH набора в моей среде:

$ echo $LD_LIBRARY_PATH 

$ 
  • Почему он не забирает библиотеку, найденную в RUNPATH?
  • Как я могу заставить его использовать библиотеки gcc-4.7.2?

ответ

3

Проблема состоит в том, что одним из условий (libppl.so) также импортирует libstdc++. Это условие было построено с использованием системы GCC, и, следовательно, находит /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) 

После библиотека была расположена по динамическому загрузчику один раз, он не будет больше не искал; это место будет использоваться для любых последующих требований.

Я разрешил это перестроить предварительные условия с новым 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) 

Я думаю, что последний шаг - это перестроить gcc с новыми предпосылками построения.

  • сборка предпосылки с системой НКОЙ
  • построить новый GCC
  • перестраивать предпосылки новой НКУ
  • восстановить НКУ с перестроена предпосылкой

ли окончательный шаг необходим, я не уверен, ,

+0

Привет. Но вы могли бы в принципе исправить 'libppl.so' с' patchelf', чтобы изменить его '' RUNPATH' вместо того, чтобы перестроить его с помощью пользовательского 'gcc'? Или 'gcc' делает какую-то дополнительную неявную магию, которая работает вокруг' RUNPATH'? – xealits

1

Вам необходимо установить LD_LIBRARY_PATH, чтобы указать на нужный libstdc++. RUNPATH оценивается после LD_LIBRARY_PATH.

RPATH issue Цитируя:

The dynamic linker will look for a matching library in the following locations, in this order, which can be changed (see the footnotes below): 
1. the DT_RPATH dynamic section attribute of the library causing the lookup 
2. the DT_RPATH dynamic section attribute of the executable 
3. the LD_LIBRARY_PATH environment variable, unless the executable is setuid/setgid. 
4. the DT_RUNPATH dynamic section attribute of the executable 
5. /etc/ld.so.cache 
6. base library directories (/lib and /usr/lib) 
+1

Я не хочу использовать LD_LIBRARY_PATH. Я думаю, что заставить пользователей менять свою среду - это неправильный подход и хрупкий. Итак, в этой ситуации нет LD_LIBRARY_PATH, поэтому RUNPATH следует использовать следующим образом? Если это так, то почему это не работает? –

+0

Из статьи, которую вы цитировали: LD_LIBRARY_PATH нельзя использовать, поскольку у нее есть свои проблемы: она будет наследоваться всеми процессами, генерируемыми родителем, и поэтому также не рекомендуется использовать ее для возможных побочных эффектов. –