简体   繁体   中英

C++ linux executable keeps trying to use library that does not exist

I am trying to write a simple application with GLFW on Linux. Right now the main file (the only file) is basically just a few lines of code to make sure the dynamic library linked correctly. Here it is:

#include <GLFW/glfw3.h>
#include <iostream>

int main()
{
    glfwInit();
    std::cout << "It works this far!" << std::endl;
    glfwTerminate();
}

The include files are stored in a directory labelled "include" and the library files are stored in a directory labelled "lib". As of right now, I am compiling the program with the following line:

g++ -Wl,-Rlib -Iinclude -Llib test.cpp -o test -lglfw.3.2

It compiles and links just fine, but when I try to execute it, I get the following error:

./test: error while loading shared libraries: libglfw.so.3: cannot open shared object file: No such file or directory

Now, before you rush to downvote this question into oblivion and mark it as a duplicate, at least allow me to explain why I believe my question is different enough to not be a duplicate. I already attempted the solutions that the other questions presented, but it was unsuccessful. As you can see, I tried setting the path to the library during linking with the -Wl,-Rlib tag. I also tried setting LD_LIBRARY_PATH to point to the location of my libraries (the 'lib' folder), but it still threw the same error. (It didn't matter if the path was relative or absolute.)

So, the next thing I tried was running the ldd command on the executable. I got some other dependencies that were working just fine, but importantly, I got this:

libglfw.so.3 => not found

For some reason, it insists on looking for libglfw.so.3 . It will not have it any other way. Upon renaming the library from libglfw.3.2.so to libglfw.so.3 , the program executed just fine and printed It works this far! as if there were no problems at all.

Why would this happen?

For some reason, it insists on looking for libglfw.so.3. ... Upon renaming the library from libglfw.3.2.so to libglfw.so.3 ...

The ELF executables contain the exact name of the dynamic libraries used.

If the executable contains the library name " libglfw.so.3 " the file must be named exactly like this.

The file naming scheme is intentionally done in a way that not the "full" version is coded into the file name: This way a later version (" libglfw.so.3.15 ") will work with the executable.

Normally there should be a symbolic link to the latest version of the library installed:

libglfw.so.3 -> libglfw.so.3.2

This symbolic link seems to be missing on your computer. I would say that this is an installation problem!

EDIT

The question could be: Why is the file name stored in the executable file not libglfw.3.2.so but libglfw.so.3 ?

The answer has to do with the backward compatibility when a new version of a library is installed:

Normally you would use the switch -lglfw and a symbolic link named libglfw.so is looked up.

If you stored the file name libglfw.so in the executable file and a new, incompatible version if this library ( libglfw.so.4 ) is installed you would have no chance to get the program running by having both versions of the library installed.

To enable backward compatibility by having both versions of the library installed the "real" symbolic link name of the library ( libglfw.so.3 ) must be stored in the executable file.

Therefore the "expected" file name of a library is stored in the library itself: Inside the file libglfw.so.3.2 you'll find some information that the file expects itself to be stored as libglfw.so.3 .

The linker will use this information about the file name because it assumes that the library name given in the linker switch ( -lglfw ) is less "precise" than the name stored in the library itself.

For some reason, it insists on looking for libglfw.so.3. It will not have it any other way.

This is the Linux convention for shared libraries which is described here among other places. For Linux libfoo.so.xyz is considered to have the same ABI as libfoo.so.x . Usually when shared libraries are installed (eg via rpm, dpkg, etc.) there's an invocation of ldconfig that happens so that the just installed libraries have a symlink following the convention installed that references the library. Also these libs (if installed to a "trusted location"), are added to a linker cache for performance reasons.

It compiles and links just fine, but when I try to execute it, I get the following error:

./test: error while loading shared libraries: libglfw.so.3: cannot open shared object file: No such file or directory

libglfw.so.3 isn't on ld-linux.so 's path.

As you can see, I tried setting the path to the library during linking with the -Wl,-Rlib

Still won't find it -- libglfw.so.3 isn't on ld-linux.so 's path. You can add it by doing something like:

ldconfig -n /path/to/lib

Which should output the requisite libglfw.so.3 symlink for your lib. IIRC setting the rpath might require a full path.

I also tried setting LD_LIBRARY_PATH to point to the location of my libraries

Again, libglfw.so.3 isn't on ld-linux.so 's path.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM