我正在尝试用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!
,好像根本没有任何问题。
为什么会发生这种情况?
答案 0 :(得分:2)
出于某种原因,它坚持寻找libglfw.so.3。 ...将库从libglfw.3.2.so重命名为libglfw.so.3 ...
ELF可执行文件包含所用动态库的完全名称。
如果可执行文件包含库名称&#34; libglfw.so.3
&#34;该文件的名称必须与此完全相同。
文件命名方案是以不是&#34; full&#34;的方式进行的。版本被编码到文件名中:这样,更高版本(&#34; libglfw.so.3.15
&#34;)将与可执行文件一起使用。
通常应该有一个指向已安装库的最新版本的符号链接:
libglfw.so.3
- &gt; libglfw.so.3.2
您的计算机上似乎缺少此符号链接。我会说这是一个安装问题!
修改强>
问题可能是:为什么文件名存储在可执行文件中不是libglfw.3.2.so
而是libglfw.so.3
?
答案与安装新版本库时的向后兼容性有关:
通常您会使用开关-lglfw
并查找名为libglfw.so
的符号链接。
如果您将文件名libglfw.so
存储在可执行文件中,并且如果安装了此库(libglfw.so.4
),则会出现一个新的不兼容版本,您将无法通过同时使用这两个版本来运行该程序已安装的库。
通过安装两个版本的库来实现向后兼容性&#34; real&#34;库的符号链接名称(libglfw.so.3
)必须存储在可执行文件中。
因此&#34;预期&#34;库的文件名存储在库本身中:在文件libglfw.so.3.2
内,您将找到文件希望将其存储为libglfw.so.3
的一些信息。
链接器将使用有关文件名的信息,因为它假定链接器开关(-lglfw
)中给出的库名称较少&#34;精确&#34;而不是存储在库本身的名称。
答案 1 :(得分:1)
出于某种原因,它坚持寻找libglfw.so.3。它不会有任何其他方式。
这是共享库的Linux约定,在其他地方描述here。对于Linux,libfoo.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
哪个应该为您的lib输出必需的libglfw.so.3
符号链接。
IIRC设置rpath可能需要一条完整的路径。
我也尝试将LD_LIBRARY_PATH设置为指向我的库的位置
同样,libglfw.so.3
不在ld-linux.so
的路径上。