Skip to content
Back to skills

Cmake

ASecurity

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. USE WHEN: user mentions "CMake", "CMakeLists.txt", "CMakePresets", "find_package", "FetchContent", "target_link_libraries", "vcpkg", "Conan", "C++ build" DO NOT USE FOR: Make, autotools, Bazel, Meson, Visual Studio .vcxproj direct editing

  • 31 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added September 8, 2026
ai-agentsgoc++bashexpresstestinggitapidocumentation

Works with

  • api
  • mcp

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add claude-dev-suite/claude-dev-suite --skill cmake --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Cmake?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Cmake
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/claude-dev-suite-cmake/badge)](https://www.skillsdirectory.com/skills/claude-dev-suite-cmake)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cmake
description: |
  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.

  USE WHEN: user mentions "CMake", "CMakeLists.txt", "CMakePresets", "find_package",
  "FetchContent", "target_link_libraries", "vcpkg", "Conan", "C++ build"

  DO NOT USE FOR: Make, autotools, Bazel, Meson, Visual Studio .vcxproj direct editing
allowed-tools: Read, Grep, Glob, Write, Edit
---
# CMake - Quick Reference

> **Deep Knowledge**: Use `mcp__documentation__fetch_docs` with technology: `cmake`.

## Minimal modern CMakeLists.txt

```cmake
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

```cmake
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+)

```json
{
  "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:
```bash
cmake --preset debug
cmake --build --preset debug
ctest --preset debug
```

## Dependencies

### find_package (system or vcpkg/Conan-installed)
```cmake
find_package(fmt 10 REQUIRED CONFIG)
target_link_libraries(myapp PRIVATE fmt::fmt)
```

### FetchContent (vendored at configure time)
```cmake
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
```json
// 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

```cmake
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

```cmake
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

```cmake
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-Pattern | Why It's Bad | Correct Approach |
|--------------|--------------|------------------|
| `file(GLOB ...)` for sources | Adds/removes invisible to CMake until reconfigure | List sources explicitly |
| Global `include_directories`, `add_definitions` | Leaks to all targets | `target_*` commands |
| `link_directories(...)` | Order-dependent, fragile | `target_link_libraries(... <imported target>)` |
| In-source build | Pollutes repo | Out-of-source: `cmake -S . -B build` |
| Hard-coded compiler flags | Breaks on other compilers | Generator expressions per `CXX_COMPILER_ID` |
| `set(CMAKE_BUILD_TYPE Release)` in CMakeLists | Overrides user choice | Set in preset or via `-DCMAKE_BUILD_TYPE=` |
| Copying `.cmake` files instead of `find_package` config mode | Versions drift | Install + export targets, consume with config-mode `find_package` |

## Common Commands

```bash
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
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.