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

时间:2009-03-29 22:40:16

标签: 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

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

export LD_LIBRARY_PATH="/path/to/library/"
./sync_test

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

LD_LIBRARY_PATH="/path/to/library/"

7 个答案:

答案 0 :(得分: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

编辑:

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

#!/bin/bash

LD_LIBRARY_PATH=/path/to/library sync_test "$@"

如果sync_test启动任何其他程序,他们最终可能会使用/path/to/library中的libs,这可能是也可能不是。

答案 1 :(得分:42)

使用

export LD_LIBRARY_PATH="/path/to/library/"

在你的.bashrc中,否则它只能用于bash而不是你开始的任何程序。

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

编辑:看起来-R仅适用于Solaris,而且您使用的是Linux。

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

答案 2 :(得分:10)

你在.bashrc中导出了吗?

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"/path/to/library"

答案 3 :(得分:10)

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

LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/path/to/library" ./sync_test

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

答案 4 :(得分:4)

不是使用LD_LIBRARY_PATH在运行时覆盖库搜索路径,而是使用rpath将其烘焙到二进制文件本身。如果您与GCC相关联,则添加-Wl,-rpath,<libdir>应该可以解决问题,如果您与ld链接,则只需-rpath <libdir>

答案 5 :(得分:2)

如果您在系统上安装了某些内容,那么您还可以执行的操作是将包含共享库的目录添加到 /etc/ld.so.conf 文件中,或者创建一个 /etc/ld.so.conf.d /

中的新文件

(我已经检查过RHEL5和Ubuntu发行版,所以我认为它是linux的通用版)

ldconfig程序将确保它们包含在系统范围内。

有关详细信息,请参阅以下链接: www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/dlls.html

答案 6 :(得分:1)

您可以在代码中添加一个带有新定义的呼叫系统:

sprintf(newdef,"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%s:%s",ld1,ld2);
system(newdef);

但是,我不知道这是一个严格的解决方案,但它确实有效。

此致