问题 在debug DAOS的过程中,gdb在执行可执行文件时,未能正确的加载libdaos的动态链接库。
什么是动态链接库 Linux中的共享库为程序提供了各种可重用函数。
假设我们想编写一个以压缩文件为输入的程序。为此,我们可以使用zlib等现有库,而不是自己实现解压缩函数。
程序在启动时加载共享库。
查看可执行文件使用了哪些动态链接库 1 2 3 4 5 6 7 8 9 10 11 $ ldd /usr/bin/clang /usr/bin/clang: linux-vdso.so.1 (0x00007ffd34a90000) libclang-cpp.so.13 => /usr/bin/../lib/libclang-cpp.so.13 (0x00007f24c5a94000) libLLVM-13.so => /usr/bin/../lib/libLLVM-13.so (0x00007f24c1548000) libstdc++.so.6 => /usr/bin/../lib/libstdc++.so.6 (0x00007f24c12d6000) libm.so.6 => /usr/bin/../lib/libm.so.6 (0x00007f24c11f8000) libgcc_s.so.1 => /usr/bin/../lib/libgcc_s.so.1 (0x00007f24c11dd000) libc.so.6 => /usr/bin/../lib/libc.so.6 (0x00007f24c0fc4000) /lib/ld-linux-x86-64.so.2 => /usr/lib/ld-linux-x86-64.so.2 (0x00007f24c95d4000) libz.so.1 => /usr/bin/../lib/../lib/libz.so.1 (0x00007f24c0fad000)
查找未能找到的库 1 2 3 4 5 $ apt search zstd Sorting... Done Full Text Search... Done zstd/stable 1.5.0 aarch64 Zstandard compression.
LD_LIBRARY_PATH 环境变量我们可以指定在LD_LIBRARY_PATH环境变量中搜索共享库的目录。
LD_LIBRARY_PATH是一个冒号分隔的目录列表,就像PATH变量一样。
默认搜索路径通常仅限于/usr/lib和/usr/local/lib。
假设我们有一个链接到libfoo.so的程序,位于/home/baeldung/libs/libfoo.so,位于默认搜索路径之外。然后,我们可以使用此变量附加到搜索路径并解决问题。
首先,让我们使用ldd命令确认程序链接到的确切库:
1 2 3 4 5 6 7 8 $ ./program ./program: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory $ ldd ./program ./program: linux-vdso.so.1 (0x00007ffce871b000) libfoo.so => not found libc.so.6 => /usr/lib/libc.so.6 (0x00007fdceadaf000) /lib/ld-linux-x86-64.so.2 => /usr/lib/ld-linux-x86-64.so.2 (0x00007fdceafd3000)
现在,让我们将目录添加到LD_LIBRARY_PATH,并使我们的程序正常工作:
1 2 3 4 5 6 7 $ export LD_LIBRARY_PATH=/home/baeldung/libs $ ldd ./program ./program: linux-vdso.so.1 (0x00007ffe28dfd000) libfoo.so => /home/baeldung/libs/libfoo.so (0x00007f8f0f7ba000) libc.so.6 => /usr/lib/libc.so.6 (0x00007f8f0f59d000) /lib/ld-linux-x86-64.so.2 => /usr/lib/ld-linux-x86-64.so.2 (0x00007f8f0f7c6000)
永久生效的配置 我们可以使用/etc/ld.so.conf文件永久设置库搜索路径。在这个文件中,我们指定了一个以换行符分隔的目录列表。
让我们再次修复libfoo.so错误:
1 2 3 4 5 6 7 8 9 10 11 $ ./program ./program: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory $ echo "/home/baeldung/libs" | sudo tee /etc/ld.so.conf /home/baeldung/libs $ sudo ldconfig $ ldd ./program ./program: linux-vdso.so.1 (0x00007ffefc3db000) libfoo.so => /home/baeldung/libs/libfoo.so (0x00007f021e88d000) libc.so.6 => /usr/lib/libc.so.6 (0x00007f021e674000) /lib/ld-linux-x86-64.so.2 => /usr/lib/ld-linux-x86-64.so.2 (0x00007f021e89e000)
我们必须运行一次ldconfig命令,以使系统意识到新路径。
ldconfig 指令 我们可能最近安装了新的共享库或修改了共享库搜索路径。因此,我们需要运行ldconfig命令。
它更新链接器的缓存,使其了解新的共享库。
链接器称为ld.so,加载程序的共享库。
我们可以使用-p标志调用ldconfig来检查当前缓存:
1 2 3 4 5 6 7 8 9 10 $ ldconfig -p 347 libs found in cache `/etc/ld.so.cache' libzstd.so.1 (libc6,x86-64) => /usr/lib/libzstd.so.1 libzstd.so (libc6,x86-64) => /usr/lib/libzstd.so libz.so.1 (libc6,x86-64) => /usr/lib/libz.so.1 libz.so (libc6,x86-64) => /usr/lib/libz.so libx265.so.199 (libc6,x86-64) => /usr/lib/libx265.so.199 libx265.so (libc6,x86-64) => /usr/lib/libx265.so libx264.so.157 (libc6,x86-64) => /usr/lib/libx264.so.157 libx264.so (libc6,x86-64) => /usr/lib/libx264.so
在编译时设置库路径 如果我们可以访问程序的源代码,我们可以在链接过程中使用特殊标志编译它,以便找到共享库。
我们可以在运行时使用ld’s-rpath标志将库路径传递给动态链接器。
让我们编译一个基本程序并将其链接到我们的库:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 $ pwd /home/baeldung/libs $ ls libfoo.so $ echo "int main() {}" > program.c $ cc program.c libfoo.so $ ./a.out ./a.out: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory $ ldd ./a.out ./a.out: linux-vdso.so.1 (0x00007ffcbc1f8000) libfoo.so => not found libc.so.6 => /usr/lib/libc.so.6 (0x00007feb0ee04000) /lib/ld-linux-x86-64.so.2 => /usr/lib/ld-linux-x86-64.so.2 (0x00007feb0f029000)
我们可以看到程序无法加载我们的共享库。
现在,让我们尝试使用-rpath标志编译它,将/home/baeldung/libs添加到库搜索路径中:
1 2 3 4 5 6 7 $ gcc program.c libfoo.so -Wl,-rpath=/home/baeldung/libs $ ldd ./a.out ./a.out: linux-vdso.so.1 (0x00007ffd0fbad000) libfoo.so => /home/baeldung/libs/libfoo.so (0x00007fba09d99000) libc.so.6 => /usr/lib/libc.so.6 (0x00007fba09b7b000) /lib/ld-linux-x86-64.so.2 => /usr/lib/ld-linux-x86-64.so.2 (0x00007fba09da5000)
在这里,我们使用gcc的-Wl标志将参数传递给ld。
libdaos未找到的解决方案 1 echo "/home/kuhan/daos/build/release/gcc/src/client/api/" | sudo tee /etc/ld.so.conf
参考 https://www.baeldung.com/linux/solve-shared-object-error