bash Linux 可执行文件在同一文件夹中找不到共享库
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39978762/
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
Linux executable can't find shared library in same folder
提问by Matrefeytontias
I am relatively new to Linux development, having been using Windows for a while now. Anyway, I am compiling a C++ game using g++ on both Windows and Linux (using mingw32 when needed), and am linking against SDL2 and SDL2_mixer. On Windows, one would only need to put the DLL files in the same folder as the executable and everything would run fine. On Linux however, although the code compiled just fine with not even a single warning, I get this at runtime :
我对 Linux 开发比较陌生,已经使用 Windows 一段时间了。无论如何,我正在 Windows 和 Linux 上使用 g++ 编译 C++ 游戏(需要时使用 mingw32),并且正在链接 SDL2 和 SDL2_mixer。在 Windows 上,只需将 DLL 文件与可执行文件放在同一文件夹中,一切都会正常运行。然而,在 Linux 上,虽然代码编译得很好,甚至没有一个警告,但我在运行时得到了这个:
./nKaruga: error while loading shared libraries: libSDL2_mixer-2.0.so.0: cannot open shared object file: No such file or directory
although said shared lib is in the same folder. I looked up several similar cases on Stack Overflow, all of them involving the use of LD_LIBRARY_PATH
, and tried it but to no avail.
虽然说共享库在同一个文件夹中。我在 Stack Overflow 上查找了几个类似的案例,都涉及到使用LD_LIBRARY_PATH
,并尝试了但无济于事。
% LD_LIBRARY_PATH=pwd
% export LD_LIBRARY_PATH
% ./nKaruga
./nKaruga: error while loading shared libraries: libSDL2_mixer-2.0.so.0: cannot open shared object file: No such file or directory
I want to distribute this program on systems that do not necessarily have admin rights to install dependencies, hence why I am putting the SO in the same folder as the executable.
我想在不一定具有安装依赖项的管理员权限的系统上分发此程序,因此我将 SO 与可执行文件放在同一文件夹中。
Thanks by advance !
提前致谢!
回答by datenwolf
LD_LIBRARY_PATH is a quick ad-hoc hack to specify alternate library loading search paths. A more permanent and cleaner solution is to specify the specific sets of paths in which libraries shall be searched specificfor your particular binary. This is called the rpath(Wikipedia article on it: https://en.wikipedia.org/wiki/Rpath). There are a number of "variables" that can be specified in the binary rpaththat get substituted. In your case the rpath variable ${ORIGIN}
would be the most interesting for you. ${ORIGIN}
tells the dynamic linker to look for libraries within the very same directory in which also the binary resides.
LD_LIBRARY_PATH 是一个快速的临时 hack,用于指定备用库加载搜索路径。一个更持久和更清晰的解决方案是指定特定的路径集,在这些路径中应针对您的特定二进制文件搜索特定的库。这称为rpath(关于它的维基百科文章:https: //en.wikipedia.org/wiki/Rpath)。有许多“变量”可以在被替换的二进制rpath中指定。在您的情况下, rpath 变量${ORIGIN}
对您来说是最有趣的。${ORIGIN}
告诉动态链接器在二进制文件所在的同一目录中查找库。
The rpath can be set at link time with the -rpath
linker option, i.e. when invoked through GCC the option would be -Wl,-rpath='${ORIGIN}'
, i.e.
rpath 可以在链接时使用-rpath
链接器选项设置,即当通过 GCC 调用时,该选项将是-Wl,-rpath='${ORIGIN}'
,即
gcc -o program_binary -Wl,-rpath='${ORIGIN}' -lSDL2_mixer a.o b.o …
For an existing binary the rpath can be set post-hoc using the chrpath
or patchelf
tools; it's better to set it at link time proper, though.
对于现有的二进制文件,可以使用chrpath
或patchelf
工具事后设置 rpath ;不过,最好在适当的链接时间设置它。
回答by Matrefeytontias
Actually nevermind it doesn't work, I had just assumed, that's my bad.
其实没关系,它不起作用,我只是假设,那是我的错。
Using the -Wl,-rpath='${ORIGIN}'
options literally does not change a thing.
-Wl,-rpath='${ORIGIN}'
从字面上使用选项不会改变任何事情。
% g++... -Wl,-rpath='${ORIGIN}' -o./bin/nKaruga ...
% cd bin
% ls
libSDL2_mixer-2.0.so.0 nKaruga
% ./nKaruga
./nKaruga: error while loading shared libraries: libSDL2_mixer-2.0.so.0: cannot open shared object file: No such file or directory
Using $ORIGIN
instead of ${ORIGIN}
gives the same result, as well as using -Wl,-rpath,'${ORIGIN}'
and -Wl,-rpath,'$ORIGIN'
.
使用$ORIGIN
而不是${ORIGIN}
给出相同的结果,以及使用-Wl,-rpath,'${ORIGIN}'
和-Wl,-rpath,'$ORIGIN'
。
EDIT (don't mind the French) :
编辑(不要介意法语):
% readelf -d ./nKaruga | grep 'RPATH'
0x000000000000000f (RPATH) Bibliothèque rpath: [$ORIGIN]
for what it's worth.
物有所值。