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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/695530/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:10:27  来源:igfitidea点击:

Why do I have to define LD_LIBRARY_PATH with an export every time I run my application?

clinuxgccshared-librariesld

提问by Paul Wicks

I have some code that uses some shared libraries (c code on gcc). When compiling I have to explicitly define the include and library directories using -I and -L, since they aren't in the standard places. When I try to run the code, I get the following error:

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

./sync_test 
./sync_test: error while loading shared libraries: libsync.so: cannot open shared object file: No such file or directory

However, do the following, everything works just fine:

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

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

Now, the strange part is, this only works once. If I try and run sync_test again I get the same error unless I run the export command first. I tried adding the following to my .bashrc, but it made no difference:

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

LD_LIBRARY_PATH="/path/to/library/"

采纳答案by brian-brazil

Use

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

in your .bashrc otherwise, it'll only be available to bash and not any programs you start.

否则,在您的 .bashrc 中,它只能用于 bash 而不能用于您启动的任何程序。

Try -R/path/to/library/flag when you're linking, it'll make the program look in that directory and you won't need to set any environment variables.

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

EDIT: Looks like -Ris Solaris only, and you're on Linux.

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

An alternate way would be to add the path to /etc/ld.so.confand run ldconfig. Note that this is a global change that will apply to all dynamically linked binaries.

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

回答by bedwyr

Did you 'export' in your .bashrc?

您在 .bashrc 中“导出”了吗?

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

回答by brian-brazil

You can just put this all on one line:

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

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

Should make things a little easier, even if it doesn't change anything fundamental

应该让事情变得更容易一些,即使它不会改变任何基本的东西

回答by sigjuice

You should avoid setting LD_LIBRARY_PATHin your .bashrc. See "Why LD_LIBRARY_PATH is bad"for more information.

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

Use the linker option -rpathwhile linking so that the dynamic linker knows where to find libsync.soduring runtime.

链接时使用链接器选项-rpath以便动态链接器知道libsync.so在运行时在哪里找到。

gcc ... -Wl,-rpath /path/to/library -L/path/to/library -lsync -o sync_test

EDIT:

编辑:

Another way would be to use a wrapper like this

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

#!/bin/bash

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

If sync_teststarts any other programs, they might end up using the libs in /path/to/librarywhich may or may not be intended.

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

回答by Roalt

What you also can do, if it's something you installed on your system, is to add the directory that contains the shared libraries to your /etc/ld.so.conffile, or make a new file in /etc/ld.so.conf.d/

您还可以做的是,如果它是您在系统上安装的东西,则是将包含共享库的目录添加到您的/etc/ld.so.conf文件中,或者在/etc/ld.so 中创建一个新文件。配置文件/

(I've both checked RHEL5 and Ubuntu distribution so I think it's generic for linux)

(我已经检查了 RHEL5 和 Ubuntu 发行版,所以我认为它适用于 linux)

The ldconfig program will make sure they are system-wide included.

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

See the following link for more information: www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/dlls.html

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

回答by fgp

Instead of overriding the library search path at runtime with LD_LIBRARY_PATH, you could instead bake it into the binary itself with rpath. If you link with GCC adding -Wl,-rpath,<libdir>should do the trick, if you link with ld it's just -rpath <libdir>.

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

回答by user3916212

You could add in your code a call system with the new definition:

您可以在代码中添加具有新定义的调用系统:

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

But, I don't know it that is the rigth solution but it works.

但是,我不知道这是正确的解决方案,但它有效。

Regards

问候