Claude Skill

cmake

Use when writing CMakeLists.txt, out-of-source builds, target_link_libraries, target properties, find_package/FetchContent, toolchain files, CPack, CMake presets, or cmake configure errors.

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download outlinedriven-outline-driven-development-.devin_skills_cmake-b0e8ce8.zip · 4 KB
Part of outlinedriven/outline-driven-development — 145 skills

Install

skills CLI npx skills add https://github.com/OutlineDriven/outline-driven-development/tree/main/.devin/skills/cmake
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install outlinedriven-outline-driven-development@llmmart
Git git clone https://github.com/OutlineDriven/outline-driven-development.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole outlinedriven/outline-driven-development collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

CMake

Modern target-first CMake for C/C++ projects. Grounded against CMake 4.4.3; the examples floor at CMake 3.25 so the preset schema version 6 works.

Contract

Field Bound contract
Trigger The task writes or refactors CMakeLists.txt, configures out-of-source builds, selects generators, manages targets with target_link_libraries, integrates packages via find_package or FetchContent, enables sanitizers, writes toolchain files, sets up presets, or resolves a cmake configure error.
Authority Reversible local: writes only CMakeLists.txt, CMakePresets.json, toolchain files, and the build directory; rollback is version control plus deleting the build directory. No remote mutation.
Side effect cmake --build and cmake --install write local build outputs and install trees; FetchContent downloads declared dependencies.
Done The project configures and builds with the requested options, or the failing command and its error are reported.

Inputs

  • Project layout (required): sources, headers, and where the root CMakeLists.txt lives.
  • CMake version (required if not inferrable): run cmake --version. Preset schema version 6 needs CMake 3.25 or newer.
  • Dependencies (optional): system packages, FetchContent sources, or vendored trees.
  • Target platform (optional): a cross-compilation target needs a toolchain file.

Procedure

  1. Apply modern CMake rules. Define targets, not variables. Use target_* commands with PUBLIC/PRIVATE/INTERFACE to control propagation. Never use include_directories() or link_libraries(); they are legacy global state. Done when: every property attaches to a target.

  2. Write the minimal project. Done when: cmake -S . -B build configures cleanly.

cmake_minimum_required(VERSION 3.25)
project(MyApp VERSION 1.0 LANGUAGES C CXX)

set(CMAKE_C_STANDARD 23)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)   # clang-tidy and IDEs read this

add_executable(myapp src/main.c src/utils.c)
target_include_directories(myapp PRIVATE include)
target_compile_options(myapp PRIVATE -Wall -Wextra)
  1. Add libraries and link them. Done when: each library target carries its own include paths and the executable links against it.
add_library(mylib STATIC lib/foo.c lib/bar.c)
target_include_directories(mylib
    PUBLIC  include    # consumers inherit this
    PRIVATE src        # only mylib sees this
)

add_library(myshared SHARED lib/foo.c)
set_target_properties(myshared PROPERTIES VERSION 1.0.0 SOVERSION 1)

target_link_libraries(myapp PRIVATE mylib)
  1. Configure and build out of source. Done when: the build completes in a separate directory.
cmake -S . -B build -G Ninja
cmake --build build -- -j"$(nproc)"

cmake -S . -B build-debug   -DCMAKE_BUILD_TYPE=Debug
cmake -S . -B build-release -DCMAKE_BUILD_TYPE=Release
cmake --install build-release --prefix /usr/local

Build types: Debug, Release, RelWithDebInfo, MinSizeRel.

  1. Integrate external dependencies. Prefer find_package for system libraries, FetchContent for source builds, pkg_check_modules as a fallback. Done when: the dependency resolves and links.
find_package(OpenSSL REQUIRED)
find_package(Threads REQUIRED)
find_package(ZLIB REQUIRED)
target_link_libraries(myapp PRIVATE OpenSSL::SSL OpenSSL::Crypto Threads::Threads ZLIB::ZLIB)

include(FetchContent)
FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        v1.17.0
    GIT_SHALLOW    TRUE
)
FetchContent_MakeAvailable(googletest)

find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBFOO REQUIRED libfoo>=1.2)
target_link_libraries(myapp PRIVATE ${LIBFOO_LIBRARIES})
target_include_directories(myapp PRIVATE ${LIBFOO_INCLUDE_DIRS})
  1. Set per-configuration flags with generator expressions. Done when: each flag applies only to its intended configuration or compiler.
