I have certain doubts:
Use case:
A static library containing a global variable, static variable, a function
and a class defined
A shared library uses these and hence they are part of the same.
A executable program also uses the same and they are part of the same.
The executable loads the shared library on run time
What all differs between windows and Linux?
Can the shared library use something from executable's static library objects?
Can the executable use something from shared library's static library objects?
What is the role of loader? For ex: does the static library objects in static library are shared between shared library and executable on Linux?
Is there any difference if the shared libraryis loaded at runtime or load time?
In the library that you define your global static you can define it as follows:
static int g_i=9;
when accessing g_i from other modules then you should use extern to tell the compiler that g_i is defined in another module:
extern int g_i;
This is all Standard C and there should be no differences between the different C compilers regardless of operating systems.
A library can't reference anything in the executable since that would cause a circular reference, rather you should take the shared functionality in the executable and add it to a third library that is referenced by both the existing library and the executable.
There are different use cases where you rather want dynamic loading over static linking. Static libraries makes your executables larger, while dynamic libraries can cause "DLL Hell". Mostly people use shared libraries when they want to share the code between different programs and use static libraries when they only are going to use the library in only one program.
Related
Aside from inclusion of 3rd party software, why would you make a static library for a project. If your writing the source yourself you could just build it as a part of the project and if it's a library to be used more than once wouldn't it make more sense to dynamically link and sit on a run-time library?
Dynamic libraries have a run-time cost due to relocations†because the base and relative load address of the library is unknown until run-time. That is, the function calls and variable access to dynamic libraries are indirect. For this reason the code for shared libraries must be compiled as position-independent code (-fPIC flag in gcc).
Whereas with static libraries it can use cheaper program counter relative access even with address-space randomization because the relative position of that static library (object files really) is available to the linker.
Note that calls to virtual functions are resolved through the vtable (which the dynamic linker can patch on load), so that the cost of calling a virtual function is always the same regardless of where that function resides. (IIRC, I may need to double-check this statement).
See How To Write Shared Libraries by Ulrich Drepper for full details.
Linking to shared libraries is easier though because they contain a list of other shared libraries they depend upon.
Whereas when linking against a static library one must also link explicitly the dependencies of that static library (because a .a is just a bunch of .o files).
A build system should do extra handling for static libraries so that the user does not have to list static library dependencies every time when linking it.
When linking against a static library the linker only pulls in those .o files from the .a that resolve any unresolved symbols, whereas an entire shared library is loaded at run-time. So that if you have a global object in a .o with constructor/destructor side-effects, those side effects will not happen with a static library unless that global object is linked in. Extra care must be taken to make sure that global object is always linked in.
When linking against a shared librarie residing in a non-standard location, along with -L<path> one must specify -Wl,-rpath=<path> as well for the run-time linker to find the shared library there and/or use -Wl,-rpath=$ORIGIN if the shared library is shipped with the executable. Having to set LD_LIBRARY_PATH is a wrong way.
†What is PLT/GOT?
The use of dynamic libraries has three main advantages: a) When you release an update of your app it can live in a DL, which is smaller for downloading from Internet than the whole app. b) If your app is a great RAM eater, then you can load and unload DL as needed. c) Its obvious purpose: share the same code in different apps, in a machine with low resources.
a) May lead to dll hell, where different files, same or different versions, populate the directory tree and mess what app uses what .dll
b) Is only possible if you reserve an excesive amount of stack RAM. Likely bad design.
c) This may be right for broad used libs, like stdio, drivers, and most of OS helpers.
The usage of static libraries avoids a) and b). The disadvantage are that they make the final executable bigger and that, when code changes, they require likely a full re-compilation of the project
I use a class which has a singleton get method which returns a static local library. This is threadsafe in C++1. When I compile this class as a static library and use this library in two different shared libraries: Is there only one instance of the singleton when linking these two shared libraries with an application?
Each DLL will get its own copy of the singleton in Windows. I've heard it's different in Linux but I have no direct experience there.
When the linker is invoked to create the shared library, it will copy any code it needs out of any static libraries - including the static variables defined in that code. Each shared library that is created will get a different copy of the code and variables.
I developed a C++ modular program which loads its modules dynamically. Each module needs a specific static library and I linked this static library to each module. Is there any way to share this static library among all modules without linking it to them separately?
Yes, it is possible. Instead of static library, create dynamic library (so on *nix or dll on Windows) and link your modules against this dynamic lib.
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.
I'd like to build both static and shared libraries in a project.
I know that shared libraries need to be be created from objects compiled with -fpic to get Position Independent Code while the static library doesn't need this. This is all fine and I can create either a shared or static library.
I wouldn't want to compile my source twice to get the different object files, so how is this usually done? I read how to get a shared library based on a static one. However, the example shows the static library being built with -fpic. Is this the way to go? Are there things to be aware of with this?
Is there a common approach to compiling both static and shared libraries? E.g. first static and based on the lib a shared version is created?
I'm interested to know if there are different approaches for this and what to consider when selecting.
I'm using gcc4.4 on Linux.
Thanks in advance!
The common approach that I've seen is, in fact, compiling your source twice, once with PIC and once without. If you don't do that, you either wind up with PIC overhead in the static library, or a shared object that can't be relocated by the OS (effectively meaning it's NOT shared across multiple clients of the library).