I found this question about the difference between .a
and .so
files
First Linking the dynamic libraries:
One answer says:
The advantage of .so (shared object) over .a library is that they are linked during the runtime i.e. after creation of your .o file -o option in gcc. So, if there's any change in .so file, you don't need to recompile your main program. But make sure that your main program is linked to the new .so file with ln command.
He said "during run time" and "is linked" which made me confused what is the time the .so (or .dll) file is linked on runtime, load time, or link time by the linker?
Second linking the static libraries:
Another answer says:
.a are static libraries. If you use code stored inside them, it's taken from them and embedded into your own binary. In Visual Studio, these would be .lib files.
It's obvious, but when I continued my research I found lots of conflicted answer for linking and when it's occurring.
My assumption is that there are multiple linking stages but what is the standard or the majority for both type of libraries? Thanks in advance.
There are two linkers in the life of a typical program - the static linker and the dynamic linker.
The static linker
Generally just called "the linker".
This linker is the one involved in creating a program. It consumes object files, static libraries and dynamic libraries (= shared libraries on Unix, DLLs on Windows) that are referred to in the linkage commandline and from them creates an executable. The static linker also creates dynamic libraries, when asked to, from the same sorts of resources.
The object files are unconditionally merged into the executable: they're cut into sections of different kinds and the sections are physically incorporated into the executable. They are the initial pieces of the program: they determine what other pieces are missing that the static linker has to locate among the static libraries and dynamic libraries that are also input to the linkage1.
Static libraries are archives of object files from which the static linker can pick ones that supply missing parts of the program, based on the parts already present - somewhat like a jigsaw puzzle. Object files in static libraries that aren't needed are ignored; so static libraries are nothing but containers providing the static linker with selections of potentially useful off-the-shelf object files. The "linking" of a static library just means the linking of 0 or more object files copied out of the archive.
Dynamic libraries cannot be physically merged into the executable, in whole or in part: they are much more similar to executables themselves than they are to object files. But they can provide missing pieces of the program that it could use (call, refer to) when it is running, if the dynamic library was loaded into the same process address space. Which can be done. Like an executable, and unlike an object file, a dynamic library is loadable as part of a process.
So when the static linker discovers that a missing piece is not supplied by
object files (including the ones in static libraries) but is supplied by a dynamic library
name.(so|dll)
it leaves that piece missing from the executable but writes a kind of memo into
the executable that says: This program needs dynamic library name.(so|dll)
. The memo
says at least that: it may include more information. When we say that name.(so|dll)
"is linked" with a program or that the program is "linked against" name.(so|dll)
, we just mean that the dynamic library was considered by the
static linker and possibly that the static linker put a memo in the executable saying that name.(so|dll)
is needed by the program.
These memos are memos for...
The dynamic linker
Sometimes called "the loader".
This is the linker that gets a typical program running, every time it runs. Come runtime, your typical executable is still an incomplete jigsaw that needs one or more dynamic libraries to be completed and contains memos saying what dynamic libraries it needs.
The executable is loaded into a process address space and the dynamic linker (if the program needs it) is given charge of finishing the jigsaw. It reads the memos that the static linker has left for it, telling it what dynamic libaries are needed. It searches for those dynamic libraries on the filesystem, following a search algorithm and - if it can find them - loads them into same process.
These dynamic libraries might well themselves be incomplete jigsaws that depend on other dynamic libraries mentioned in their own memos or the memos of the executable. The dynamic linker recursively finds and loads them all.
Then it finishes the whole jigsaw, working in essentially the same way that the static linker did, but this time connecting the pieces together in memory rather than in a file. It carries on linking where the static linker stopped, using the help that the static linker has provided in the executable and in the dynamic libraries themselves. When the dynamic linker has completed the program in memory, with no missing pieces, the program gets to run.
The technicalities of how the jigsaw pieces are connected by either the static linker or the dynamic linker are difficult, so I'll leave them aside here.
Confusingly...
When the static linker produces an executable that depends on dynamic libraries we say that the executable is dynamically linked - before it has even run. But come runtime, we also say that the job done by the dynamic linker is dynamic linkage.
It's possible for the static linker to produce an executable that is a complete jigsaw itself, composed entirely from sections of object files, with no dependenciies on dynamic libraries. Such a progam is said to statically linked. We don't just mean: The static linker made it - the static linker makes every executable. We mean: It has no dependencies on dynamic libraries: once it's loaded, there's no dynamic linkage to be done.
*.lib
) to find out what the corresponding dynamic library offers.