Gcc 为什么在构建共享库时--rpath会被取代?
我在CentOS机器上工作。我有一个文件(Gcc 为什么在构建共享库时--rpath会被取代?,gcc,ld,Gcc,Ld,我在CentOS机器上工作。我有一个文件(test.c)正在编译到共享库中 test.c: #include <stdio.h> #include <stdlib.h> #include <quadmath.h> int my_func(void){ __float128 r; r = strtoflt128 ("1.2345678", NULL); int * b = malloc(sizeof(int) * 5); doub
test.c
)正在编译到共享库中
test.c
:
#include <stdio.h>
#include <stdlib.h>
#include <quadmath.h>
int my_func(void){
__float128 r;
r = strtoflt128 ("1.2345678", NULL);
int * b = malloc(sizeof(int) * 5);
double a = 10*M_PI_2q;
printf("Hello world %f\n",a);
return 0;
}
从ld
的详细输出中,似乎找到了/opt/gcc/5.5.0/lib64/libquadmath.so.0
(这就是我想要的)。即
但是,当我使用ldd poo.so查看时,它没有正确的库。即
$ ldd poo.so
linux-vdso.so.1 => (0x00007fffc0e8e000)
libquadmath.so.0 => /act/gcc-4.7.2/lib64/libquadmath.so.0 (0x00002aea8fd39000)
libc.so.6 => /lib64/libc.so.6 (0x00002aea8ff6f000)
libm.so.6 => /lib64/libm.so.6 (0x00002aea90303000)
/lib64/ld-linux-x86-64.so.2 (0x00002aea8f8f2000)
我正在使用gcc
version5.5.0,希望poo.so
链接到/opt/gcc/5.5.0/lib/libquadmath.so.0
,而不是4.7.2版本
我认为这与/etc/ld.so.conf
中存在指定旧库位置的文件有关。即
$ cat /etc/ld.so.conf.d/gcc-4.7.2.conf
/act/gcc-4.7.2/lib64
/act/gcc-4.7.2/lib
ld
(如我所问)的手册页不太有用
问题:我在链接和构建共享库时指定了
-rpath
,但我不明白为什么它会找到较旧的gcc-4.7.2版本的quadmath库。为什么链接器似乎对/etc/ld.so.conf
中的路径进行了优先级排序,而忽略了-rpath
选项?如何在编译时指定库的位置以及如何解决此问题?要理解解决方案,首先我们必须理解错误的想法
ld
(在编译时使用)和ld.so
(在运行时使用)。ld.so的手册页描述了如何在运行时找到库。要总结it搜索,请执行以下操作:
a) DT_RPATH
b) 在LD\u LIBRARY\u路径中指定的目录
c) 二进制文件的DT_运行路径动态部分中的目录(如果存在)
d) 缓存文件/etc/ld.so.Cache
e) 默认路径是/lib,然后是/usr/lib
ld
的手册页主要把我弄糊涂了。它在-rpath选项下显示:
将目录添加到运行库搜索路径。这在将ELF可执行文件与共享对象链接时使用
我认为在构建共享库时传递-rpath
会
保证它可以在不需要设置的情况下找到库
LD\u库路径
错误。此功能似乎只有用
生成可执行文件时,不是共享库。有一个-rpath链接
选项,但我不知道如何使它工作$ cat test2.c
#include <stdio.h>
#include <stdlib.h>
#include <quadmath.h>
int main(void){
__float128 r;
r = strtoflt128 ("1.2345678", NULL);
int * b = malloc(sizeof(int) * 5);
double a = 10*M_PI_2q;
printf("Hello world %f\n",a);
return 0;
}
$ export LD_LIBRARY_PATH=
$ which gcc
/opt/gcc/5.5.0/bin/gcc
$ gcc -Wl,-rpath,/opt/gcc/5.5.0/lib64 test2.c -lquadmath
$ ldd a.out
linux-vdso.so.1 => (0x00007fffff34f000)
libquadmath.so.0 => /opt/gcc/5.5.0/lib64/libquadmath.so.0 (0x00002b9c35e07000)
libc.so.6 => /lib64/libc.so.6 (0x00002b9c36069000)
libm.so.6 => /lib64/libm.so.6 (0x00002b9c363fd000)
/lib64/ld-linux-x86-64.so.2 (0x00002b9c35be5000)
$ readelf -a a.out | grep -i rpath
0x000000000000000f (RPATH) Library rpath: [/opt/gcc/5.5.0/lib64]
$cat test2.c
#包括
#包括
#包括
内部主(空){
__浮子;
r=strtoflt128(“1.2345678”,空);
int*b=malloc(sizeof(int)*5);
双a=10*M_PI_2q;
printf(“你好世界%f\n”,a);
返回0;
}
$export LD\u LIBRARY\u路径=
$gcc
/opt/gcc/5.5.0/bin/gcc
$gcc-Wl,-rpath,/opt/gcc/5.5.0/lib64 test2.c-lquadmath
$ldd a.out
linux vdso.so.1=>(0x00007fffff34f000)
libquadmath.so.0=>/opt/gcc/5.5.0/lib64/libquadmath.so.0(0x00002b9c35e07000)
libc.so.6=>/lib64/libc.so.6(0x00002b9c36069000)
libm.so.6=>/lib64/libm.so.6(0x00002b9c363fd000)
/lib64/ld-linux-x86-64.so.2(0x00002b9c35be5000)
$readelf-a a.out | grep-i rpath
0x000000000000000f(RPATH)库RPATH:[/opt/gcc/5.5.0/lib64]
/opt/gcc/5.5.0/bin/gcc
的路径并查看与之相关的路径。我通过设置export LD_LIBRARY\u PATH=
并排除rpath
参数来检查这一点,即gcc-shared-Wl,--verbose-Wl,-soname,poo.so-o poo.so test.o-lquadmath
。即使在那时,它也能够链接到正确的libquadmath.so.0
库ldpoo.so
找不到正确的库的原因是它需要libquadmath.so.0
库的
版本。这是库的32位版本。当您检查库的两个版本并看到它们分别是ELF64和ELF32(例如readelf-a/opt/gcc/5.5.0/lib64/libquadmath.so.0 | grep Class
)时,这一点就很明显了ld.so
在默认情况下查看/etc/ld.conf.cache
(它建立在“/etc/ld.conf.d/”的基础上)来决定要查找哪些目录。这就是为什么它发现了quadmath的4.7.2版本export
LD_LIBRARY_PATH=/opt/gcc/5.5.0/lib64
ld
(b/c它查看了gcc的相对路径),但在运行时找不到正确的库(b/c ld\u library\u路径设置不正确)。解决办法是:
export-LD\u-LIBRARY\u-PATH=/opt/gcc/5.5.0/lib64
<代码>-rpath在构建共享库时不是有效的选项。要理解解决方案,首先我们必须理解错误的想法
ld
(在编译时使用)和ld.so
(在运行时使用)。ld.so的手册页描述了如何在运行时找到库。要总结it搜索,请执行以下操作:
a) DT_RPATH
b) 在LD\u LIBRARY\u路径中指定的目录
c) 二进制文件的DT_运行路径动态部分中的目录(如果存在)
d) 缓存文件/etc/ld.so.Cache
e) 默认路径是/lib,然后是/usr/lib
ld
的手册页主要把我弄糊涂了。它是
$ cat /etc/ld.so.conf.d/gcc-4.7.2.conf
/act/gcc-4.7.2/lib64
/act/gcc-4.7.2/lib
$ cat test2.c
#include <stdio.h>
#include <stdlib.h>
#include <quadmath.h>
int main(void){
__float128 r;
r = strtoflt128 ("1.2345678", NULL);
int * b = malloc(sizeof(int) * 5);
double a = 10*M_PI_2q;
printf("Hello world %f\n",a);
return 0;
}
$ export LD_LIBRARY_PATH=
$ which gcc
/opt/gcc/5.5.0/bin/gcc
$ gcc -Wl,-rpath,/opt/gcc/5.5.0/lib64 test2.c -lquadmath
$ ldd a.out
linux-vdso.so.1 => (0x00007fffff34f000)
libquadmath.so.0 => /opt/gcc/5.5.0/lib64/libquadmath.so.0 (0x00002b9c35e07000)
libc.so.6 => /lib64/libc.so.6 (0x00002b9c36069000)
libm.so.6 => /lib64/libm.so.6 (0x00002b9c363fd000)
/lib64/ld-linux-x86-64.so.2 (0x00002b9c35be5000)
$ readelf -a a.out | grep -i rpath
0x000000000000000f (RPATH) Library rpath: [/opt/gcc/5.5.0/lib64]