为什么每次运行应用程序时都必须使用导出定义LD_LIBRARY_PATH?

Pau*_*cks 41 c linux gcc shared-libraries ld

我有一些使用一些共享库的代码(gcc上的c代码).编译时我必须使用-I和-L显式定义include和library目录,因为它们不在标准位置.当我尝试运行代码时,出现以下错误:

./sync_test 
./sync_test: error while loading shared libraries: libsync.so: cannot open shared object file: No such file or directory
Run Code Online (Sandbox Code Playgroud)

但是,执行以下操作,一切正常:

export LD_LIBRARY_PATH="/path/to/library/"
./sync_test
Run Code Online (Sandbox Code Playgroud)

现在,奇怪的是,这只能工作一次.如果我再次尝试运行sync_test,除非我先运行export命令,否则会得到相同的错误.我尝试将以下内容添加到我的.bashrc中,但它没有区别:

LD_LIBRARY_PATH="/path/to/library/"
Run Code Online (Sandbox Code Playgroud)

sig*_*ice 44

你应该避免设置LD_LIBRARY_PATH你的.bashrc.有关详细信息,请参阅" Why LD_LIBRARY_PATH is bad".

链接时使用链接器选项-rpath,以便动态链接器知道libsync.so在运行时期间找到的位置.

gcc ... -Wl,-rpath /path/to/library -L/path/to/library -lsync -o sync_test
Run Code Online (Sandbox Code Playgroud)

编辑:

另一种方法是使用这样的包装器

#!/bin/bash

LD_LIBRARY_PATH=/path/to/library sync_test "$@"
Run Code Online (Sandbox Code Playgroud)

如果sync_test启动任何其他程序,他们可能最终使用/path/to/library可能会或可能不会打算使用的库.

  • 如果您将应用程序移动到其他人的计算机并且他们不希望将库放在链接时所期望的/ path /中,那么这实际上没有用.虽然-rpath肯定对系统管理员和发行版提供商有用,但我相信个人设置它是很冒昧的. (5认同)

bri*_*zil 42

使用

export LD_LIBRARY_PATH="/path/to/library/"
Run Code Online (Sandbox Code Playgroud)

在你的.bashrc中,它只能用于bash而不是你启动的任何程序.

-R/path/to/library/在链接时尝试标记,它将使程序看起来在该目录中,您不需要设置任何环境变量.

编辑:看起来-R只有Solaris,你在Linux上.

另一种方法是添加路径/etc/ld.so.conf并运行ldconfig.请注意,这是一个全局更改,将适用于所有动态链接的二进制文件.

  • 使用`-Wl,-rpath`(如果传递给`cc`)或`-rpath`(如果传递给`ld`)比`-R`更便携. (7认同)

bed*_*wyr 10

你在.bashrc中"导出"了吗?

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/path/to/library"
Run Code Online (Sandbox Code Playgroud)


小智 10

你可以把这一切都放在一行:

LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/library" ./sync_test
Run Code Online (Sandbox Code Playgroud)

应该让事情变得更容易,即使它没有改变任何根本的东西


fgp*_*fgp 5

与其在运行时使用 LD_LIBRARY_PATH 覆盖库搜索路径,您还可以使用rpath. 如果您使用 GCC 添加链接-Wl,-rpath,<libdir>应该可以解决问题,如果您使用 ld 链接它只是-rpath <libdir>.