I can't say I understand what a "statically linked dynamic library", nor do I know anything about signatures contained in libraries (sounds interesting though: does this mean the linker is able to check for type mismatches in arguments and return types at link time? ELF definitely does not have such a feature.) so this answer will not be from a comparative point of view. Also, as your question is very broad, the answer will be superficial in detail.
Yes, you can create either a static library (.a
) or a shared library (.so
). When the linker looks for libraries requested with -l
, it will prefer the shared library if both exist, unless overridden with an option like -static
.
When building a library from source code, one only needs to build it as a static library (.a
) or as a shared library (.so
), not both. Still, quite a few packages' build scripts are set up to build both versions (which requires compiling twice, once with position independent code and once without) in order to give consumers of the library the choice of which one to link with.
The necessary pieces of a static library are totally incorporated into the binary that is built. There is no need to have the .a
file available at run time. In contrast, a shared library that was linked to a binary has to be available at run time, although the run-time dynamic linker will typically search for it under a modified name, its "soname" (usually libsomething.so
at link time and libsomething.so.<integer>
at run time), which is a feature that allows multiple different versions of a library with slightly different APIs to be installed in the system at the same time.
In your question you mention also explicitly loading dynamic libraries at run time. This is often done for modular applications or applications with plugins. In this case, the library in question (often called a "module" or "plugin") is not linked with the application at all and the build-time linker knows nothing of it. Instead, the application developer must write code to call the run-time dynamic linker and ask it to open a library by filename or full pathname. Sometimes the names of the modules to open are listed in the application's configuration file, or there is some other piece of application logic that decides which modules are or aren't needed.