CMake
SkillFiles & storageUse 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.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the CMake skill
What this skill tells your AI
The instructions your AI receives, as published by outlinedriven/outline-driven-development in .devin/skills/cmake/SKILL.md and read by ahel’s review.
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.txtlives. - 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
-
Apply modern CMake rules. Define targets, not variables. Use
target_*commands withPUBLIC/PRIVATE/INTERFACEto control propagation. Never useinclude_directories()orlink_libraries(); they are legacy global state. Done when: every property attaches to a target. -
Write the minimal project. Done when:
cmake -S . -B buildconfigures 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)
- 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)
- 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.
- Integrate external dependencies. Prefer
find_packagefor system libraries,FetchContentfor source builds,pkg_check_modulesas 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})
- 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>
)
- Gate sanitizers behind an option. Done when:
cmake -DENABLE_ASAN=ONproduces 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()
- 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)
- Capture common configurations in
CMakePresets.json. Schema version 6 requires CMake 3.25 or newer. Done when:cmake --preset <name>configures andcmake --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" }
]
}
- 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_packagefails: install the-devpackage or setCMAKE_PREFIX_PATH; fall back toFetchContentwhen 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 --versionmeets the schema version's floor. - Stale cache after option changes: delete the build directory or pass
-Uto clear a cache entry; do not editCMakeCache.txtby 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.
Signals
- GitHub stars
- 52
- Forks
- 9
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
cmake-outlinedriven- Source
- github.com/outlinedriven/outline-driven-development