All Courses
Build Tools Testing

CMake Basics

Overview

CMake is a cross-platform build system generator. It doesn't build your code directlyβ€”it generates native build files (Makefiles, Visual Studio projects, etc.) that then compile your code.

Learning Objectives

By the end of this section, you will understand:

  • CMake basics and CMakeLists.txt structure
  • Creating executables and libraries
  • Managing dependencies
  • Modern CMake practices (target-based)
  • Using CMake with external libraries

Why CMake?

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      CMake WORKFLOW                                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                         β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                                  β”‚
β”‚    β”‚ CMakeLists.txt  β”‚                                                  β”‚
β”‚    β”‚ (Platform-      β”‚                                                  β”‚
β”‚    β”‚  Independent)   β”‚                                                  β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                                  β”‚
β”‚             β”‚                                                           β”‚
β”‚             β–Ό                                                           β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                                  β”‚
β”‚    β”‚     CMake       β”‚                                                  β”‚
β”‚    β”‚   Generator     β”‚                                                  β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                                  β”‚
β”‚             β”‚                                                           β”‚
β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”                                                   β”‚
β”‚     β–Ό       β–Ό       β–Ό                                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”                                            β”‚
β”‚  β”‚Make- β”‚ β”‚Visualβ”‚ β”‚Ninja β”‚  ... other build systems                   β”‚
β”‚  β”‚file  β”‚ β”‚Studioβ”‚ β”‚      β”‚                                            β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”˜                                            β”‚
β”‚                                                                         β”‚
β”‚  Write once, build anywhere!                                            β”‚
β”‚                                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Minimal CMakeLists.txt

# Minimum required CMake version
cmake_minimum_required(VERSION 3.16)

# Project name and version
project(MyProject VERSION 1.0.0 LANGUAGES CXX)

# Create an executable
add_executable(my_app main.cpp)

Project Structure

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    TYPICAL CMAKE PROJECT STRUCTURE                       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                         β”‚
β”‚  my_project/                                                            β”‚
β”‚  β”œβ”€β”€ CMakeLists.txt           ◄── Root CMake file                       β”‚
β”‚  β”œβ”€β”€ src/                                                               β”‚
β”‚  β”‚   β”œβ”€β”€ CMakeLists.txt       ◄── Source directory CMake               β”‚
β”‚  β”‚   β”œβ”€β”€ main.cpp                                                       β”‚
β”‚  β”‚   β”œβ”€β”€ utils.cpp                                                      β”‚
β”‚  β”‚   └── utils.hpp                                                      β”‚
β”‚  β”œβ”€β”€ include/                                                           β”‚
β”‚  β”‚   └── my_project/                                                    β”‚
β”‚  β”‚       └── public_header.hpp                                          β”‚
β”‚  β”œβ”€β”€ tests/                                                             β”‚
β”‚  β”‚   β”œβ”€β”€ CMakeLists.txt       ◄── Test directory CMake                 β”‚
β”‚  β”‚   └── test_utils.cpp                                                 β”‚
β”‚  β”œβ”€β”€ libs/                    ◄── Third-party libraries                β”‚
β”‚  └── build/                   ◄── Build output (generated)             β”‚
β”‚      β”œβ”€β”€ Makefile                                                       β”‚
β”‚      └── ...                                                            β”‚
β”‚                                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Building with CMake

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    BUILD COMMANDS                                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                         β”‚
β”‚  # Step 1: Create build directory                                       β”‚
β”‚  mkdir build && cd build                                                β”‚
β”‚                                                                         β”‚
β”‚  # Step 2: Generate build files                                         β”‚
β”‚  cmake ..                                                               β”‚
β”‚                                                                         β”‚
β”‚  # Step 3: Build the project                                            β”‚
β”‚  cmake --build .                                                        β”‚
β”‚                                                                         β”‚
β”‚  # Or use make directly (if Makefile generator)                         β”‚
β”‚  make                                                                   β”‚
β”‚                                                                         β”‚
β”‚  # Build with parallel jobs                                             β”‚
β”‚  cmake --build . -j4                                                    β”‚
β”‚                                                                         β”‚
β”‚  # Build specific target                                                β”‚
β”‚  cmake --build . --target my_app                                        β”‚
β”‚                                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