target_compile_options(myapp PRIVATE
    $<$<CONFIG:Debug>:-g -Og -fsanitize=address>
    $<$<CONFIG:Release>:-O2 -DNDEBUG>
    $<$<CXX_COMPILER_ID:GNU>:-fanalyzer>
)
target_link_options(myapp PRIVATE
    $<$<CONFIG:Debug>:-fsanitize=address>
)
  1. Gate sanitizers behind an option. Done when: cmake -DENABLE_ASAN=ON produces an instrumented build.
option(ENABLE_ASAN "Enable AddressSanitizer" OFF)
if(ENABLE_ASAN)
    target_compile_options(myapp PRIVATE -fsanitize=address -fno-omit-frame-pointer -g -O1)
    target_link_options(myapp PRIVATE -fsanitize=address)
endif()
  1. Write a toolchain file for cross-compilation. Done when: cmake -DCMAKE_TOOLCHAIN_FILE=... configures for the target.
# toolchain-aarch64.cmake
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER   aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_SYSROOT /opt/aarch64-sysroot)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
  1. Capture common configurations in CMakePresets.json. Schema version 6 requires CMake 3.25 or newer. Done when: cmake --preset <name> configures and cmake --build --preset <name> builds.
{
  "version": 6,
  "configurePresets": [
    {
      "name": "release",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build/release",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release",
        "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
      }
    },
    {
      "name": "debug",
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build/debug",
      "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "ENABLE_ASAN": "ON" }
    }
  ],
  "buildPresets": [
    { "name": "release", "configurePreset": "release" },
    { "name": "debug",   "configurePreset": "debug" }
  ]
}
  1. Diagnose configure errors against this table. Done when: the error maps to a cause and a fix.
Error Cause Fix
Could not find package Foo Package missing or wrong prefix Install the dev package; set CMAKE_PREFIX_PATH
No CMAKE_CXX_COMPILER No C++ compiler found Install g++ or clang++; check PATH
target_link_libraries called with wrong number of arguments Missing PUBLIC/PRIVATE/INTERFACE Add the keyword
Cannot find source file Typo or wrong relative path Check the path relative to CMakeLists.txt
Compatibility error on old cmake_minimum_required CMake 4 dropped compatibility with versions below 3.5 Raise the floor to 3.25

For complete project templates see references/templates.md.

Failure and recovery

  • find_package fails: install the -dev package or set CMAKE_PREFIX_PATH; fall back to FetchContent when no system package exists.
  • FetchContent fails offline: pre-seed FETCHCONTENT_SOURCE_DIR_<NAME> with a local copy.
  • Generator expression error: check the expression name against cmake --help-manual cmake-generator-expressions.
  • Preset rejected: confirm cmake --version meets the schema version's floor.
  • Stale cache after option changes: delete the build directory or pass -U to clear a cache entry; do not edit CMakeCache.txt by hand.

Output

A working CMakeLists.txt or build configuration, verified by a successful cmake -S . -B build and cmake --build build. For debugging tasks, the diagnosed error with its cause and applied fix.

