Build Systems¶
C++ code needs to be compiled and linked. While you can use the compiler directly, build systems automate this process.
The Compilation Process¶
Understanding what happens when you run g++ main.cpp is crucial.
- Preprocessing (
.cpp-> Translation Unit): - Handles directives like#include,#define,#ifdef. - The output is a pure C++ file with all headers pasted in. - Command:g++ -E main.cpp > main.i
- Compilation (Translation Unit -> Assembly
.s): - Translates C++ code into assembly language for the target architecture. - Command:g++ -S main.i - Assembly (Assembly -> Object File
.o): - Translates assembly into machine code. - The object file contains code but unresolved symbols (functions defined elsewhere). - Command:g++ -c main.s - Linking (Object Files + Libs -> Executable):
- Combines multiple
.ofiles and libraries. - Resolves symbols (e.g., connecting a call tostd::coutto the standard library). - Command:g++ main.o utils.o -o my_program
Make¶
The classic build tool. It uses a Makefile to define rules.
Basic Makefile¶
CMake¶
The modern standard. It generates build files (like Makefiles or Ninja) for you. It is cross-platform and handles dependencies gracefully.
Modern CMake uses "Targets". Avoid global variables like include_directories.
CMakeLists.txt¶
Building with CMake¶
Libraries¶
- Static Library (
.a/.lib): Code is copied into your executable. Larger size, no runtime dependency. - Dynamic/Shared Library (
.so/.dll): Code is loaded at runtime. Smaller executable, requires library to be present.