CMake Commands

Creating Targets

# Executable
add_executable(app_name source1.cpp source2.cpp)

# Static library (.a / .lib)
add_library(mylib STATIC source1.cpp source2.cpp)

# Shared library (.so / .dll)
add_library(mylib SHARED source1.cpp source2.cpp)

# Header-only library (INTERFACE)
add_library(mylib INTERFACE)

Setting Properties

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

# Or per-target (modern way)
target_compile_features(my_app PRIVATE cxx_std_17)

# Compiler flags
target_compile_options(my_app PRIVATE -Wall -Wextra -Wpedantic)

# Definitions
target_compile_definitions(my_app PRIVATE DEBUG_MODE=1)

Include Directories

# Include paths
target_include_directories(my_app
    PUBLIC  ${PROJECT_SOURCE_DIR}/include  # Propagates to dependents
    PRIVATE ${PROJECT_SOURCE_DIR}/src      # Only for this target
)

Linking

# Link libraries
target_link_libraries(my_app
    PRIVATE mylib       # Internal dependency
    PUBLIC  otherlib    # Propagates to dependents
)

Visibility Keywords

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚               TARGET PROPERTY VISIBILITY                                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                         PRIVATE                                  β”‚   β”‚
β”‚  β”‚  Only affects the target itself                                  β”‚   β”‚
β”‚  β”‚  Example: Implementation details, internal includes              β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                         PUBLIC                                   β”‚   β”‚
β”‚  β”‚  Affects target AND anything that links to it                   β”‚   β”‚
β”‚  β”‚  Example: Public headers, API definitions                        β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚                        INTERFACE                                 β”‚   β”‚
β”‚  β”‚  Only affects things that link to the target                    β”‚   β”‚
β”‚  β”‚  Example: Header-only libraries                                  β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                         β”‚
β”‚  Example:                                                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” PUBLIC β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” links β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”                      β”‚
β”‚  β”‚  LibA   │───────►│  LibB   │──────►│   App   β”‚                      β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β”‚
β”‚       β”‚                  β”‚                  β”‚                           β”‚
β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β”‚
β”‚                App gets LibA's public properties!                       β”‚
β”‚                                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Finding Packages

# Find system-installed package
find_package(Threads REQUIRED)

# Find with components
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)

# Use the found package
target_link_libraries(my_app
    PRIVATE
        Threads::Threads
        Boost::filesystem
        Boost::system
)

Common Package Patterns

# OpenSSL
find_package(OpenSSL REQUIRED)
target_link_libraries(app PRIVATE OpenSSL::SSL OpenSSL::Crypto)

# CURL
find_package(CURL REQUIRED)
target_link_libraries(app PRIVATE CURL::libcurl)

# SQLite
find_package(SQLite3 REQUIRED)
target_link_libraries(app PRIVATE SQLite::SQLite3)

FetchContent (Download Dependencies)

include(FetchContent)

# Declare dependency
FetchContent_Declare(
    json
    GIT_REPOSITORY https://github.com/nlohmann/json.git
    GIT_TAG        v3.11.2
)

# Make it available
FetchContent_MakeAvailable(json)

# Use it
target_link_libraries(my_app PRIVATE nlohmann_json::nlohmann_json)

Variables and Cache

# Regular variable
set(MY_VAR "value")

# Cache variable (user-configurable)
set(MY_OPTION "default" CACHE STRING "Description of option")

# Boolean option
option(ENABLE_TESTS "Build tests" ON)

# Use variables
message(STATUS "MY_VAR = ${MY_VAR}")

# Conditional
if(ENABLE_TESTS)
    add_subdirectory(tests)
endif()

Subdirectories

# Root CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(MyProject)

# Add subdirectories
add_subdirectory(src)
add_subdirectory(tests)

