Linux accommodates multiple versions of a shared library but what about includes? - linux

I'm trying to understand how shared library versions are managed under Linux and how these interact with different versions of include files when configuring and compiling a program.
I understand that a system can have multiple versions of shared libraries (.so files) differing by the first version number following libxxx.so in the filename, and that different programs may have been linked with different versions of the same library. A new version of a library (.so.# has changed) is generally incompatible with the previous version. (Version numbers after the first are minor library changes not affecting its compatibility).
If I am compiling (or recompiling) an older program which has been linked with an older version of a library, and if I have both the older and newer libraries on my system, there seems to be no mechanism for managing multiple versions of the include files that are associated with each library version. Thus, even though I have the older version of the library available, without the older version of the include files to link to, I really can't recompile that program. Is that true?
If so, support of multiple library versions seems to be of questionable value. The idea must be that the only users of old versions of libraries are programs that were compiled when the old version was current, and that no program should ever be recompiled unless all the versions of all the libraries it links with are the most recent versions of those libraries installed on the system. As soon as a new version of a library is installed, all programs using the older version can no longer be compiled (unless they are updated to newer version using the newer library). Right?
Or, do people commonly go to the trouble of keeping a separate subdirectory of include files for each version of each library that is installed, so programs can be recompiled using the appropriate include file and library versions?

Include-files are handled differently from shared libraries:
With shared libraries, there will be one name for development packages to use when linking, which is a symbolic link to a file which has a specific soname (name plus version). After linking, a program has a reference to that file which is used whenever running the program.
Include-files can be distinguished by the -I option for include-paths. When there are multiple useful versions of a library, some developers may package the versions using different directory names for holding the related header files. That way, changing just the -I option when compiling makes the build scripts able to work with a specific version of the headers. But unlike shared libraries, the header files are used only when building the program which uses a library.

Related

How to dynamically check for library information in posix compliant systems in C++?

I am playing around with Linux to learn some things about operating systems. Currently I want to query the OS for the version of certain libraries (GLFW and GLEW on particular). I want to print the current version or a message if the library is not installed.
Is there a general way to query the OS for the version of an installed library?
It is library-specific. Each library will have its own method (or might have none) to query what version is loaded.
This is different to querying the system to ask what version of a library is installed--that's the wrong way to go about it because the version loaded in your program might be different to what the system has installed (and the system might have multiple runtime versions installed).
In your specific case, you need to call glfwGetVersion() for GLFW, and use GLEW_VERSION for GLEW.

How to link against system libraries and not Matlab's provided libraries

We have Matlab R2017a installed on a RHEL 7.3 machine and I can provide verbose installation instructions if necessary. We have the Matlab library paths saved in /etc/ld.so.conf.d/matlab.conf and have run ldconfig to make sure the paths get picked up. Matlab works and everything is functional. However, Matlab seems to come bundled with it's own versions of libraries such as libstdc++, libicui18n, and others.
I'm trying to build and link a non-Matlab executable with the two libraries mentioned above and it's linking against Matlab's and not the system. How can I tell the linker to use the system provided libraries? I'm pretty sure this isn't a Matlab-specific problem, but that happens to be the environment I'm working in. Any thoughts would be greatly appreciated.
Here is what our /etc/ld.so.conf.d/matlab.conf file looks like. Based on some testing, it does look like all three of these are necessary.
/opt/MATLAB/R2017a/bin/glnxa64
/opt/MATLAB/R2017a/runtime/glnxa64
/opt/MATLAB/2017a/sys/os/glnxa64
There are libraries installed in the runtime that depend on libraries installed in sys/os. The libraries in sys/os are the ones conflicting with the RHEL system libraries (such as libstdc++).

How to store same library version compiled differently in Linux?

I have two different Qt projects, one of which needs to be compiled with Qt 4.8 and the other being compiled with Qt 5.4. Both need to use the library QDeviceWatcher compiled in accordance to their versions (i.e. the app under Qt 5 should have QDeviceWatcher compiled for Qt 5 and the one using Qt 4.8 needs QDeviceWatcher compiled with Qt 4.8).
The problem is that, under Linux, the .so library files are supposed to be located in the same "global" folder, /usr/local/lib. Since I'm working on both projects, I'ld have to have both groups of .so files located in that folder - what simply is not possible given that they have the same name and the last addition would simply overwrite the previous one.
As for now what I'm doing is each time I change the project to be compiled, I update the library files with the compilation I need, but that is obviously undesirable.
Is there any way to counter this problem?
The only two ways I came across was to create a fake new version of the library (currently is 2.0.0, so I could create version 2.0.1) and compile each lib version for one different Qt version (but of course that would be messy, I mean, it's a fake version!) or to locate the .so files in a directory close to the project so the files would be looked after there instead of in the global dir /usr/local/lib. But that, seems to me, breaks down the whole idea of having the library available globally for all and new applications. And Google didn't help me with this.
Given that QDeviceWatcher is a 3rd party app what I would do is install it outside of the /usr/local/lib folder and into the project directory instead, and update my .pro to point to it directly.

Export libraries which are used in compile & running MSVC++ 2010

I am developing a C++ program which is using 6 different libraries (like Boost, OpenCV, Protobuf etc). I've compiled and installed all required libraries on my development PC. I want to export the program to work in another computer standalone. I can copy all the shared libraries to a folder and put the executable next to it but it will be really useful as my program's size would be enormous. Is it possible that MSVC++ exports all the shared libraries (and maybe the include files too) which are used in compilation?
Edit: Let me make clear the question.
I've libraries & header files all around in my PC (Like C:\boost\lib, D:\Workspace\opencv\lib etc..)
I don't use most of the libraries in these folders in my application.
I want to run my application at another computer.
I don't want to install all the libraries to the new computer.
I want only that MSVC export the required(used) shared libraries to another folder that I specify so I can copy only 1 folder containing only required libraries in it.
Is it possible?

How to get rid of 'GLIBCXX_3.4.9 not found error'?

I am building a redistrbutable .so file.
However when my users try to use it they get the dreaded /usr/lib/libstdc++.so.6: version GLIBCXX_3.4.9' not found error.
Doing an objdump, it seems its this particular symbol in my binary that is causing the issue:
_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l##GLIBCXX_3.4.9
How do i tell my gcc/g++ to compile/link against an older version of GLIBXX so that my users dont get this error?
Or is the only way out of this conundrum to install a separate older version of linux which has an GLIBXX?
How do i tell my gcc/g++ to compile/link against an older version of GLIBXX so that my users dont get this error?
There is no way to do that. Your only choices are:
build with older g++ version, or
link libstdc++.a statically into your shared library, and hide its symbols (this may also have licensing implications, check with your lawyer).
package your version of libstdc++.so.6 together with your library, and ask users who have an older version to arrange to pick up your newer version instead (also has licensing implications, but I believe these are easier to satisfy).
You are building for GLIBCXX_3.4.9, hence your users also need to have at least GLIBCXX_3.4.9.

Resources