## 概述
- 目标:用现代 CMake 设计清晰的目标与依赖关系,统一构建入口,降低平台差异带来的复杂度。
- 价值:摆脱旧式全局变量与手工包含路径,采用“目标为中心”的属性与链接模型,实现模块化与可复用。
## 技术参数与环境
- CMake 版本:建议 `>= 3.21`(完整支持 `CMakePresets.json`;`FetchContent` 自 3.11 可用)。
- 语言标准:`C++20`(通过目标属性启用)。
- 生成器:`Ninja` 或平台默认(MSVC、Makefiles)。
- 平台:Windows(MSVC/Clang)、Linux(GCC/Clang)、macOS(Apple Clang)。
## 基础项目结构
project-root/
CMakeLists.txt
CMakePresets.json
src/
main.cpp
lib/
CMakeLists.txt
mylib.hpp
mylib.cpp
## 顶层 CMakeLists(目标为中心)
cmake_minimum_required(VERSION 3.21)
project(modern_cmake LANGUAGES CXX)
add_subdirectory(lib)
add_executable(app src/main.cpp)
target_compile_features(app PRIVATE cxx_std_20)
target_link_libraries(app PRIVATE mylib fmt::fmt)
### 库目标定义(lib/CMakeLists.txt)
add_library(mylib STATIC mylib.cpp)
target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_features(mylib PUBLIC cxx_std_20)
include(FetchContent)
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 11.0.2
)
FetchContent_MakeAvailable(fmt)
target_link_libraries(mylib PUBLIC fmt::fmt)
### 示例源码
// src/main.cpp
#include "mylib.hpp"
int main() {
run_demo();
}
// lib/mylib.hpp
#pragma once
void run_demo();
// lib/mylib.cpp
#include <fmt/format.h>
void run_demo() {
fmt::print("Hello Modern CMake\\n");
}
## 统一入口:CMakePresets.json
{
"version": 6,
"configurePresets": [
{
"name": "default",
"generator": "Ninja",
"binaryDir": "build",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
],
"buildPresets": [
{ "name": "default", "configurePreset": "default" }
]
}
说明:使用 Presets 可在不同环境下复用相同的配置与构建入口,避免脚本分叉。
## 构建与运行
- 通用命令:
cmake --preset default
cmake --build --preset default
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
## 依赖管理策略
- 优先使用“目标”为单位的链接:`target_link_libraries(app PRIVATE mylib)`。
- 第三方库优先 `find_package(... CONFIG REQUIRED)`,如有困难再用 `FetchContent` 引入源代码。
- 为公共 API 暴露头文件目录:`target_include_directories(mylib PUBLIC ...)`;实现细节用 `PRIVATE`。
- 版本锁定:为 `FetchContent` 指定稳定 `GIT_TAG`,以保证可重复构建。
## 跨平台要点
- Windows/MSVC:默认生成器即可;或 `Ninja` 配合 MSVC 编译工具链。
- Linux:GCC/Clang 均可;确保安装 `ninja-build` 包。
- macOS:Apple Clang;`xcode-select --install`;可选择 `Ninja` 或 `Xcode` 生成器。
## 常见问题与解法
- 全局变量与 `include_directories()` 造成污染:改用目标属性与 `target_include_directories()`。
- 手工拷贝依赖:用 `find_package` 或 `FetchContent`;保持单一真实来源。
- Debug/Release 配置不一致:收敛到 Presets,统一入口与输出目录。
## 注意事项(发布规范)
- 关键词需与正文高度相关:`CMake`、`Presets`、`FetchContent`、目标属性。
- 分类匹配:`C-C++`。
- 描述准确概括核心价值:现代实践 + 可维护架构 + 依赖管理。
- 技术参数已验证:CMake 3.21+ 的 Presets、FetchContent、目标属性在主流平台支持良好。
- 文件名与标题一致:`现代CMake实践:可维护跨平台工程与包管理.md`。
---
采用现代 CMake 能显著提升工程可维护性与跨平台一致性。通过目标中心的设计与 Presets 的统一入口,团队可在不同平台快速复现一致的构建与依赖配置。

发表评论 取消回复