# src/CMakeLists.txt
add_library(mylib source.cpp)
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

# tests/CMakeLists.txt
add_executable(tests test_main.cpp)
target_link_libraries(tests PRIVATE mylib)

Complete Example

# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(Calculator VERSION 1.0.0 LANGUAGES CXX)

# Settings
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Options
option(BUILD_TESTS "Build unit tests" ON)

# Create library
add_library(calc_lib
    src/calculator.cpp
    src/operations.cpp
)

target_include_directories(calc_lib
    PUBLIC  ${PROJECT_SOURCE_DIR}/include
    PRIVATE ${PROJECT_SOURCE_DIR}/src
)

target_compile_options(calc_lib PRIVATE
    $<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra>
    $<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra>
    $<$<CXX_COMPILER_ID:MSVC>:/W4>
)

# Create executable
add_executable(calculator src/main.cpp)
target_link_libraries(calculator PRIVATE calc_lib)

# Tests
if(BUILD_TESTS)
    enable_testing()
    add_subdirectory(tests)
endif()

# Installation
install(TARGETS calculator DESTINATION bin)
install(DIRECTORY include/ DESTINATION include)

Generator Expressions

# Compiler-specific flags
target_compile_options(app PRIVATE
    $<$<CXX_COMPILER_ID:GNU>:-Wall>
    $<$<CXX_COMPILER_ID:MSVC>:/W4>
)

# Configuration-specific
target_compile_definitions(app PRIVATE
    $<$<CONFIG:Debug>:DEBUG_MODE>
    $<$<CONFIG:Release>:NDEBUG>
)

# Build interface vs install interface
target_include_directories(lib
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
)

Recommended Conventions

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    MODERN CMAKE BEST PRACTICES                           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                         β”‚
β”‚  βœ“ DO                              βœ— DON'T                              β”‚
β”‚  ─────────────────────────────     ─────────────────────────────        β”‚
β”‚  β€’ Use target_* commands           β€’ Use include_directories()          β”‚
β”‚  β€’ Use PRIVATE/PUBLIC/INTERFACE    β€’ Use link_libraries()               β”‚
β”‚  β€’ Use generator expressions       β€’ Use CMAKE_CXX_FLAGS                β”‚
β”‚  β€’ Use FetchContent for deps       β€’ Use file(GLOB ...) for sources     β”‚
β”‚  β€’ Create IMPORTED targets         β€’ Hardcode paths                     β”‚
β”‚  β€’ Use cmake --build              β€’ Mix old and modern CMake            β”‚
β”‚                                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  OLD (avoid):                                                    β”‚   β”‚
β”‚  β”‚  include_directories(include)                                    β”‚   β”‚
β”‚  β”‚  link_libraries(mylib)                                           β”‚   β”‚
β”‚  β”‚  add_definitions(-DDEBUG)                                        β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  MODERN (prefer):                                                β”‚   β”‚
β”‚  β”‚  target_include_directories(app PRIVATE include)                 β”‚   β”‚
β”‚  β”‚  target_link_libraries(app PRIVATE mylib)                        β”‚   β”‚
β”‚  β”‚  target_compile_definitions(app PRIVATE DEBUG)                   β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚                                                                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Useful Commands

Command Description
cmake -S . -B build Configure with source and build dirs
cmake --build build Build the project
cmake --build build -j Build with all CPU cores
cmake --install build Install the project
cmake --build build --target clean Clean build
cmake -DCMAKE_BUILD_TYPE=Release .. Release build
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .. For IDE/tools

Summary

Concept Purpose
cmake_minimum_required Set minimum CMake version
project() Define project name and languages
add_executable() Create executable target
add_library() Create library target
target_* commands Modern, target-based configuration
find_package() Locate installed dependencies
FetchContent Download dependencies at configure time

Next Steps

  • Practice with examples.cpp (a complete CMake project)
  • Complete the exercises.cpp challenges
  • Try building real projects with CMake
  • Explore CPack for packaging