Modern CMake Examples
This module demonstrates CMake best practices through anti-pattern vs best-practice comparisons.
Contents
anti-patterns/- Common CMake mistakes to avoidbest-practices/- Modern CMake approaches
Key Concepts
Target-Based Commands
Anti-pattern:
include_directories(${PROJECT_SOURCE_DIR}/include)
link_libraries(some_lib)
Best practice:
target_include_directories(my_target PRIVATE ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(my_target PRIVATE some_lib)
Why Target-Based is Better
- Encapsulation - Dependencies don't leak to other targets
- Transitivity - PUBLIC/PRIVATE/INTERFACE control propagation
- Scalability - Works correctly in large projects
- IDE Support - Better integration with modern IDEs
Dependency Management
Use FetchContent for automatic dependency download:
include(FetchContent)
FetchContent_Declare(
benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG v1.8.3
)
FetchContent_MakeAvailable(benchmark)
CMake Presets
Use CMakePresets.json for reproducible builds:
cmake --preset=release
cmake --build build/release
Building
# From project root
cmake --preset=release
cmake --build build/release --target cmake_anti_patterns cmake_best_practices