简介:CMake 3.28.6 的 Windows x86_64 文档资源包,面向需要在 Windows 平台配置构建流程、编写 CMakeLists 或调试构建脚本的开发者与运维人员。资源以官方 3.28.6 版本文档为蓝本,压缩包共 2000 个文件,包含 1171 个 txt 文本与 829 个 html 页面;txt 文件多用于保存命令行参考、配置项说明和快速查阅手册,html 页面则覆盖生成器表达式、ctest 测试框架、cmake-presets 预设、构建系统模型、变量字典等核心主题。文件整体体积为 43.06MB,容量适中,适合离线收藏与本地浏览器检索。内容预览中出现 genindex 索引以及 cmake-generator-expressions、ctest、cmake-buildsystem 等关键文档,便于按需定位具体章节,也能帮助读者快速了解 3.28.6 版本的文档结构与功能脉络。目前已有 397 人学习下载,对于希望系统掌握 CMake 构建机制、排查常见配置错误或升级到新版特性的开发者,这份离线文档能提供直接的参考价值,无论是初学者还是有一定经验的用户,都能缩短查阅与排错时间。
1. 一份能当离线手册用的 CMake 3.28.6 Windows x86_64 发行包
搜 cmake 下载时最容易看到这个名字:cmake-3.28.6-windows-x86_64.zip。它解决的不是“装个最新版”的问题,而是换机器、换 VS 版本、换构建目录之后,构建脚本大面积失灵的问题。这个包是 CMake 官方在 Windows x86_64 下的免安装发行包,解压即用,bin 里有 cmake.exe、ctest.exe、cpack.exe,doc 目录还带着一整份和版本一一对应的官方 HTML 手册——buildsystem、generator expressions、variables、presets、file-api 全在里面,断网也能查。适合维护跨平台 C++ 项目、需要在 IDE 与 CI 之间反复切换、又不想被安装器写注册表的人。下面对照着拆包顺序,把版本机理、路径规划、命令行用法和踩坑记录一次讲完。
2. 先把版本机理说透:生成器、变量与文件 API 决定你怎么用
2.1 从文档清单看这份包的完整度
项目正文里那串 html 文件,对应的是解压后 doc/cmake-3.28/html 目录下的官方手册。index.html 是总入口,cmake-buildsystem.7.html 讲构建系统里的 target、directory、command 是怎么组织的,cmake-generator-expressions.7.html 是$<...>语法的完整参考,cmake-variables.7.html 覆盖所有内置变量,cmake-presets.7.html 规定 CMakePresets.json 的字段格式,cmake-file-api.7.html 说明 IDE 如何通过 JSON 查询构建系统,cmake.1.html 和 ctest.1.html 分别是两个命令行工具的手册,连 cpack 的 rpm.html 生成器文档都在。
这意味着遇到生成器表达式报错、变量作用域不清、presets 写错 key 这类问题,直接打开本地文档就能查原文。3.28 之后的版本行为变更很密集,很多老博客的结论已经失效,而这份文档与二进制同版本,可信度远高于搜索引擎里的二手答案。所以我把这包定位为“带手册的构建工具”,不只是丢几个 exe 完事。
2.2 单配置与多配置生成器:最影响命令的参数
Windows 下最常用的生成器分成两类,行为差异直接决定命令怎么写。Visual Studio 17 2022、Xcode、Ninja Multi-Config 属于多配置生成器,一个构建目录里同时存在 Debug、Release、RelWithDebInfo 多套编译参数,构建阶段用--config挑选;Ninja、MinGW Makefiles、Unix Makefiles 属于单配置生成器,configure 阶段用 CMAKE_BUILD_TYPE 把优化级别写死,构建阶段不再需要--config。
| 维度 | 单配置(Ninja / MinGW Makefiles) | 多配置(VS / Ninja Multi-Config) |
|---|---|---|
| 配置时机 | configure 时定 CMAKE_BUILD_TYPE | 构建时用 --config 选择 |
| 构建目录内 | 只有一组编译参数 | Debug/Release 并存 |
| 常见翻车 | --config 被静默忽略,不报错 | 忘写 --config,默认走 Debug |
我用 Ninja 配好 Release 之后敲cmake --build build --config Release,CMake 不会报错,只会提示当前生成器忽略--config,实际产物还是 configure 时定的 Debug。反过来,VS 生成器忘了--config Release,发布包体积直接大一圈,链接时还可能混进调试版运行库。这类问题在第 5 章还要展开。
2.3 生成器表达式:为什么它要到生成阶段才计算
cmake-generator-expressions.7.html 讲的$<...>不在 configure 阶段展开,而是在 generate 阶段按目标与配置计算。这意味着它可以感知$<CONFIG>的值、目标文件路径这类“生成时才知道”的信息。Windows 下常见用法是区分 Debug 与 Release 的编译选项:
target_compile_options(demo PRIVATE "$<$<CONFIG:Debug>:/Od;/Zi>")这段表示仅当当前配置为 Debug 时,给 demo 目标追加 /Od 和 /Zi。注意嵌套写法$<$<CONFIG:Debug>:...>在单配置生成器里同样有效,因为 CONFIG 会被替换成 CMAKE_BUILD_TYPE 的值。另一个高频场景是复制目标产物:
add_custom_command(TARGET demo POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:demo>" "$<TARGET_FILE_DIR:demo>/demo_copy.exe")$<TARGET_FILE:demo> 会在生成阶段展开成 demo 的完整 exe 路径。如果把这个表达式塞进 configure 阶段的普通变量赋值,得到的只会是空串。理解这个计算时机,是排这类坑的前提。
2.4 File API 与 CTest:留给 IDE 与 CI 的接缝
cmake-file-api.7.html 描述的是 CMake 3.14 引入的查询协议。IDE(VS、CLion、VSCode 插件)在构建目录下写.cmake/api/v1/query/codemodel-v2/query.json,CMake 在 generate 阶段把目标、编译命令、源文件列表以 JSON 输出到.cmake/api/v1/reply/。我在调试 IDE 集成时最常做的是手动创建这样一个 query 文件:
{ "requests": [ { "kind": "codemodel-v2" } ] }然后跑一次cmake -S . -B build,reply 目录里就会生成新的 index-*.json。这条链路和 cmake-presets 共同支撑了“命令行配置、IDE 读数据”的协作模式。
ctest.1.html 则是 CTest 手册。CTest 负责执行 add_test 注册的测试,常见参数有--test-dir指定构建目录、-C指定配置、--output-on-failure让失败用例打印日志。Windows CI 上这三个参数基本是标配,第 4 章会落到具体命令。
3. Windows 安装与路径规划:解压、PATH、多版本并存一次到位
3.1 解压后的目录结构
我习惯把 zip 解压到 D:\tools\cmake-3.28.6,而不是 C 盘深处。解压后的关键内容如下:
| 路径 | 作用 |
|---|---|
| bin/cmake.exe | 主程序 |
| bin/ctest.exe | 测试驱动 |
| bin/cpack.exe | 打包工具 |
| doc/cmake-3.28/html | 官方 HTML 手册 |
| share/cmake-3.28/Modules | Find 模块与编译器探测脚本 |
验证包是否完整的第一个动作是执行D:\tools\cmake-3.28.6\bin\cmake.exe --version,输出 3.28.6 说明二进制正常。注意编译器探测脚本 CMakeDetermineCompilerId.cmake 在 share 目录下,如果这个目录被移动或删除,configure 阶段会直接报“找不到编译器 ID 文件”,和编译器本身没关系。
3.2 PATH 配置:用户级变量而不是系统级
把 bin 写进 PATH 时优先用户级变量。系统级 PATH 会被所有服务、计划任务、已有 shell 继承,切版本时容易踩到看不见的旧路径。推荐用 PowerShell 的 Environment 接口:
$cmakeBin = "D:\tools\cmake-3.28.6\bin" $old = [Environment]::GetEnvironmentVariable("Path", "User") [Environment]::SetEnvironmentVariable("Path", "$old;$cmakeBin", "User")先读出当前用户已有的 Path,追加 cmake 的 bin 再写回。这里不用 setx,因为 setx 会把变量截断到 1024 字符,路径一多就静默丢内容。
提示:改完 PATH 必须新开终端窗口,已打开的会话不会刷新环境变量。
验证命令是where cmake和cmake --version。where 会把 PATH 里所有匹配的 cmake.exe 路径列出来,能顺带发现是不是有旧版本抢先占位。如果输出里出现两个不同路径,说明多版本混了,先清理再继续。
3.3 多版本并存:靠目录命名,不靠注册表
zip 免安装版天然适合多版本并存。我在 D:\tools 下同时放 cmake-3.28.6 和 cmake-3.20.5,哪个项目要求最低版本用哪个,切换方式就是改一下 PATH。真正的坑在缓存:CMakeCache.txt 里的生成器和编译器路径不会跟着 PATH 走。从 3.28 切回老版本后直接复用旧构建目录,configure 会拿旧缓存里的工具链路径硬拼。我一般用 3.24 引入的--fresh选项解决:
cmake --fresh -S . -B build等价于删掉 CMakeCache.txt 和 CMakeFiles 目录再重新配置,专门解决换版本后变量残留的问题。如果换的是编译器版本,建议连构建目录整体删掉,因为--fresh不清除已生成的中间产物。
3.4 配套工具链:Ninja、MSVC 与 MinGW 的边界
zip 里只有 CMake,没有编译器。Windows 下三条路线要分清:
- MSVC:装 Visual Studio 2022 时勾选“使用 C++ 的桌面开发”,CMake 通过 vswhere 自动定位 VS 实例,不需要手工导 vcvars64.bat。
- Ninja:ninja.exe 单独下载后放进某个目录并加入 PATH,配合 MSVC 或 MinGW 的编译器使用。
- MinGW:MSYS2 里的 mingw-w64 工具链,配置时用
-G "MinGW Makefiles",还得有 mingw32-make.exe 在同一 PATH 下。
常见误区是把-G Ninja和 MinGW 混在一起。Ninja 生成器只负责驱动构建,不负责找编译器;CMAKE_CXX_COMPILER 指向 g++ 时要用 MinGW Makefiles 或 Ninja 都行,但 make 相关的辅助脚本会有差异。“cmake 与 mingw”“opencv cmake 编译步骤”这类搜索里反复出现的报错,大多是生成器名写错或 PATH 里缺 ninja/make,configure 卡在“找不到生成器”一步。
4. 命令行构建一条链:配置、编译、测试、安装的完整命令
4.1 最小工程准备
先建一个最小工程,验证整条链路:
learn-cmake/ CMakeLists.txt main.cppcmake_minimum_required(VERSION 3.28) project(demo LANGUAGES CXX) add_executable(demo main.cpp) enable_testing() add_test(NAME demo_test COMMAND demo)cmake_minimum_required 写 3.28 是为了在 configure 阶段校验版本,如果 PATH 里串进来旧版 cmake,这里会直接报版本不满足。enable_testing() 必须出现在 add_test 之前,否则测试不会注册。
#include <iostream> int main() { std::cout << "cmake demo passed" << std::endl; return 0; }4.2 配置与构建:-S、-B、-G、-D 的配合
先用 Ninja 做一遍配置:
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release-S 指定源码目录,-B 指定构建目录,-G 选生成器,-D 写入缓存变量。Ninja 是单配置生成器,所以 CMAKE_BUILD_TYPE 在这里写死为 Release。配置成功后,构建目录里会出现 build.ninja 和 CMakeCache.txt,前者是实际驱动编译的规则文件,后者缓存全部变量。
再执行构建:
cmake --build build这条命令在 Ninja 生成器下等价于在 build 目录执行 ninja,CMake 会自动判断 configure 是否过期,必要时重跑。输出里能看到每条 cl.exe 或 g++ 的完整命令行,便于排查参数问题。
换成 Visual Studio 生成器时,两段命令变成:
cmake -S . -B build -G "Visual Studio 17 2022" -A x64 cmake --build build --config Release-G 后面的字符串必须与官方支持名称完全一致,写错会提示候选列表。-A x64对应 VS 的平台架构,不写默认 Win32,64 位项目链接时会报 LNK1112 这类架构不匹配。VS 是多配置生成器,所以配置阶段不设 CMAKE_BUILD_TYPE,构建阶段用--config Release选择。
4.3 测试:ctest 的三个参数哪个都不能少
ctest --test-dir build -C Release --output-on-failure--test-dir 指向构建目录,-C Release 指定测试配置,--output-on-failure 让失败用例把 stdout 和 stderr 打出来。用 Ninja 单配置生成器时,-C 不写也能跑,但它只能覆盖 configure 时固定下来的那一套;用 VS 多配置时漏掉-C Release,默认去测 Debug 产物,可能因为运行时库不匹配直接崩溃。这种“构建是好的但 ctest 全红”的情况,九成是配置没对上。
4.4 安装与打包:cmake --install 和 cpack
cmake --install build --config Release --prefix D:/install/demo--prefix 指定安装位置,不写则默认装到 C:/Program Files 下。Windows 上想快速分发,用 cpack 生成 zip:
cpack --config build/CPackConfig.cmake -G ZIP-G 可以换成 NSIS、WIX 等安装器格式,但 zip 最省心,不需要额外工具。cpack 的 RPM 生成器在 Windows 也能配置,但需要 rpmbuild 外部命令,实际使用极少——这也是为什么包里的 rpm.html 文档更多是查边界用的,不是鼓励你在 Windows 上打包 rpm。
5. 避坑记录:Windows 下 CMake 五种翻车现场与排查路径
按“现象 → 原因 → 解决”整理我实际踩过的两类问题。
5.1 工具链识别与缓存残留类
第一条:configure 报错说找不到编译器。现象是 CMakeError.log 里出现 fatal error C1083 或“unable to find cl.exe”,但 VS 明明装了。原因是安装 VS 时只选了本体,没勾“使用 C++ 的桌面开发”工作负载,缺少编译器和 Windows SDK。解决方法是打开 Visual Studio Installer,修改安装并勾选该负载。命令行环境缺变量时,可以在“开发者 PowerShell”里跑 cmake,但更稳的做法是让 CMake 自己用 vswhere 自动探测,不要手动导 vcvars64.bat,因为不同 VS 版本的 vcvars 路径并不一致。
第二条:换 VS 版本后链接到旧库。现象是明明选了 VS2022,编译日志里却出现旧 v143 工具集路径或旧 SDK 包含目录。原因是 CMakeCache.txt 缓存了旧的 CMAKE_CXX_COMPILER,configure 阶段认为缓存有效、跳过探测器。解决是删掉构建目录,或执行cmake --fresh -S . -B build重新探测。--fresh 会清掉缓存与 CMakeFiles,但不清中间产物,最保险的做法是构建目录整体删除后重配。这条值得多说一句:换编译器版本时,别只删缓存里那两行路径,直接删目录最省事。
5.2 路径、生成器与文件 API 类
第三条:中文或带空格路径导致构建失败。现象是 Ninja 报出解析规则错误,或 cl.exe 打不开源文件,GCC 时报错定位到乱码路径。原因是非 ASCII 路径在各工具链之间的编码处理不一致,CMake 3.28 对 UTF-8 路径的兼容已经改善,但 MSVC 的源文件清单和 ninja 的规则文件之间仍可能互相打架。解决是源码目录和构建目录都放到纯英文路径下,至少构建目录要在纯英文位置。这里没有玄学,规避比修复节省时间。
第四条:单配置/多配置混淆导致产物不对。现象是 Ninja 构建后再执行 ctest 出现 Debug 与 Release 混用,或 install 出来的 exe 体积明显不对。原因是 Ninja 的缓存里没有 CMAKE_BUILD_TYPE 时,构建命令带--config会被静默忽略,实际按上次 configure 的参数走。解决是在 CMakePresets 里固化 CMAKE_BUILD_TYPE,或者干脆用 Ninja Multi-Config 生成器,让构建目录同时保留多套配置。
第五条:File API 返回旧数据。现象是 IDE 里目标列表还是几小时前的,新增源文件不出现。原因多是 IDE 在构建目录写好了 query 描述,但 cmake 没有重新 generate,reply 里的 index 还是上一次生成的。解决是先检查.cmake/api/v1/query/下有没有客户端描述文件,再手动跑一次cmake -S . -B build,最后看 reply 目录里新生成的 index-*.json 时间戳。如果 IDE 仍然读旧文件,把 reply 目录整体删掉再重配。
6. 用 CMakePresets 锁定 Windows 构建流程:一份可复用 JSON 模板
命令行已经顺手,但每次手敲-G、-DCMAKE_BUILD_TYPE依然有出错空间。CMakePresets.json 的价值在于把生成器、架构、缓存变量、测试参数全部固化,让 VS、VSCode、命令行和 CI 读同一份配置。3.28 已经完全吃透 presets 格式,下面这份模板可以直接抄:
{ "version": 3, "cmakeMinimumRequired": { "major": 3, "minor": 22, "patch": 0 }, "configurePresets": [ { "name": "win-vs2022", "generator": "Visual Studio 17 2022", "architecture": "x64", "binaryDir": "${sourceDir}/out/${presetName}" }, { "name": "win-ninja", "generator": "Ninja", "binaryDir": "${sourceDir}/out/${presetName}", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } } ], "buildPresets": [ { "name": "win-vs2022", "configurePreset": "win-vs2022", "configuration": "Release" }, { "name": "win-ninja", "configurePreset": "win-ninja" } ], "testPresets": [ { "name": "win-vs2022", "configurePreset": "win-vs2022", "configuration": "Release", "output": { "outputOnFailure": true } }, { "name": "win-ninja", "configurePreset": "win-ninja", "output": { "outputOnFailure": true } } ] }注意 binaryDir 里的${presetName}会自动替换为当前 preset 名,VS 与 Ninja 的产物分别落在 out/win-vs2022 和 out/win-ninja,互不污染。configurePresets 里 VS 的 architecture 替代了-A x64,Ninja 的 cacheVariables 替代了-DCMAKE_BUILD_TYPE=Release。buildPresets 和 testPresets 通过 configurePreset 字段反查配置,命令行只需要三句:
cmake --preset win-ninja cmake --build --preset win-ninja ctest --preset win-ninja这套文件放进项目根目录后,VS 打开源码目录会自动识别,CLI 和 CI 也能用同一个名字调用。我第一次大规模用 presets 时没写 cmakeMinimumRequired,同事的老版 cmake 把 version 3 当成未知 key 解析失败,一上午都耗在环境排查上。从那以后我每次新建工程都强制走一遍:先写 cmakeMinimumRequired,再写 configurePresets,最后补 build 和 test 两段,换机器后从零执行三句命令验证一次。希望这份模板和前面的避坑记录能帮你省掉我在配置链路上浪费掉的时间。
本文还有配套的精品资源,点击获取