This is a note covering compilation, linking, static linking and dynamic linking of shared libraries.
The content of this post is organized into the following parts
- What is Compilation?
- What is Linking?
- Why do we need a separate Linking phase?
- What is Static Linking?
- What is Dynamic Linking?
It process the files and generate object files. This step doesn’t create anything that can actually run. In compilation, It focuses on the content of a single file. It process one file at a time and have no way of knowing the content of other files. As a result, if the definition of a certain function has not been found, it will just assume that it is defined at some other file.
In g++, you can just do Compilation without Linking using the -c flag. But note, you should not have multiple files in the commandline
(the error g++: fatal error: cannot specify -o with -c, -S or -E with multiple files)
This follows the principle we described above because compilation is focusing on a single file. As a result, there shouldn’t be multiple files in the commandline). With the -c flag, you don’t need to have a “main ” function to get this file compiled.
It creates a single executable file from multiple object files. This single executable can actually run. If it couldn’t find the definition of a certain function, it would throw an error. (quote “Computer Systems – A Programmer’s Perspective (CSAPP)”, “Linking is the process of collecting and combining various pieces of code and data into a single file that can be loaded (copied) into memory and executed“).
You need to have all the object files you need and a main function.
Design Reasoning behind the separation of compilation and linking
- Allow better modulation of the system. Functions can be defined in separate files, reducing the complexity of the program.
- For large programs, it increases the efficiency of the overall compilation process. Only the source files that have changed needs to go through the compilation process again.
- Allow plugging in executable files directly.
Again, quoting “CSAPP”
” (1) Usability: Linkers play a crucial role in software development because they enable separate compilation. In stead of organizing a large application as one monolithic source file, we can decompose it into smaller, more manageable modules that can be modified and compiled separately. (2) Efficiency: When we change one of these modules, we simple recompile it and relink the application, without having to recompile the other files”. ”
Static linkers takes input a 1) collection of relocatable object files (outputs from the compilation phase) and 2) command line arguments to generate output a fully linked executable file.
The two major tasks are 1) symbol resolution (associate each symbol reference with exactly one symbol definition) 2) relocation (relocates code and data sections in each relocatable object files).
Static linking copies over all the library routines into the single executable file, which can potentially result in a large executable file that takes a lot of memory space. The Pros are the executable file is all you need (portability)
in Makefile, you also often see
targe : lib.o lib2.o
or in commandline (bash shell for example)
g++ main.c -o main.o staic_lib.a
The .a files is a kind of c++ archive file
The static libraries has a few major draw backs
1) library routines can be outdated (the contents of the library routines were actually copied into the final executable)
2) The executable can be fairly large in terms of memory space. For example, printf and scanf are often duplicated across 50-100 processes, taking up a lot of memory.
To solve these problems, shared libraries are created. A shared library is an object module, at run time, can be loaded at an arbitrary memory address and linkers with a program in memory. This process is called dynamic linking, and is performed by a program called dynamic linker. (CS:APP, section 7.10)
Some good references for further reading (also source materials for this post)
A good resource is also “Computer Systems – A Programmer’s Perspective” chapter 7.