Static Linking in C++
After the compilation process, linking plays a crucial role in finalising the executable. The object code generated during compilation often contains references to functions or symbols that are defined elsewhere, such as in other parts of the code or in external libraries. To resolve these references and ensure the executable runs smoothly, the linker incorporates the necessary code from external libraries. These libraries can be either static or dynamic, and the linker’s job is to integrate them appropriately into the final executable.
Imagine you are building a toy car using different parts: a body, wheels, and engine. Engine and wheels are owned by your friends. Each part of your car represents a different piece of code stored in a separate file, which could be an external library. To assemble your car, you need to attach the engine and wheels to the body.
When it comes to linking all these parts together, you can opt for two ways:
- Static Linking: This is like permanently glueing the wheels and engine to the body. With static linking, you take the code from your friend's engine and wheels and merge them into the body’s code. Just like how your toy car has all the parts glued together and ready to roll! Static linking ensures that the final executable has everything it needs to successfully run.
- Dynamic linking: Instead of permanently glueing the parts, you assemble your car with detachable parts. When you want to play, you snap the wheels and engine together with the body. Dynamic linking ensures that the toy car’s body knows where to find the engine code and wheel code when it needs them. So when you run your executable, depending on the requirement, it snaps the required parts together. Dynamic linking offers flexibility and efficient memory usage by loading external code libraries at runtime.
As we’ve seen, static linking and dynamic linking offer different approaches to incorporating external code into your program. Now, let’s delve deeper into the concept of external libraries, which can be either static or dynamic, and how they fit into the linking process.
External libraries serve as a repository of reusable code, much like the engine and wheel in our toy car analogy. These libraries contain precompiled functions and data that can be used by different program. Just as you would attach the toy car’s body with engine and wheels, your program can link to external libraries to access their functionalities.
When it comes to linking with external libraries, there are two different primary types: static libraries and dynamic libraries. Here we will be focusing on the static library.
What are static libraries?
Static libraries, also known as static archives, are collections of precompiled object files (.obj on Windows or .o on Unix-like systems) bundled together into a single archive file (.lib on Windows or .a on Unix-like systems). Each object file within the static library contains code for specific functionalities used by the executable.
Why use a static library?
- Static libraries are compiled directly into your program, making your final executable completely self-contained. This means you don’t need to worry about the end user having the correct version of the library installed on their system or potential compatibility issues.
- Because the static library code has been directly integrated into the executable, there is no overhead associated with loading it at runtime. This could lead to faster startup time and execution speeds for your program, although larger executable sizes may be a trade-off.
- With the static library, you have complete control over which version of the library is being linked into the program. This can be beneficial if you need to ensure compatibility with specific library functions.
How are static libraries created?
Creating a static library in C++ for Linux distributions involves several steps, including compiling source code into object files, archiving those object files into a library, and then using that library in other projects.
Let’s say you have two source files: addFunctions.cpp and subtractFunctions.h, which contain some math functions that you want to include in your static library.
Write the source code:
Get Hitgirl’s stories in your inbox
Join Medium for free to get updates from this writer.
addFunction.h contains the declaration of the add function.
#ifndef ADD_H
#define ADD_H
int add(int numberOne, int numberTwo);
#endifsubtractFunction.h contains a declaration of the subtract function.
#ifndef SUBTRACT_H
#define SUBTRACT_H
int subtract(int numberOne, int numberTwo);
#endifImplement the add function in sumFunction.cpp .
#include "addFunction.h"
int add(int numberOne, int numberTwo) {
return a + b;
}Implement the subtract function in subtractFunction.cpp .
#include "subtractFunction4.h"
int subtract(int a, int b) {
return a - b;
}Compile into object code.
Compile each source file into object files using the g++ compiler. When you compile with the -c flag, it instructs the compiler to stop the process before the linking phase and produce a .o object file instead. These object files contain machine code generated from your source code, representing the compiled version of each individual source file.
g++ -c sumFunction.cpp subtractFunction.cpp -o sumFunction.o subtractFunction.og++: This is the GNU Compiler Collection command for compiling and linking C++ programs.-c: Indicates that you want to compile without linking, producing object files.sumFunction.cpp,subtractFunction.cpp: Specifies the source files to compile.
Create a static Library.
To create the static library , we use ar command to create the static library, the r option replaces older object files with the new ones, and the c option creates the library if it doesn't already exist. Additionally, the s option can be added to automatically index the library during creation.
ar rcs libmathFunctions.a sumFunction.o subtractFunction.oHow to use the static library?
Now that the library is created, to use the static library, include the header files addFunction.h and subtractFunction.h in your source code(main.cpp) to provide the function declarations.
Compile your program, ensuring to link against the static library libmathFunctions.a.
g++ -o myProgram main.cpp -L/path/to/library -lmathFunctionsg++: This is the GNU Compiler Collection command for compiling and linking C++ programs.-o myProgram: This option specifies the name of the output file. In this case, the compiled executable will be namedmyProgram.main.cpp: This is the source file containing main program code.-L/path/to/library: This option specifies the directory to search for libraries. Replace/path/to/librarywith the actual path to the directory where your static librarylibmathFunctions.ais located.-lmathFunctions: This option tells the compiler to link against the static library namedlibmathFunctions.a. Thelibprefix and.aextension are omitted here, only specify the base name of the library.
This compilation command instructs the compiler to compile the main.cpp file, while also directing it to search for the static library libmathFunctions.a in the specified directory (/path/to/library). By statically linking against this library, the compiler produces the executable myProgram. This executable incorporates all the necessary functionality from the static library, rendering it self-contained and independent of external dependencies at runtime.






