cmake
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCMake
CMake
Purpose
用途
Guide agents through modern (target-first) CMake for C/C++ projects: out-of-source builds, dependency management, generator selection, and integration with CI and IDEs.
指导Agent为C/C++项目使用现代的(以目标为核心的)CMake:实现源码外构建、依赖管理、生成器选择,以及与CI和IDE的集成。
Triggers
触发场景
- "How do I write a CMakeLists.txt for my project?"
- "How do I add an external library with CMake?"
- "CMake can't find my package / library"
- "How do I enable sanitizers in CMake?"
- "How do I cross-compile with CMake?"
- "How do I use CMake Presets?"
- "我该如何为项目编写CMakeLists.txt?"
- "怎么用CMake添加外部库?"
- "CMake找不到我的包/库"
- "怎么在CMake中启用sanitizers?"
- "怎么用CMake进行交叉编译?"
- "怎么使用CMake Presets?"
Workflow
工作流程
1. Modern CMake principles
1. 现代CMake原则
- Define targets, not variables. Use commands.
target_* - Use /
PUBLIC/PRIVATEto control property propagation.INTERFACE - Never use or
include_directories()(legacy).link_libraries() - Minimum CMake version: for most features.
cmake_minimum_required(VERSION 3.20)
- 定义目标而非变量,优先使用系列命令。
target_* - 使用/
PUBLIC/PRIVATE控制属性的传播范围。INTERFACE - 不要使用或
include_directories()(属于遗留用法)。link_libraries() - 最低CMake版本要求:大多数功能需要
cmake_minimum_required(VERSION 3.20)
2. Minimal project
2. 最小项目示例
cmake
cmake_minimum_required(VERSION 3.20)
project(MyApp VERSION 1.0 LANGUAGES C CXX)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(myapp
src/main.c
src/utils.c
)
target_include_directories(myapp PRIVATE include)
target_compile_options(myapp PRIVATE -Wall -Wextra)cmake
cmake_minimum_required(VERSION 3.20)
project(MyApp VERSION 1.0 LANGUAGES C CXX)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(myapp
src/main.c
src/utils.c
)
target_include_directories(myapp PRIVATE include)
target_compile_options(myapp PRIVATE -Wall -Wextra)3. Static / shared libraries
3. 静态/共享库配置
cmake
undefinedcmake
undefinedStatic library
静态库
add_library(mylib STATIC lib/foo.c lib/bar.c)
target_include_directories(mylib
PUBLIC include # consumers get this include path
PRIVATE src # only mylib itself sees this
)
add_library(mylib STATIC lib/foo.c lib/bar.c)
target_include_directories(mylib
PUBLIC include # 依赖该库的目标可访问这个头文件路径
PRIVATE src # 仅mylib自身可访问该路径
)
Shared library
共享库
add_library(myshared SHARED lib/foo.c)
set_target_properties(myshared PROPERTIES
VERSION 1.0.0
SOVERSION 1
)
add_library(myshared SHARED lib/foo.c)
set_target_properties(myshared PROPERTIES
VERSION 1.0.0
SOVERSION 1
)
Link executable against library
将可执行文件与库链接
add_executable(myapp src/main.c)
target_link_libraries(myapp PRIVATE mylib)
undefinedadd_executable(myapp src/main.c)
target_link_libraries(myapp PRIVATE mylib)
undefined4. Configure and build
4. 配置与构建
bash
undefinedbash
undefinedOut-of-source build (always do this)
源码外构建(推荐始终使用该方式)
cmake -S . -B build
cmake --build build
cmake -S . -B build
cmake --build build
With generator
指定生成器
cmake -S . -B build -G Ninja
cmake --build build -- -j$(nproc)
cmake -S . -B build -G Ninja
cmake --build build -- -j$(nproc)
Debug build
Debug构建
cmake -S . -B build-debug -DCMAKE_BUILD_TYPE=Debug
cmake --build build-debug
cmake -S . -B build-debug -DCMAKE_BUILD_TYPE=Debug
cmake --build build-debug
Release
Release构建
cmake -S . -B build-release -DCMAKE_BUILD_TYPE=Release
cmake --build build-release
cmake -S . -B build-release -DCMAKE_BUILD_TYPE=Release
cmake --build build-release
Install
安装
cmake --install build --prefix /usr/local
Build types: `Debug`, `Release`, `RelWithDebInfo`, `MinSizeRel`.cmake --install build --prefix /usr/local
构建类型:`Debug`、`Release`、`RelWithDebInfo`、`MinSizeRel`。5. External dependencies
5. 外部依赖管理
find_package (system-installed libraries)
find_package(系统已安装的库)
cmake
find_package(OpenSSL REQUIRED)
target_link_libraries(myapp PRIVATE OpenSSL::SSL OpenSSL::Crypto)
find_package(Threads REQUIRED)
target_link_libraries(myapp PRIVATE Threads::Threads)
find_package(ZLIB REQUIRED)
target_link_libraries(myapp PRIVATE ZLIB::ZLIB)cmake
find_package(OpenSSL REQUIRED)
target_link_libraries(myapp PRIVATE OpenSSL::SSL OpenSSL::Crypto)
find_package(Threads REQUIRED)
target_link_libraries(myapp PRIVATE Threads::Threads)
find_package(ZLIB REQUIRED)
target_link_libraries(myapp PRIVATE ZLIB::ZLIB)FetchContent (download and build dependency)
FetchContent(下载并构建依赖)
cmake
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
FetchContent_MakeAvailable(googletest)
add_executable(mytest test/test_foo.cpp)
target_link_libraries(mytest PRIVATE GTest::gtest_main mylib)cmake
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
FetchContent_MakeAvailable(googletest)
add_executable(mytest test/test_foo.cpp)
target_link_libraries(mytest PRIVATE GTest::gtest_main mylib)pkg-config fallback
pkg-config备选方案
cmake
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})cmake
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. Compiler options by configuration
6. 按构建配置设置编译器选项
cmake
target_compile_options(myapp PRIVATE
$<$<CONFIG:Debug>:-g -Og -fsanitize=address>
$<$<CONFIG:Release>:-O2 -DNDEBUG>
$<$<CXX_COMPILER_ID:GNU>:-fanalyzer>
$<$<CXX_COMPILER_ID:Clang>:-Weverything>
)
target_link_options(myapp PRIVATE
$<$<CONFIG:Debug>:-fsanitize=address>
)Generator expressions: evaluated at build time.
$<condition:value>cmake
target_compile_options(myapp PRIVATE
$<$<CONFIG:Debug>:-g -Og -fsanitize=address>
$<$<CONFIG:Release>:-O2 -DNDEBUG>
$<$<CXX_COMPILER_ID:GNU>:-fanalyzer>
$<$<CXX_COMPILER_ID:Clang>:-Weverything>
)
target_link_options(myapp PRIVATE
$<$<CONFIG:Debug>:-fsanitize=address>
)生成器表达式:会在构建阶段进行求值。
$<condition:value>7. Enable sanitizers
7. 启用sanitizers
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()Build:
cmake -DENABLE_ASAN=ON -S . -B build-asan && cmake --build build-asancmake
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()构建命令:
cmake -DENABLE_ASAN=ON -S . -B build-asan && cmake --build build-asan8. Cross-compilation toolchain file
8. 交叉编译工具链文件
cmake
undefinedcmake
undefinedtoolchain-aarch64.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)
```bash
cmake -S . -B build-arm -DCMAKE_TOOLCHAIN_FILE=toolchain-aarch64.cmakeset(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)
```bash
cmake -S . -B build-arm -DCMAKE_TOOLCHAIN_FILE=toolchain-aarch64.cmake9. CMake Presets (CMake 3.20+)
9. CMake Presets(CMake 3.20及以上版本支持)
json
{
"version": 6,
"configurePresets": [
{
"name": "release",
"displayName": "Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
},
{
"name": "debug",
"displayName": "Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"ENABLE_ASAN": "ON"
}
}
],
"buildPresets": [
{ "name": "release", "configurePreset": "release" },
{ "name": "debug", "configurePreset": "debug" }
]
}bash
cmake --preset release
cmake --build --preset releasejson
{
"version": 6,
"configurePresets": [
{
"name": "release",
"displayName": "Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
},
{
"name": "debug",
"displayName": "Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"ENABLE_ASAN": "ON"
}
}
],
"buildPresets": [
{ "name": "release", "configurePreset": "release" },
{ "name": "debug", "configurePreset": "debug" }
]
}bash
cmake --preset release
cmake --build --preset release10. Common errors
10. 常见错误
| Error | Cause | Fix |
|---|---|---|
| Package not installed or wrong prefix | Install dev package; set |
| No C++ compiler found | Install g++/clang++; check PATH |
| Missing | Add the keyword |
| Typo or wrong relative path | Check path relative to |
| Wrong | Check CMake docs for expression name |
For a complete CMakeLists.txt template, see references/templates.md.
| 错误 | 原因 | 解决方法 |
|---|---|---|
| 依赖包未安装或前缀路径错误 | 安装对应开发包;设置 |
| 未找到C++编译器 | 安装g++/clang++;检查PATH环境变量 |
| 缺少 | 补充对应的访问控制关键字 |
| 文件名拼写错误或相对路径错误 | 检查相对于当前 |
| | 查阅CMake官方文档确认表达式的正确写法 |
完整的CMakeLists.txt模板可参考references/templates.md。
Related skills
相关技能
- Use for Ninja generator details
skills/build-systems/ninja - Use for Make generator
skills/build-systems/make - Use for cross-compilation toolchain setup
skills/compilers/cross-gcc - Use for sanitizer integration details
skills/runtimes/sanitizers
- 如需了解Ninja生成器的详细用法,可使用技能
skills/build-systems/ninja - 如需了解Make生成器的详细用法,可使用技能
skills/build-systems/make - 如需了解交叉编译工具链的配置方法,可使用技能
skills/compilers/cross-gcc - 如需了解sanitizer集成的详细信息,可使用技能
skills/runtimes/sanitizers