C++ Linux 可执行文件一直尝试使用不存在的库
C++ linux executable keeps trying to use library that does not exist
我正在尝试在Linux上使用GLFW编写一个简单的应用程序。现在主文件(唯一的文件)基本上只有几行代码,以确保动态库正确链接。在这里:
#include <GLFW/glfw3.h>
#include <iostream>
int main()
{
glfwInit();
std::cout << "It works this far!" << std::endl;
glfwTerminate();
}
包含文件存储在标记为"include"的目录中,库文件存储在标记为"lib"的目录中。截至目前,我正在使用以下行编译程序:
g++ -Wl,-Rlib -Iinclude -Llib test.cpp -o test -lglfw.3.2
它可以很好地编译和链接,但是当我尝试执行它时,我收到以下错误:
./test: error while loading shared libraries: libglfw.so.3: cannot open shared object file: No such file or directory
现在,在你急于否决这个问题并将其标记为重复之前,至少请允许我解释为什么我认为我的问题足够不同,不会重复。我已经尝试了其他问题提出的解决方案,但没有成功。如您所见,我尝试在与-Wl,-Rlib
标签链接期间设置库的路径。我还尝试将LD_LIBRARY_PATH设置为指向我的库的位置("lib"文件夹),但它仍然抛出了相同的错误。(路径是相对的还是绝对的并不重要。
因此,我尝试的下一件事是在可执行文件上运行ldd
命令。我得到了一些其他的依赖项,它们工作得很好,但重要的是,我得到了这个:
libglfw.so.3 => not found
出于某种原因,它坚持寻找libglfw.so.3
.它不会有任何其他方式。将库从libglfw.3.2.so
重命名为libglfw.so.3
后,程序执行得很好,打印It works this far!
好像根本没有问题。
为什么会这样?
出于某种原因,它坚持寻找libglfw.so.3。将库从 libglfw.3.2.so 重命名为 libglfw.so.3 后......
ELF 可执行文件包含所用动态库的确切名称。
如果可执行文件包含库名称"libglfw.so.3
",则文件的名称必须完全按照这个方式命名。
文件命名方案有意以未将"完整"版本编码到文件名中的方式完成:这样,更高版本("libglfw.so.3.15
")将与可执行文件一起使用。
通常应该有一个符号链接到已安装的最新版本的库:
libglfw.so.3
->libglfw.so.3.2
您的计算机上似乎缺少此符号链接。我会说这是一个安装问题!
编辑
问题可能是:为什么存储在可执行文件中的文件名不是libglfw.3.2.so
而是libglfw.so.3
?
答案与安装新版本库时的向后兼容性有关:
通常,您将使用开关-lglfw
并查找名为libglfw.so
的符号链接。
如果您将文件名libglfw.so
存储在可执行文件中,并且安装了新的不兼容版本(libglfw.so.4
),则没有机会通过安装两个版本的库来运行程序。
要通过安装两个版本的库来实现向后兼容性,库的"真实"符号链接名称(libglfw.so.3
)必须存储在可执行文件中。
因此,库的"预期"文件名存储在库本身中:在文件libglfw.so.3.2
中,您会发现文件希望自己存储为libglfw.so.3
的一些信息。
链接器将使用有关文件名的此信息,因为它假定链接器开关(-lglfw
)中给出的库名称不如存储在库本身中的名称"精确"。
出于某种原因,它坚持寻找libglfw.so.3。它不会有任何其他方式。
这是共享库的 Linux 约定,此处在其他地方进行了描述。 对于 Linuxlibfoo.so.x.y.z
被认为具有与libfoo.so.x
相同的 ABI。 通常,当安装共享库时(例如通过rpm,dpkg等),会发生ldconfig
调用,以便刚刚安装的库具有遵循引用库的约定的符号链接。 此外,出于性能原因,这些库(如果安装到"受信任位置")将添加到链接器缓存中。
它可以很好地编译和链接,但是当我尝试执行它时,我收到以下错误:
./test:加载共享库时出错:libglfw.so.3:无法打开共享对象文件:没有这样的文件或目录
libglfw.so.3
不在ld-linux.so
的道路上。
如您所见,我尝试在与 -wl,-Rlib 链接期间设置库的路径
还是找不到——libglfw.so.3
不在ld-linux.so
的道路上。 您可以通过执行以下操作来添加它:
ldconfig -n /path/to/lib
这应该为您的库输出必要的libglfw.so.3
符号链接。 IIRC 设置 rpath 可能需要完整路径。
我还尝试将LD_LIBRARY_PATH设置为指向我的库的位置
同样,libglfw.so.3
不在ld-linux.so
的道路上。
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- g++ 说函数不存在,即使包含正确的标头
- 这些是什么样的错误?即使我不在 Linux 上工作,我也遇到了 Linux 错误
- 找不到Linux Visual Studio代码C++文件
- 显式 std::exception_ptr 转换为 bool 不存在.VS2010 错误?
- C++ 尝试在不存在的构造函数中引用已删除的函数(使用 rapidJson)
- 查找第一个数组中不存在的元素
- 查找不存在的键时,unordered_map返回什么
- 如何优化代码以返回最接近给定整数的数字,但给定列表中不存在?
- set::find 查找不存在的元素
- 有没有办法将字符串添加到 Vector 中,但前提是它尚不存在?->C++
- inet_ntop返回不存在的地址
- CPP 使用不存在的键访问映射
- 为什么QMediaGaplessPlaybackControl不存在?
- 如果键不存在,使用 [] 运算符访问 STL Map 元素会添加新元素
- 标记未定义的颜色,并且颜色匹配系统中不存在样品
- 为什么minhook库目录不存在
- 为什么 std::vector::p ush_front() 不存在?
- C++ Linux 可执行文件一直尝试使用不存在的库