C ++ linux可执行文件一直在尝试使用不存在的库

时间:2017-06-25 04:14:52

标签: c++ linux dynamic-linking

我正在尝试用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!,好像根本没有任何问题。

为什么会发生这种情况?

2 个答案:

答案 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的路径上。