如何指定二进制库的位置?(Linux)


34

对于这个问题,我将使用一个特定的示例,但实际上,它可以推广到Linux上几乎找不到其依赖库的任何二进制文件。因此,我有一个由于缺少库而无法运行的程序:

./cart5: error while loading shared libraries: libcorona-1.0.2.so: cannot open shared object file: No such file or directory

ldd阐明了这个问题:

linux-vdso.so.1 =>  (0x00007fff18b01000)
libcorona-1.0.2.so => not found
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/libstdc++.so.6 (0x00007f0975830000)
libm.so.6 => /lib/libm.so.6 (0x00007f09755af000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007f0975399000)
libc.so.6 => /lib/libc.so.6 (0x00007f0975040000)
libz.so.1 => /lib/libz.so.1 (0x00007f0974e2b000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0975b36000)

但是,已安装电晕:

oliver@human$ find / -name libcorona-1.0.2.so 2> /dev/null

/usr/local/lib64/libcorona-1.0.2.so
/home/oliver/installed/corona-1.0.2/src/.libs/libcorona-1.0.2.so

我该如何告诉二进制文件在哪里寻找“丢失的”库?

Answers:


43

一次过,将变量设置为LD_LIBRARY_PATH要搜索的冒号分隔的目录列表。这类似于PATH可执行文件,只是在通过环境指定的目录之后另外搜索标准系统目录。

LD_LIBRARY_PATH=/usr/local/lib64 ./cart5

如果您有一个程序将库保存在非标准位置并且无法独自找到它们,则可以编写包装脚本:

#!/bin/sh
if [ -n "$LD_LIBRARY_PATH" ]; then
  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
else
  LD_LIBRARY_PATH=/usr/local/lib64
fi
export LD_LIBRARY_PATH
exec /path/to/cart5 "$@"

标准系统目录的列表保存在中/etc/ld.so.conf。最近的系统允许该文件包含其他文件;如果您的文件包含include /etc/ld.so.conf.d/*.conf,则请创建一个新文件,/etc/ld.so.conf.d/mala.conf其中包含要添加的目录。更改/etc/ld.so.conf或包含文件后,请运行/sbin/ldconfig以使更改生效(这将更新缓存)。

LD_LIBRARY_PATH也适用于许多其他的Unix系统,包括FreeBSD,NetBSD的,OpenBSD系统,Solaris和Tru64的HP-UX拥有SHLIB_PATH和Mac OS X有DYLD_LIBRARY_PATH/etc/ld.so.conf对多数Unix,但位置和语法不同类似物的应用越来越广泛。)


1
太好了,非常感谢。我对/etc/ld.so.conf一无所知,将来对我来说将非常有用。
马拉

15

如果要避免LD_LIBRARY_PATH,也可以在链接期间执行此操作:

gcc -o exename -L/path/to/dynamiclib/ -lnameofLib \
    -Wl,-R/path/to/dynamiclib/ sourceCode1.c ...

-Wl,...用于将额外的命令传递给链接器,在这种情况下,使用-R告诉链接器将此路径存储为.so的“默认搜索路径”。

我在自己的网站上记录了许多类似这样的小技巧:

https://www.thanassis.space/tricks.html


但是,如果所讨论的库本身具有共享库要查找,则二进制文件中存储的rpath不会递归应用于子库查找。除了在环境中设置LD_LIBRARY_PATH之外,我没有找到其他解决方法,然后确实将其应用于递归查找...
Ethan

@Ethan:是的。但是,事实是,要对某些二进制文件“打包”共享库的通常情况是,将它们全部放在一起。例如,/opt/mypackage/bin/someBinary将需要您存储在中的库/opt/mypackage/lib/。在/ opt下安装的几乎所有专有软件几乎都遵循此规则-这意味着上面显示的方式将涵盖所有此类安装。然后,他们通常还会在/ usr / bin下添加一个指向/ opt下的二进制文件的符号链接-知道“默认搜索路径”将.so在适当的/opt/.../lib文件夹下找到s 。
ttsiodras

是的,在我的情况下,我想通过链接到其构建目录而不是安装它来测试一个软件包……(但是该软件包具有多个内部.so,它们之间存在相互依赖关系……各种解决方法都令人讨厌)
伊桑

0

这表明libcorona没有安装在正确的路径中。将libcorona目录移动到正确的路径,此问题将得到解决。


这比其他答案更好吗?
多托

@Toto与其他答案不同,您基本上是在手动安装文件...虽然这并不完全意味着此答案更好,但是应该考虑这一选项(人们也可以通过将库复制到Windows中来实现此目的)系统32 / sysWOW64(如果他们的应用找不到它们),则不建议这样做,因为强烈建议不要这样做。
Tcll
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.