Introduction to efficient build tools for C++ projects

We now reach a rite of passage by moving from a Make-based build process to a CMake-based workflow.

The traditional "rule of three" (found in many classic open-source projects) — ./configure && make && sudo make install — is gradually being replaced by the CMake approach. This modern workflow typically involves creating a separate build directory to keep the source tree clean (so-called "out-of-source builds"):

mkdir build && cd build
cmake ..
cmake --build .

To get from the makefile based approach in our cpp-tutorial please check out the git branch main-with-cmake where all makefiles a converted to a cmake based approach.

Let’s start simple with the first tutorial, tutorial00 which list our limits file as print output:

cmake_minimum_required(VERSION 3.10)

# 1. Define the project name
project(MyProject)

# 2. Define the executable name and source files
# This replaces: g++ main.cpp -o main
add_executable(main ../main.cpp)

For this minimal example the make file would be simpler and shorter than the cmake project, but this changes rapidly when we are using (meaning including and linking) external libraries, like SDL in our cases:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cmake_minimum_required(VERSION 3.10)
project(SynthProject)

# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 1. Find the SDL2 and SDL2_ttf packages
# This replaces manual -I and -L paths
find_package(SDL2 REQUIRED)
find_package(SDL2_ttf REQUIRED)

# 2. Define the executable and source files
add_executable(synth
    main.cpp
)

# 3. Link the libraries
# On Linux, we don't need mingw32 or winmm!
target_link_libraries(synth PRIVATE
    SDL2::SDL2
    # SDL2::SDL2main is usually not needed on Linux,
    # but SDL2::SDL2 handles the heavy lifting.
)

Tip: You can combine the configuration and build steps into a single line to save time:

cmake -B build && cmake --build .

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
sven@kali-yuga:~/development/cpp-tutorials/tutorial08/build$ cmake ..
-- The C compiler identification is GNU 12.2.0
-- The CXX compiler identification is GNU 12.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "1.8.1")
-- Checking for module 'sdl2'
--   Found sdl2, version 2.26.5
-- Checking for module 'SDL2_ttf'
--   Found SDL2_ttf, version 2.20.1
-- Configuring done
-- Generating done
-- Build files have been written to: /home/sven/development/cpp-tutorials/tutorial08/build
sven@kali-yuga:~/development/cpp-tutorials/tutorial08/build$ cmake --build .
[ 33%] Building CXX object CMakeFiles/synth.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/synth.dir/Voice.cpp.o
[100%] Linking CXX executable synth
[100%] Built target synth