Gcc 链接共享库绝对路径与相对路径
我一直在尝试将一个共享库链接到我的程序中,我希望它的路径与我的RPATH相对 然而,当我运行ldd时,我注意到共享库的绝对路径是链接的。你知道为什么吗 编辑:Gcc 链接共享库绝对路径与相对路径,gcc,cmake,linker,shared-libraries,Gcc,Cmake,Linker,Shared Libraries,我一直在尝试将一个共享库链接到我的程序中,我希望它的路径与我的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/libpth
/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 我的猜测是,您使用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
$ mkdir -p lib/tmp
$ mv exlib.so lib/tmp
$ RPATH=$(pwd)/lib ./bad.out
external_function
链接器在RPATH下搜索名为/home/projects/my\u files/winter\u 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__);
}
正如您看到的字符串/tmp/exlib.so
指向共享库。我可以运行该程序,使用RPATH将链接器指向exlib.so位置。我需要在RPATH中创建子树/tmp/exlib.so
,如下所示:
$ 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
$ mkdir -p lib/tmp
$ mv exlib.so lib/tmp
$ RPATH=$(pwd)/lib ./bad.out
external_function
运行bad.out时,链接器在RPATH
中搜索名为/tmp/exlib.so
的文件
Linux使用命名约定。现在让我们链接到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目录中搜索名为libexlib.so的alibrary。通过指定LD_LIBRARY_路径到libexlib.so路径,我可以运行good.out:
$ LD_LIBRARY_PATH=/tmp ldd ./good.out
external_function
问题是第一个文件。我不希望冬季图书馆成为一条绝对的道路
这通常发生在您链接库时,如下所示:
gcc ... /home/projects/my_files/winter_fresh.so ...
而且您的库没有SONAME
(您在构建它时没有使用-SONAME
链接器选项)
要解决此问题,请将SONAME
添加到winter\u fresh.so
(通常这是一个很好的做法),或者将其链接如下:
gcc ... -L /home/projects/my_files -l:winter_fresh.so
gcc ... -L /home/projects/my_files -lwinter_fresh
更好的方法可能是将winter\u fresh.so
重命名为libwinter\u fresh.so
,然后像这样链接:
gcc ... -L /home/projects/my_files -l:winter_fresh.so
gcc ... -L /home/projects/my_files -lwinter_fresh
你能发布ldd输出吗?首先在rpath中搜索库。ldd调用链接器以获取程序依赖项,它将始终打印到库的绝对路径。@KamilCuk已完成。是否使用CMake构建项目?否则,为什么要使用cmake
标记?我发现问题在于创建共享库时缺少“-soname”。