5

gcc-4.7.2我在我的环境中定制了。系统 gcc 是gcc-4.3.4.

我已经为我的所有自定义 gcc 的二进制文件和共享库修补了RUNPATH ,使用patchelf --set-rpath

但是,当我ldd在 4.7.2 上运行时,cc1它会选择系统而不是RUNPATHlibstdc++指向的系统:

$ 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库?
4

2 回答 2

5

问题是先决条件之一 ( 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 构建先决条件
  • 构建新的 gcc
  • 使用新的 gcc 重建先决条件
  • 使用重建的先决条件重建 gcc

最后一步是否必要我不确定。

于 2013-06-18T00:57:48.940 回答
2

您需要将LD_LIBRARY_PATHto 指向所需的libstdc++. RUNPATH在 之后进行评估LD_LIBRARY_PATH

引用RPATH 问题

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) 
于 2013-06-17T08:53:41.060 回答