I just wanted to understand how shared libraries with statically linked libraries are expected to perform. I am writing a shared library (lshared.so) that is statically linked to another library (lstatic). Now, I have another executable helloworld which loads a dynamic version of library lstatic (lstatic.so) and lshared.so as well. Will the static version of library (lstatic) loaded by lshared.so and the dynamic version (lstatic.so) conflict? Will they share any global state? Tried to show it better below.
helloworld
--> lshared.so (statically linked to lstatic at compile time)
--> lstatic.so (hello world loads this at runtime)
To throw some context, I've to use a shared library for logging. It is possible that lshared.so is statically linked to a different version that the one available to helloworld at runtime.
Will the static version of library (lstatic) loaded by lshared.so and the dynamic version (lstatic.so) conflict.
Possibly.
Will they share any global state.
Possibly.
The answers depend on how exactly lshared.so is built (which symbols it exports), and how the main helloworld binary is linked.
The answers also tend to be somewhat complicated, and may depend on inlining and other optimizations, and possibly on compiler versions.
It is best to avoid doing that by using shared version of lstatic.so, where all the answers become simple.
Related
I'm currently developing a shared library on Windows (dll) with c++.
The library depends on another external library.
What is the best way to link them together?
Link the external library as a static library into my shared lib?
Link it as a shared library and provide the dll to the application who is using my shared lib?
For the second case what happens if i create an application which uses my own created shared library and also the external library as a shared library?
If for example my shared library is build with the external library version 1.1 and the application uses the newer Version for example 1.3 ? Now the dlls should be different but how could i provide them to the main application?
Are there some best practices or recommendations on how to handle such a situation?
This really depends on what you want to do and how you are deploying your library.
shared/dynamic libraries (dll's on windows) have several advantages over static libraries
They can be distributed externally from the application, allowing your application binary to be smaller
They can be updated externally to the application
They are slightly more efficient as code is only executed if its needed rather than being bundled with the executable
Of course they have several weaknesses too
They can be distributed externally from your application and updated externally - allowing dll injection attacks
Trying to release dynamic libraries with the executable is one of the most painful and horrible things to do (especially on windows where there is no RPATH)
You may have to use a dll, dependent on your external libraries licensing, Qt for example requires shared library linking in many cases (not all).
Standard convention is usually to offer shared and static versions of your library with the shared version being completely linked to other shared libraries and the static version being an ar static library (includes all dependencies). The shared library variant then offers instructions on linking (i.e a .pc (pkgconfig) file) which specifies the versions of the other libraries to link to (i.e v1.1 of x.dll) in order to successfully compile/link.
I'm working on a library that is statically linking our boost dependencies so that we do not have to worry about conflicting with users.
Our library statically links
date_time
system
thread
regex
filesystem
program options
We then have an executable that also needs program_options and links against it dynamically.
When we run the excutable we are getting a double free.
We could take the solution of not linking our code against program_options, which realistically we do not need to, but I want to know WHY this is happening and HOW to prevent it going forward.
Is the answer "don't link your library against boost statically"? If so then what kind of strategies exist to ensure that my boost and your boost play nice together? If the answer is "there are a few boost libraries which shouldn't be static" then is there a list?
I was able to address the double free issue by using GCC's -fvisibility=hidden when building boost.
For more information, see:
Static library loaded twice
https://lists.boost.org/boost-users/2015/01/83575.php
Do shared libraries (.so) files need to present (or specified) at link time?
I've read here (Difference between shared objects (.so), static libraries (.a), and DLL's (.so)?) that .so files must be present at compile time, but in my experience this is not true?
Doesn't shared libraries just get linked at runtime using dlopen and dlsym, so that the library may not be present on the system, when the application is linked?
Most shared libraries need to be present both at build time and at run time. Notice that shared libraries are not DLLs (which is a Windows thing).
I assume you code for Linux. Details are different on other OSes (and they matter).
For example, if you are compiling a Qt application, you need the Qt shared libraries (such as /usr/lib/x86_64-linux-gnu/libQt5Gui.so and many others) both when building your application and when running it. Read about the dynamic linker ld-linux.so(8) & about ELF.
But you are asking about dynamic loading (using dlopen(3) with dlsym(3) ...) of plugins.
Then read Levine's Linkers & Loaders, Program Library HowTo, C++ dlopen mini HowTo, and Drepper's How To Write Shared Libraries
See also this answer.
Some libraries and frameworks try to abstract the loading of plugins in an OS-neutral manner. Read e.g. about Qt plugins support, or about POCO shared libraries (poorly named, it is about plugins).
You can have it both way, it all works.
While with library present at compile time,instead of get library by dlopen/LoadLibrary explictly, you can use all the functions directly
Let's say you compile a C++ shared library libBeta.so which makes use of pre-existing C++ shared libraries libAlpha1.so, libAlpha2.so, libAlpha3.so, etc. If I then write a C++ application which uses libBeta.so directly (and therefore indirectly uses the other libraries), should I link my application to libBeta.so only, or should I link my application to all libraries?
My intuition tells me that I should only link to libBeta.so, because linking to all libraries seems redundant as libBeta.so is already linked to the other libraries. However, undefined reference to errors are proving my intuition wrong.
Could someone explain me why my intuition might be wrong in particular cases?
p.s.:
OS: Linux
Compiler: g++
EDIT
As it turns out the tool I was using for compiling has different behaviour for compiling an executable and compiling a shared library. Linkage to sub-libraries were being omitted when compiling a shared library :(
Shared libraries are fully linked entities, and you don't need to explicitly link to their dependencies.
This is unlike static libraries which is only a collection of object files. When you use a static library you must link to its dependencies. But for share libraries, no you don't need that.
If you get undefined references, then it's not for the dependencies of the shared libraries you link to. It's either that you are missing linking with your own code, or you actually link with a static library.
You only need to link with your direct dependency, libBeta.so.
Actually, a few years ago on some Linux distributions you could get away with having indirect dependencies in your executable -- in this case, say, on libAlpha1.so -- and as long as the dependency gets loaded at runtime, directly or indirectly, the dependency would get satisfied.
This is no longer the case.
I am writing a build system for a project and I am not sure about the links between executables, static libraries and shared libraries.
For me there are three affirmations:
An executable can use both static and shared libraries.
A static library can use both static and shared libraries.
A shared library can only use static libraries.
I have still doubts about the third affirmation...
Can you enlighten me on this?
To use a static library's basically like linking a .o or .obj file: all the implementation's linked into the using application or library at that specific point in time. Changes made to the static library after that time won't be picked up automatically by the code that linked it... the latter would need to be relinked for the changes to be incorporated.
Shared libraries defer the linking until runtime, which means every time the code using a shared library invokes some functionality within it, the version of the shared library which is found at runtime is utilised. As long as the changes don't affect the public API, you can replace a shared library and applications that find it at runtime will pick up the updates/changes without themselves having to be modified/relinked.
So, yes an executable can use both, a static library can use both, and your third "affirmation" is wrong: a shared library can also use both. It just means the shared library itself may use a snapshot of functionality from a static library, or it may find other functionality from another shared library at runtime.