Table of Contents
CMake Projects and Targets
A project is declared with project(name), and targets are the build artifacts you create — executables, libraries, or custom outputs. Each target has properties (source files, include paths, linked libraries, compiler flags). In modern CMake, you apply settings to targets, not globally.
A project groups related targets:
cmake_minimum_required(VERSION 3.20) project(MyApp VERSION 1.0) add_executable(myapp main.cpp) add_library(mylib utils.cpp)
This creates a project MyApp with two targets: the executable myapp and a library mylib.
Target types:
add_executable(name source.cpp)— builds an executableadd_library(name source.cpp)— builds a library (static by default)add_library(name SHARED source.cpp)— shared library (.so, .dll)add_library(name STATIC source.cpp)— static library (.a, .lib)add_library(name INTERFACE)— header-only library (no build, only interface)add_custom_target(name COMMAND ...)— runs a command (not a traditional build output)
Each target owns its properties: source files, include directories, linked libraries, compiler flags. Properties are set with target_* commands:
target_sources(mylib PRIVATE utils.cpp utils.h) target_include_directories(mylib PUBLIC include/) target_link_libraries(mylib PRIVATE somelib) target_compile_options(mylib PRIVATE -Wall)
The PRIVATE, PUBLIC, INTERFACE keywords control visibility:
PRIVATE— only the target itself uses itPUBLIC— target and anything that links to it use itINTERFACE— only consumers of the target use it (for header-only libraries)
Modern CMake means thinking in targets. Don't set global flags with set(CMAKE_CXX_FLAGS ...). Instead, configure each target individually. This makes builds predictable and modular.
