How to deal with conflicting names of two shared libraries?

On my Linux Mint 17.3 system, I installed the packages libglfw2 and libglfw-dev. Since GLFW v3 is not available in repositories, I chose to compile it manually using instructions here.

Almost all the instructions I found online state that to link to GLFW v2, I should use -lglfw while for GLFW v3, it should be -lglfw3. However, doing -lglfw3 gave the error:

/usr/bin/ld: cannot find -lglfw3

while using -lglfw gave lots of errors like:

1.cpp:(.text+0x49): undefined reference to <function_name>

Just to be sure, all the paths in C_INCLUDE_PATH and LD_LIBRARY_PATH were correct. However, after uninstalling the GLFW v2 packaged I had installed using apt-get and running ldconfig, -lglfw worked without a problem. Seems that, somewhere in the CMake file (I guess), there is a bug resulting in name conflict.

My question is: If I have two sources that provide the shared libraries with same name, and if I need them both, what can I do (short of diving in the build config) to workaround the issue? Can I manually change the names of so files reliably?

Answer

Shared libraries are called e.g. libfoo.so-x.y.z, with the idea being that z gets incremented for minor (totally backwards compatible) changes, y is incremented for API additions that keep backward compatibility, while changes to x are reserved for major API changes (not compatible). The executable program (check e.g ldd(1)‘s output for an executable) tells you what library the program requests, by major number (libfoo.so.x) and which libary is used to fullfill that dependency (libfo.so.x.y.z). The “links against libfoo.so.x” is fixed at build time, the exact y.z at startup. Thus you can change y and/or z and have programs still working, and have e.g. libfoo.so.3 and libfoo.so.4 installed at the same time, with some programs using one or the others without conflicts.

If you look at the directories for libraries, you will see a chain of symbolic links like libfoo.so -> libfoo.so.x -> libfoo.so.x.y.z; when linking with -lfoo the linker will follow this and add libfoo.so.x as dependency to the executable, and use libfoo.so.x.y.z to resolve symbols.

This machinery is tailored to always get the latest libfoo when compiling, while having older versions around for legacy applications. Thus often you will see e.g. libbar.so and libbar3.so (and their farm of symlinks) to be able to build against version 2 (-lbar, if the unnumbered legacy version is 2) or 3 (-lbar3).

The build machinery should be able to sort this out, but it is rather tricky (and not everybody is thrilled by the idea that their latest and shiniest version 3 will stand beside hoary version 2).

Your best bet is to rely on your distribution to set up this mess for you.

Attribution
Source : Link , Question Author : strNOcat , Answer Author : vonbrand

Leave a Comment