CMake - Quick Reference

SkillAI & models

CMake build system for C/C++ projects. Modern CMake (3.20+) with targets, properties, presets (CMakePresets.json), FetchContent, find_package, generator expressions, install rules, vcpkg/Conan integration.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the CMake - Quick Reference skill

What this skill tells your AI

The instructions your AI receives, as published by claude-dev-suite/claude-dev-suite in skills/build-tools/cmake/SKILL.md and read by ahel’s review.

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: cmake.

Minimal modern CMakeLists.txt

cmake_minimum_required(VERSION 3.25)
project(myapp VERSION 0.1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)   # for clang-tidy / IDEs

add_library(mylib
    src/api.cpp
    src/util.cpp
)

target_include_directories(mylib
    PUBLIC  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
            $<INSTALL_INTERFACE:include>
    PRIVATE src
)

target_compile_features(mylib PUBLIC cxx_std_20)

target_compile_options(mylib PRIVATE
    $<$<CXX_COMPILER_ID:MSVC>:/W4 /WX /permissive->
    $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Wpedantic -Werror>
)

add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE mylib)

Targets, not variables

Rule: Configure things on targets (target_* commands), not via global add_* / include_directories / set(CMAKE_...). Modern CMake = target-centric.

Avoid (legacy)Use (modern)
include_directories(...)target_include_directories(tgt PUBLIC ...)
add_definitions(-DX)target_compile_definitions(tgt PRIVATE X)
link_libraries(...)target_link_libraries(tgt PRIVATE ...)
set(CMAKE_CXX_FLAGS "...")target_compile_options(tgt PRIVATE ...)

Visibility: PUBLIC / PRIVATE / INTERFACE

target_link_libraries(mylib
    PUBLIC    fmt::fmt        # consumers also need fmt (in mylib's API)
    PRIVATE   spdlog::spdlog  # implementation only
    INTERFACE asio::asio      # header-only requirement, not used by mylib itself
)

CMakePresets.json (CMake 3.19+)

{
  "version": 6,
  "configurePresets": [
    {
      "name": "base",
      "hidden": true,
      "binaryDir": "${sourceDir}/build/${presetName}",
      "generator": "Ninja",
      "cacheVariables": { "CMAKE_EXPORT_COMPILE_COMMANDS": "ON" }
    },
    {
      "name": "debug",
      "inherits": "base",
      "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" }
    },
    {
      "name": "debug-asan",
      "inherits": "debug",
      "cacheVariables": {
        "CMAKE_CXX_FLAGS": "-fsanitize=address,undefined -fno-omit-frame-pointer",
        "CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address,undefined"
      }
    },
    {
      "name": "release",
      "inherits": "base",
      "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
    }
  ],
  "buildPresets":   [ { "name": "debug", "configurePreset": "debug" } ],
  "testPresets":    [ { "name": "debug", "configurePreset": "debug",
                         "output": { "outputOnFailure": true } } ]
}

Usage:

cmake --preset debug
cmake --build --preset debug
ctest --preset debug

Dependencies

find_package (system or vcpkg/Conan-installed)

find_package(fmt 10 REQUIRED CONFIG)
target_link_libraries(myapp PRIVATE fmt::fmt)

FetchContent (vendored at configure time)

include(FetchContent)
FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG v1.15.2
    GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(googletest)
target_link_libraries(my_test PRIVATE GTest::gtest_main)

vcpkg manifest mode

// vcpkg.json
{ "name": "myapp", "version-string": "0.1.0",
  "dependencies": ["fmt", "spdlog", { "name": "boost-asio", "version>=": "1.84.0" }] }

Configure with -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake.

Generator Expressions

target_compile_options(mylib PRIVATE
    $<$<CONFIG:Debug>:-O0 -g3>
    $<$<CONFIG:Release>:-O3 -DNDEBUG>
    $<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>
)

# Different include path at build vs install time
target_include_directories(mylib PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

Tests with CTest

enable_testing()
add_executable(api_test tests/api_test.cpp)
target_link_libraries(api_test PRIVATE mylib GTest::gtest_main)

include(GoogleTest)
gtest_discover_tests(api_test)

Run: ctest --output-on-failure -j$(nproc).

Install + export package

include(GNUInstallDirs)

install(TARGETS mylib EXPORT mylibTargets
    LIBRARY  DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE  DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME  DESTINATION ${CMAKE_INSTALL_BINDIR}
    INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(EXPORT mylibTargets
    FILE mylibTargets.cmake
    NAMESPACE mylib::
    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mylib
)

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
file(GLOB ...) for sourcesAdds/removes invisible to CMake until reconfigureList sources explicitly
Global include_directories, add_definitionsLeaks to all targetstarget_* commands
link_directories(...)Order-dependent, fragiletarget_link_libraries(... <imported target>)
In-source buildPollutes repoOut-of-source: cmake -S . -B build
Hard-coded compiler flagsBreaks on other compilersGenerator expressions per CXX_COMPILER_ID
set(CMAKE_BUILD_TYPE Release) in CMakeListsOverrides user choiceSet in preset or via -DCMAKE_BUILD_TYPE=
Copying .cmake files instead of find_package config modeVersions driftInstall + export targets, consume with config-mode find_package

Common Commands

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j
ctest --test-dir build --output-on-failure
cmake --install build --prefix /opt/myapp
cmake --build build --target clean
cmake --build build --target package         # if CPack configured

Signals

GitHub stars
33
Forks
6
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
cmake
Source
github.com/claude-dev-suite/claude-dev-suite