Files (outline-driven-development)
  • agents
    • openai.yaml 291 B
      interface:
        display_name: "Cmake"
        short_description: "Use when writing CMakeLists.txt, out-of-source builds, target_link_libraries, target properties, find_package/FetchContent, toolchain files, CPack, CMake presets, or cmake configure errors."
      policy:
        allow_implicit_invocation: false
      
  • references
    • templates.md 3.2 KB
      # CMake project templates
      
      Floors at CMake 3.25 so preset schema version 6 and current commands apply.
      Standards follow the repo floor: C23 and C++23.
      
      ## Minimal C library plus executable
      
      ```text
      myproject/
      ├── CMakeLists.txt
      ├── include/mylib/mylib.h
      ├── src/mylib.c
      ├── src/main.c
      └── test/test_mylib.c
      ```
      
      ```cmake
      cmake_minimum_required(VERSION 3.25)
      project(MyProject VERSION 1.0 LANGUAGES C)
      
      set(CMAKE_C_STANDARD 23)
      set(CMAKE_C_STANDARD_REQUIRED ON)
      set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
      
      add_library(mylib STATIC src/mylib.c)
      target_include_directories(mylib PUBLIC include)
      target_compile_options(mylib PRIVATE -Wall -Wextra)
      
      add_executable(myapp src/main.c)
      target_link_libraries(myapp PRIVATE mylib)
      
      enable_testing()
      add_executable(test_mylib test/test_mylib.c)
      target_link_libraries(test_mylib PRIVATE mylib)
      add_test(NAME mylib_tests COMMAND test_mylib)
      
      install(TARGETS myapp RUNTIME DESTINATION bin)
      install(TARGETS mylib ARCHIVE DESTINATION lib)
      install(DIRECTORY include/ DESTINATION include)
      ```
      
      ## C++ project with GoogleTest via FetchContent
      
      ```cmake
      cmake_minimum_required(VERSION 3.25)
      project(MyProject VERSION 1.0 LANGUAGES CXX)
      
      set(CMAKE_CXX_STANDARD 23)
      set(CMAKE_CXX_STANDARD_REQUIRED ON)
      
      add_library(mylib STATIC src/engine.cpp src/parser.cpp)
      target_include_directories(mylib PUBLIC include PRIVATE src)
      target_compile_options(mylib PRIVATE
          -Wall -Wextra
          $<$<CONFIG:Debug>:-g -Og>
          $<$<CONFIG:Release>:-O2 -DNDEBUG>
      )
      
      add_executable(myapp src/main.cpp)
      target_link_libraries(myapp PRIVATE mylib)
      
      include(FetchContent)
      FetchContent_Declare(
          googletest
          GIT_REPOSITORY https://github.com/google/googletest.git
          GIT_TAG        v1.17.0
          GIT_SHALLOW    TRUE
      )
      set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
      FetchContent_MakeAvailable(googletest)
      
      enable_testing()
      add_executable(unit_tests test/test_engine.cpp test/test_parser.cpp)
      target_link_libraries(unit_tests PRIVATE mylib GTest::gtest_main)
      include(GoogleTest)
      gtest_discover_tests(unit_tests)
      ```
      
      ## Sanitizer option pattern
      
      ```cmake
      option(SANITIZE_ADDRESS   "Enable ASan"  OFF)
      option(SANITIZE_THREAD    "Enable TSan"  OFF)
      option(SANITIZE_UNDEFINED "Enable UBSan" OFF)
      
      set(SANITIZER_FLAGS "")
      if(SANITIZE_ADDRESS)
          list(APPEND SANITIZER_FLAGS -fsanitize=address -fno-omit-frame-pointer)
      endif()
      if(SANITIZE_THREAD)
          list(APPEND SANITIZER_FLAGS -fsanitize=thread)
      endif()
      if(SANITIZE_UNDEFINED)
          list(APPEND SANITIZER_FLAGS -fsanitize=undefined)
      endif()
      
      if(SANITIZER_FLAGS)
          add_compile_options(${SANITIZER_FLAGS})
          add_link_options(${SANITIZER_FLAGS})
      endif()
      ```
      
      ASan and TSan are mutually exclusive; do not enable both in one build.
      
      ## Dependency management patterns
      
      System package with a FetchContent fallback:
      
      ```cmake
      find_package(ZLIB QUIET)
      if(NOT ZLIB_FOUND)
          include(FetchContent)
          FetchContent_Declare(zlib
              GIT_REPOSITORY https://github.com/madler/zlib.git
              GIT_TAG        v1.3.1
          )
          FetchContent_MakeAvailable(zlib)
          set(ZLIB_TARGET zlibstatic)
      else()
          set(ZLIB_TARGET ZLIB::ZLIB)
      endif()
      target_link_libraries(myapp PRIVATE ${ZLIB_TARGET})
      ```
      
      Vendored in-tree library:
      
      ```cmake
      add_subdirectory(third_party/json)
      target_link_libraries(myapp PRIVATE nlohmann_json::nlohmann_json)
      ```
      
  • SKILL.md 7.6 KB
    ---
    name: cmake
    description: 'Use when writing CMakeLists.txt, out-of-source builds, target_link_libraries, target properties, find_package/FetchContent, toolchain files, CPack, CMake presets, or cmake configure errors.'
    disable-model-invocation: true
    ---
    
    # CMake
    
    Modern target-first CMake for C/C++ projects. Grounded against CMake 4.4.3; the examples floor at CMake 3.25 so the preset schema version 6 works.
    
    ## Contract
    
    | Field | Bound contract |
    |---|---|
    | Trigger | The task writes or refactors `CMakeLists.txt`, configures out-of-source builds, selects generators, manages targets with `target_link_libraries`, integrates packages via `find_package` or `FetchContent`, enables sanitizers, writes toolchain files, sets up presets, or resolves a cmake configure error. |
    | Authority | Reversible local: writes only `CMakeLists.txt`, `CMakePresets.json`, toolchain files, and the build directory; rollback is version control plus deleting the build directory. No remote mutation. |
    | Side effect | `cmake --build` and `cmake --install` write local build outputs and install trees; `FetchContent` downloads declared dependencies. |
    | Done | The project configures and builds with the requested options, or the failing command and its error are reported. |
    
    ## Inputs
    
    - Project layout (required): sources, headers, and where the root `CMakeLists.txt` lives.
    - CMake version (required if not inferrable): run `cmake --version`. Preset schema version 6 needs CMake 3.25 or newer.
    - Dependencies (optional): system packages, FetchContent sources, or vendored trees.
    - Target platform (optional): a cross-compilation target needs a toolchain file.
    
    ## Procedure
    
    1. Apply modern CMake rules. Define targets, not variables. Use `target_*` commands with `PUBLIC`/`PRIVATE`/`INTERFACE` to control propagation. Never use `include_directories()` or `link_libraries()`; they are legacy global state. Done when: every property attaches to a target.
    
    2. Write the minimal project. Done when: `cmake -S . -B build` configures cleanly.
    
    ```cmake
    cmake_minimum_required(VERSION 3.25)
    project(MyApp VERSION 1.0 LANGUAGES C CXX)
    
    set(CMAKE_C_STANDARD 23)
    set(CMAKE_C_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_STANDARD 23)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_EXPORT_COMPILE_COMMANDS ON)   # clang-tidy and IDEs read this
    
    add_executable(myapp src/main.c src/utils.c)
    target_include_directories(myapp PRIVATE include)
    target_compile_options(myapp PRIVATE -Wall -Wextra)
    ```
    
    3. Add libraries and link them. Done when: each library target carries its own include paths and the executable links against it.
    
    ```cmake
    add_library(mylib STATIC lib/foo.c lib/bar.c)
    target_include_directories(mylib
        PUBLIC  include    # consumers inherit this
        PRIVATE src        # only mylib sees this
    )
    
    add_library(myshared SHARED lib/foo.c)
    set_target_properties(myshared PROPERTIES VERSION 1.0.0 SOVERSION 1)
    
    target_link_libraries(myapp PRIVATE mylib)
    ```
    
    4. Configure and build out of source. Done when: the build completes in a separate directory.
    
    ```bash
    cmake -S . -B build -G Ninja
    cmake --build build -- -j"$(nproc)"
    
    cmake -S . -B build-debug   -DCMAKE_BUILD_TYPE=Debug
    cmake -S . -B build-release -DCMAKE_BUILD_TYPE=Release
    cmake --install build-release --prefix /usr/local
    ```
    
    Build types: `Debug`, `Release`, `RelWithDebInfo`, `MinSizeRel`.
    
    5. Integrate external dependencies. Prefer `find_package` for system libraries, `FetchContent` for source builds, `pkg_check_modules` as a fallback. Done when: the dependency resolves and links.
    
    ```cmake
    find_package(OpenSSL REQUIRED)
    find_package(Threads REQUIRED)
    find_package(ZLIB REQUIRED)
    target_link_libraries(myapp PRIVATE OpenSSL::SSL OpenSSL::Crypto Threads::Threads ZLIB::ZLIB)
    
    include(FetchContent)
    FetchContent_Declare(
        googletest
        GIT_REPOSITORY https://github.com/google/googletest.git
        GIT_TAG        v1.17.0
        GIT_SHALLOW    TRUE
    )
    FetchContent_MakeAvailable(googletest)
    
    find_package(PkgConfig REQUIRED)
    pkg_check_modules(LIBFOO REQUIRED libfoo>=1.2)
    target_link_libraries(myapp PRIVATE ${LIBFOO_LIBRARIES})
    target_include_directories(myapp PRIVATE ${LIBFOO_INCLUDE_DIRS})
    ```
    
    6. Set per-configuration flags with generator expressions. Done when: each flag applies only to its intended configuration or compiler.
    
    ```cmake
    target_compile_options(myapp PRIVATE
        $<$<CONFIG:Debug>:-g -Og -fsanitize=address>
        $<$<CONFIG:Release>:-O2 -DNDEBUG>
        $<$<CXX_COMPILER_ID:GNU>:-fanalyzer>
    )
    target_link_options(myapp PRIVATE
        $<$<CONFIG:Debug>:-fsanitize=address>
    )
    ```
    
    7. Gate sanitizers behind an option. Done when: `cmake -DENABLE_ASAN=ON` produces an instrumented build.
    
    ```cmake
    option(ENABLE_ASAN "Enable AddressSanitizer" OFF)
    if(ENABLE_ASAN)
        target_compile_options(myapp PRIVATE -fsanitize=address -fno-omit-frame-pointer -g -O1)
        target_link_options(myapp PRIVATE -fsanitize=address)
    endif()
    ```
    
    8. Write a toolchain file for cross-compilation. Done when: `cmake -DCMAKE_TOOLCHAIN_FILE=...` configures for the target.
    
    ```cmake
    # toolchain-aarch64.cmake
    set(CMAKE_SYSTEM_NAME Linux)
    set(CMAKE_SYSTEM_PROCESSOR aarch64)
    set(CMAKE_C_COMPILER   aarch64-linux-gnu-gcc)
    set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
    set(CMAKE_SYSROOT /opt/aarch64-sysroot)
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
    ```
    
    9. Capture common configurations in `CMakePresets.json`. Schema version 6 requires CMake 3.25 or newer. Done when: `cmake --preset <name>` configures and `cmake --build --preset <name>` builds.
    
    ```json
    {
      "version": 6,
      "configurePresets": [
        {
          "name": "release",
          "generator": "Ninja",
          "binaryDir": "${sourceDir}/build/release",
          "cacheVariables": {
            "CMAKE_BUILD_TYPE": "Release",
            "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
          }
        },
        {
          "name": "debug",
          "generator": "Ninja",
          "binaryDir": "${sourceDir}/build/debug",
          "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug", "ENABLE_ASAN": "ON" }
        }
      ],
      "buildPresets": [
        { "name": "release", "configurePreset": "release" },
        { "name": "debug",   "configurePreset": "debug" }
      ]
    }
    ```
    
    10. Diagnose configure errors against this table. Done when: the error maps to a cause and a fix.
    
    | Error | Cause | Fix |
    |---|---|---|
    | `Could not find package Foo` | Package missing or wrong prefix | Install the dev package; set `CMAKE_PREFIX_PATH` |
    | `No CMAKE_CXX_COMPILER` | No C++ compiler found | Install g++ or clang++; check `PATH` |
    | `target_link_libraries called with wrong number of arguments` | Missing `PUBLIC`/`PRIVATE`/`INTERFACE` | Add the keyword |
    | `Cannot find source file` | Typo or wrong relative path | Check the path relative to `CMakeLists.txt` |
    | Compatibility error on old `cmake_minimum_required` | CMake 4 dropped compatibility with versions below 3.5 | Raise the floor to 3.25 |
    
    For complete project templates see `references/templates.md`.
    
    ## Failure and recovery
    
    - `find_package` fails: install the `-dev` package or set `CMAKE_PREFIX_PATH`; fall back to `FetchContent` when no system package exists.
    - FetchContent fails offline: pre-seed `FETCHCONTENT_SOURCE_DIR_<NAME>` with a local copy.
    - Generator expression error: check the expression name against `cmake --help-manual cmake-generator-expressions`.
    - Preset rejected: confirm `cmake --version` meets the schema version's floor.
    - Stale cache after option changes: delete the build directory or pass `-U` to clear a cache entry; do not edit `CMakeCache.txt` by hand.
    
    ## Output
    
    A working `CMakeLists.txt` or build configuration, verified by a successful `cmake -S . -B build` and `cmake --build build`. For debugging tasks, the diagnosed error with its cause and applied fix.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related