Linux 可执行文件在同一文件夹中找不到共享库

Linux executable can't find shared library in same folder

本文关键字:找不到 共享 文件夹 可执行文件 Linux      更新时间:2023-10-16

我对Linux开发比较陌生,使用Windows已经有一段时间了。无论如何,我正在使用g++在Windows和Linux上编译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

,尽管所述共享库位于同一文件夹中。我在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

我想把这个程序发布到那些不一定有管理员权限来安装依赖项的系统上,因此我把SO文件和可执行文件放在同一个文件夹里。

LD_LIBRARY_PATH是一个快速的临时hack,用于指定备用库加载搜索路径。一个更持久、更简洁的解决方案是指定搜索库的特定路径集specific为您的特定二进制文件。这被称为rpath(关于它的维基百科文章:https://en.wikipedia.org/wiki/Rpath)。可以在二进制rpath中指定许多被替换的"变量"。在您的情况下,路径变量${ORIGIN}将是您最感兴趣的。${ORIGIN}告诉动态链接器查找与二进制文件所在目录相同的库。

rpath可以在链接时使用-rpath链接器选项设置,即当通过GCC调用时,该选项将是-Wl,-rpath='${ORIGIN}',即

gcc -o program_binary -Wl,-rpath='${ORIGIN}' -lSDL2_mixer a.o b.o …

对于已存在的二进制文件,可以使用chrpathpatchelf工具设置rpath;不过,最好在链接时适当设置它。