我一直在尝试将共享库链接到我的程序中,我希望它的路径与我的RPATH相关。
但是,当我运行ldd时,我注意到共享库的绝对路径已链接。有什么想法吗?
修改
/home/projects/my_files/winter_fresh.so
libgcc_s.so.1 => /home/tomo/anaconda3/lib/libgcc_s.so.1 (0x00007f0a3bf64000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0a3bd47000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0a3b97d000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0a3e369000)
libstdc++.so.6 => /home/tomo/anaconda3/lib/libstdc++.so.6 (0x00007f0a3b643000)
问题是第一个文件。我不希望winter_fresh的库成为绝对路径,因为我有一个包含它的RPATH。
答案 0 :(得分:4)
问题是第一个文件。我不希望winter_fresh的库成为绝对路径
这种情况通常发生在您链接到您的图书馆时:
gcc ... /home/projects/my_files/winter_fresh.so ...
并且您的库没有SONAME
(构建它时您没有使用-soname
链接器选项。)
要解决此问题,请将SONAME
添加到winter_fresh.so
(一般来说是一种不错的做法),或者像这样链接:
gcc ... -L /home/projects/my_files -l:winter_fresh.so
更好的方法可能是将winter_fresh.so
重命名为libwinter_fresh.so
,然后将其链接为:
gcc ... -L /home/projects/my_files -lwinter_fresh
答案 1 :(得分:0)
我的猜测是,你使用winter_fresh.so作为源文件编译你的程序,而不是通过链接来编译你的程序
如果您将共享库/可执行文件的路径编码为/home/projects/my_files/winter_fresh.so
,则可以将共享库放在RPATH目录中,如下所示:
$ mkdir some_dir
$ mkdir -p some_dir/home/projects/my_files
$ cp /home/projects/my_files/winter_fresh.so some_dir/home/projects/my_files
$ RPATH=$(pwd)/some_dir ./executable
链接器在RPATH下搜索名为/home/projects/my_files/winter_fresh.so
的库。
现在进行简单的测试:
// main.c
int main() {
int external_function(void);
return external_function();
}
// exlib.c
#include <stdio.h>
int external_function(void) {
return printf("%s\n", __func__);
}
现在,让我们创建使用bad.out
共享库编译的exlib.so
作为源代码:
$ gcc -shared -fPIC -o exlib.so exlib.c
$ gcc /tmp/exlib.so main.c -o bad.out
$ ldd bad.out
linux-vdso.so.1 (0x00007ffd921db000)
/tmp/exlib.so (0x00007fe4470f7000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007fe446d3b000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fe4474fb000)
如您所见,字符串/tmp/exlib.so
指向共享库。我可以运行程序,使用RPATH将链接器指向exlib.so位置。我需要在RPATH中创建子树/tmp/exlib.so
,如下所示:
$ mkdir -p lib/tmp
$ mv exlib.so lib/tmp
$ RPATH=$(pwd)/lib ./bad.out
external_function
运行bad.out时,链接器会在/tmp/exlib.so
内搜索名为RPATH
的文件
Linux使用约定来命名shared libraries。现在让我们链接good.out:
$ gcc -shared -fPIC -o libexlib.so exlib.c
$ gcc -I /tmp -lexlib main.c -o good.out
$ ldd good.out
linux-vdso.so.1 (0x00007ffcb01bf000)
libexlib.so => not found
libc.so.6 => /usr/lib/libc.so.6 (0x00007fc1230ef000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fc1236ad000)
现在您看到good.out
与libexlib.so
相关联。 gcc在链接时在/ tmp目录中搜索名为 lib exlib .so 的图书馆。我可以通过将LD_LIBRARY_PATH指定给libexlib.so驻留的路径来运行good.out:
$ LD_LIBRARY_PATH=/tmp ldd ./good.out
external_function