资讯动态

Windows下CMake 3.17.1免安装包配置与编译器接入指南

发布时间:2026/10/27 11:07:05 来源:尧图企业网站定制
简介面向 Windows 64 位开发者的 CMake 3.17.1 免安装压缩包适合需要跨平台构建、快速搭建编译环境或不方便运行安装程序的 C/C 项目开发者。解压后即可获得命令行工具与配套组件可直接加入 PATH 调用支持为 Visual Studio、Ninja 等生成器产出工程文件包内参考文档覆盖命令、模块、属性、变量与策略等主题便于查阅构建规则和排查配置问题。对初次接触 CMake 的读者可借助包内文档理解用描述文件定义构建过程的方式有经验者则可将便携目录用于机房、临时开发机或没有管理员权限的环境。压缩包共 6169 个文件以 txt、html、rst 文档及 cmake 模块定义为主另含 json 配置、png 图示和少量可执行文件整体约 32.47MB目录结构完整。已有 1192 人学习适合希望减少环境配置成本、随身携带构建工具并在多平台项目中保持构建规则一致的读者使用。1. 解压即用不等于装好cmake-3.17.1-win64-x64.zip 落地前先认清三件事Windows 上装 CMake翻车最多的环节往往不是解压那一下而是解压完敲cmake --version出来的版本号跟你以为的不一样。有人把 cmake-3.17.1-win64-x64.zip 丢进Program Files有人直接双击 zip 里的cmake.exe就跑结果 configure 时满屏找不到编译器——免安装包确实省掉了安装向导但它把「路径、PATH 顺序、编译器对接」这三件事全部留给了你自己。这份 3.17.1 的 win64 x64 包适合两类人一类是在 CI 机器或内网离线段机器上要固定 CMake 版本、不想让 MSI 安装器往注册表里写东西的人另一类是本机已经装了别的 CMake想再挂一份干净副本做对比测试的人。下面按我实际落地的顺序从解压位置一路讲到编译器接管和缓存清理。2. 解压与环境变量把 cmake.exe 放到正确位置并让命令行认它2.1 解压路径的三个硬要求CMake 本身不挑路径但它生成的东西挑。configure 阶段会把大量绝对路径写进CMakeCache.txt、*.vcxproj、build.ninja和 Makefile后续cmake --build读回来的还是这些路径。路径里带中文、带空格、带括号在 3.17.1 这一代上依然会在某些生成器上炸掉尤其是 MinGW Makefiles 拼mingw32-make命令行的时候。我给这份包定的落地规则是三条纯 ASCII 字符、不含空格、层级固定且不放在C:\Program Files下面。放Program Files的问题不是权限而是多版本共存时目录名会被迫加上版本后缀写脚本的时候容易漏引号。我一般统一放D:\tools\cmake\下解压出来正好是D:\tools\cmake\cmake-3.17.1-win64-x64\以后升到 3.2x 就平行放一份靠 PATH 或包装脚本切换。解压可以直接用 PowerShell也可以用 Win10 1803 之后自带的tar本质是 bsdtar认 zip# 建好父目录避免 Expand-Archive 把 zip 内容散到当前目录 New-Item -ItemType Directory -Force -Path D:\tools\cmake | Out-Null # 方式一PowerShell 原生解压 Expand-Archive -Path .\cmake-3.17.1-win64-x64.zip -DestinationPath D:\tools\cmake -Force # 方式二系统自带 tar速度通常更快且不会因长路径报错 tar -xf .\cmake-3.17.1-win64-x64.zip -C D:\tools\cmake-DestinationPath指到父目录就够了zip 内部自带一层cmake-3.17.1-win64-x64顶层文件夹不要再往里套一层否则路径会变成...\cmake\cmake-3.17.1-win64-x64\cmake-3.17.1-win64-x64\bin这种重复层级在写批处理时特别容易写错。-Force是覆盖已存在的同名文件重装同一版本时省掉手动删目录。解压完先别急着配 PATH进去看一眼结构。合格的包里bin目录下应该有四个可执行文件cmake.exe、ctest.exe、cpack.exe、cmake-gui.exe同级还有share\cmake-3.17\Modules这个模块目录。Modules 目录是 CMake 找FindXXX.cmake的地方缺了它 configure 会报一堆Could not find a package configuration file。确认这一步dir /b D:\tools\cmake\cmake-3.17.1-win64-x64\bin dir /b D:\tools\cmake\cmake-3.17.1-win64-x64\share\cmake-3.17\Modules | find /c .cmake第二条命令数一下模块文件数量正常是几百个。如果bin里只有cmake.exe没有别的说明下载的是残缺包或者被安全软件截断过重新下一份即可别硬着头皮往下走。2.2 PATH 配置用户变量还是系统变量这一步是整个安装里最容易留下隐患的地方。很多人习惯直接改系统级 PATH觉得「全局生效」但在一台装了多份工具链的机器上系统 PATH 越写越长后来的人根本分不清哪条是谁加的出问题也没法快速回滚。我的做法是只动当前用户的 PATH把bin目录追加进去系统 PATH 一个字不碰。追加顺序也有讲究新加的项放在前面这样它能盖住之前可能存在的旧 CMake。用 PowerShell 改用户 PATH 比setx稳setx有两个老毛病——超过 1024 字符会截断以及会把REG_EXPAND_SZ类型的变量降级成普通字符串导致%USERPROFILE%这类引用失效。# 读取当前用户的 PATH不要用 $env:PATH那个是用户系统合并后的结果 $old [Environment]::GetEnvironmentVariable(Path, User) # 目标 bin 目录注意结尾不要带反斜杠 $cmakeBin D:\tools\cmake\cmake-3.17.1-win64-x64\bin # 幂等先剔除已存在的同名项再前置避免重复追加把 PATH 撑爆 $items $old -split ; | Where-Object { $_ -and $_ -ne $cmakeBin } $new (($cmakeBin) $items) -join ; [Environment]::SetEnvironmentVariable(Path, $new, User)GetEnvironmentVariable(Path,User)只取用户级那一段Machine才是系统级这两个作用域分开读写是后面能干净卸载的前提。剔除同名项那一步是幂等性处理同一段脚本我愿意多跑几遍也不会把 PATH 写坏。-join ;重新拼回分号分隔格式Windows 的 PATH 就认这个分隔符别用逗号也别用换行。设置完成后已经打开的 cmd 和 PowerShell 窗口不会自动刷新这是新手最常问的「我明明配了怎么还找不到」。开个新窗口或者在当前窗口手动同步一次# 仅对当前会话生效从注册表重新拉一遍用户系统 PATH 合并值 $env:PATH [Environment]::GetEnvironmentVariable(Path,Machine) ; [Environment]::GetEnvironmentVariable(Path,User)cmd 用户对应的临时写法是set PATHD:\tools\cmake\cmake-3.17.1-win64-x64\bin;%PATH%只影响当前这个黑窗口关掉就没了适合临时试跑。有一点要提醒不要手动去设CMAKE_ROOT环境变量。这个变量是 CMake 启动时根据自身 exe 位置反推出来的内部变量手动指定反而会让它去错误的目录找 Modules报出「CMake Error: Could not find CMAKE_ROOT」这种看着莫名其妙的问题。免安装包天然支持这种反推因为bin和share的相对位置是对的——这也是为什么上一节强调不要把目录层级改乱。2.3 验证接管where 和 --version 要一起看配完 PATH 只验证版本号是不够的cmake --version只告诉你「找到了一个 cmake」不告诉你「找到的是哪一个」。两个命令一起用where cmake cmake --versionwhere会按 PATH 顺序列出所有匹配的cmake.exe第一行才是实际被调用的那个。正常输出应该是D:\tools\cmake\cmake-3.17.1-win64-x64\bin\cmake.exe C:\Program Files\CMake\bin\cmake.exe然后cmake --version第一行应当是cmake version 3.17.1。如果where第一行是别的路径说明你机器上有更高优先级的旧安装这时候要么调整 PATH 顺序要么把旧的那份从 PATH 里摘掉。我见过最阴的一种情况是where只输出一行看着很干净但版本号对不上——那是某个 IDE 自带的cmake.exe被某个 shell 初始化脚本塞到了最前面这种只能靠逐个where排查。顺带确认ctest和cpack也能被找到它们跟cmake.exe在同一个bin里PATH 配对了一般就是全套配对了ctest --version cpack --version两条都应输出 3.17.1。到这一步CMake 本体的安装算完成了但它现在还是个「只会生成构建文件、不知道该用什么编译器」的空壳——下一章才是真正决定成败的地方。3. 接上编译器cmake 3.17.1 在 Windows 下配 VS 2019 与 MinGW 的两条路CMake 自己不编译它只负责读CMakeLists.txt、探测编译器、生成下游构建系统能读的文件。所以在 Windows 上谈「cmake windows 编译器」这件事本质是回答两个问题用哪个生成器Generator以及那个生成器背后依赖的编译器装没装、CMake 找不找得到。3.1 生成器与编译器的对应关系3.17.1 这一代在 Windows 上能用的生成器不算少先cmake --help拉到 Generators 那一段看一眼带*的是当前默认。常见组合整理成一张表更直观生成器名-G 参数依赖的编译器/工具是否需要特定命令行环境产物形式Visual Studio 16 2019VS 2019 的 MSVCv142否CMake 会自己查注册表.sln.vcxprojVisual Studio 15 2017VS 2017 的 MSVCv141否.sln.vcxprojNinja任意 C/C 编译器 ninja.exe建议在 Native Tools 命令行下build.ninjaNinja Multi-Config同上Ninja ≥ 1.10同上多配置build-*.ninjaMinGW MakefilesMinGW 的gcc.exe/g.exemingw32-make.exe否但两者都必须在 PATHMakefileNMake MakefilesMSVC 的cl.exenmake.exe是必须在 VS 命令行下Makefile表格里最容易踩的是最后一行NMake Makefiles在普通 cmd 里跑必然失败因为cl.exe和nmake.exe都不在默认 PATH 里得从开始菜单进「x64 Native Tools Command Prompt for VS 2019」。而Visual Studio 16 2019生成器不需要CMake 会通过 COM 接口去问系统装了哪些 VS 实例这也是它在 Windows 上最省心的原因。Ninja Multi-Config是 3.17 版本新引入的生成器优势是一次 configure 就能同时产出 Debug 和 Release 两套构建规则cmake --build build --config Debug和--config Release直接切不用建两个目录。代价是对ninja.exe版本有要求低于 1.10 会直接报错。3.2 走 VS 2019 这条路最稳的第一次 configure前提只有一个VS 2019 装了「使用 C 的桌面开发」工作负载。只装 .NET 或只装 VS Code 是不够的CMake 会明确告诉你No CMAKE_CXX_COMPILER could be found。假设项目源码在D:\work\demoCMakeLists.txt就在这一层。用 3.13 之后引入的-S/-B分离写法cd /d D:\work\demo cmake -G Visual Studio 16 2019 -A x64 -S . -B build -DCMAKE_CONFIGURATION_TYPESDebug;Release逐段解释-G Visual Studio 16 2019显式锁定生成器不写的话 CMake 会挑本机最高版本的 VS机器上同时有 2017 和 2019 时结果不确定-A x64指定目标平台架构不写会默认生成 Win32 工程编译出来的 exe 是 32 位的跟 64 位依赖库链接时报模块计算机类型“x86”与目标计算机类型“x64”冲突-S .是源码目录-B build是构建目录源码和构建产物彻底分开删产物只需要删build一个目录-DCMAKE_CONFIGURATION_TYPES限制只生成 Debug 和 Release 两种配置不写的话 VS 工程里会多出 RelWithDebInfo 和 MinSizeRel编译时容易选错。成功的标志是最后几行出现-- Configuring done -- Generating done -- Build files have been written to: D:/work/demo/build看到Build files have been written to才算 configure 真的过了。中间那些-- Detecting C compiler ABI info、-- Check for working CXX compiler是正常探测流程只要没出现CMake Error就继续往下。接着编译。VS 生成器是多配置的--build后面必须跟--configcmake --build build --config Release --parallel--config Release对应 VS 里的解决方案配置不写默认是 Debug--parallel不跟数字表示用满所有核跟数字就是限定并发数。这条命令比进 VS 里按 F7 的好处是同一个脚本在 CI 和本机完全一致。3.3 走 MinGW Ninja 这条路轻量但要自己对齐不想装几个 G 的 VS就用 MinGW-w64 加 Ninja。这条路的要求很明确gcc.exe、g.exe、mingw32-make.exe或ninja.exe全部在 PATH 里缺一个就 configure 失败。:: 先确认编译器能被命令行找到 where gcc where g where ninja cmake -G Ninja -S . -B build-mingw ^ -DCMAKE_BUILD_TYPERelease ^ -DCMAKE_C_COMPILERgcc ^ -DCMAKE_CXX_COMPILERg ^ -DCMAKE_MAKE_PROGRAMninja-DCMAKE_C_COMPILER和-DCMAKE_CXX_COMPILER是两个只在第一次 configure 时有效的变量一旦写进CMakeCache.txt后面再传不同值会被忽略并给出警告。-DCMAKE_MAKE_PROGRAM用来显式指定构建程序路径PATH 里有多份 ninja 时这个参数能省掉一堆猜谜。^是 cmd 的续行符写在最后一行就别加了。Ninja 是单配置生成器所以-DCMAKE_BUILD_TYPERelease在这里是必填的空着不写CMake 会当 Debug 处理但很多项目的CMakeLists.txt里对空 build type 有特殊分支行为不一定符合预期。编译命令也因此简单cmake --build build-mingw不要在这里加--config Release单配置生成器不认这个参数加了也不报错但什么也不做很容易让人误以为配置切换成功了。如果改用 MinGW Makefiles把-G Ninja换成-G MinGW Makefiles-DCMAKE_MAKE_PROGRAM改成mingw32-make其余不变。这条路生成的Makefile对路径里的空格极其敏感源码放在D:\My Projects\这种目录下大概率会在链接阶段失败这也是第 2 章强调纯 ASCII 无空格路径的直接原因。两条路都通选哪条看场景要在 CI 上跑、又不想装完整 VSBuild Tools Ninja 是最小组合要给别人发 Visual Studio 工程、让对方直接在 IDE 里调那就走 VS 生成器。我自己的习惯是本机用 VS 2019 生成器保底CI 上用 Ninja 跑得快。4. 缓存与参数CMakeCache.txt 里哪些变量值得手动改4.1 缓存到底存了什么以及它为什么锁死生成器第一次 configure 之后build目录里会多出一个CMakeCache.txt。这个文件的本质是一张变量名:类型值的键值表记录着编译器路径、生成器名字、各种find_package的结果、用户传过的所有-D参数。后续每次 configure 都会先读它只有命令行上显式传的新值才会覆盖。这解释了一个高频问题改了-G参数重新 configure结果报一堆红字。cmake -G Ninja -S . -B build # CMake Error: Error: generator : Ninja # Does not match the generator used previously: Visual Studio 16 2019原因是CMakeCache.txt里存着CMAKE_GENERATOR:INTERNALVisual Studio 16 2019CMake 认为你是在同一个构建目录上换了生成器直接拒绝。解决办法不是加什么参数而是把构建目录整个删掉重建:: 干净重建构建目录内所有内容都是可再生的删了不心疼 rmdir /s /q build cmake -G Ninja -S . -B build这条规则同样适用于换编译器、换架构-A x86换-A x64、换工具链文件。凡是涉及生成器或编译器身份的参数变了一律删build重来别指望 CMake 自动迁移。想少删几次就一开始把构建目录按配置分开命名build-vs2019、build-ninja、build-mingw。查缓存值不需要打开文件翻-N -L加grep更快:: -N 表示只加载缓存不重新 configure-L 列出所有带类型的缓存变量 cmake -N -L build | findstr /i CMAKE_BUILD_TYPE CMAKE_CXX_COMPILER CMAKE_INSTALL_PREFIX4.2 真正值得手动传的几个 -D 参数缓存变量几百个日常需要手动干预的就那么几个。整理成表后面遇到不认识的直接对照变量类型默认值什么时候必须手动给CMAKE_BUILD_TYPESTRING空等价 Debug所有单配置生成器CMAKE_INSTALL_PREFIXPATHC:/Program Files/项目名不想往系统盘装的时候CMAKE_CXX_STANDARDSTRING由项目决定项目没写、又要用 C17 时CMAKE_TOOLCHAIN_FILEFILEPATH空交叉编译或 vcpkg 场景CMAKE_PREFIX_PATHPATH空依赖装在非标准位置BUILD_SHARED_LIBSBOOLOFF想默认产出动态库CMAKE_BUILD_TYPE只对单配置生成器有效VS 生成器下传了也是白传——这是新手最容易混淆的一对概念。CMAKE_INSTALL_PREFIX默认落在Program Files下面用免安装包的人通常也不希望装到系统目录所以这条基本要改cmake -G Ninja -S . -B build ^ -DCMAKE_BUILD_TYPERelease ^ -DCMAKE_INSTALL_PREFIXD:/work/demo/install ^ -DCMAKE_CXX_STANDARD17 ^ -DCMAKE_CXX_STANDARD_REQUIREDON路径一律用正斜杠。cmd 里传D:\work\demo会被反斜杠转义问题坑到D:/work/demo在 CMake 里是完全合法的写法且跨 shell 一致。CMAKE_CXX_STANDARD_REQUIREDON表示编译器不支持 C17 就报错而不是悄悄降级这个开关我建议和CMAKE_CXX_STANDARD绑定使用否则会出现「本机能编、CI 上编出来行为不一样」的玄学问题。CMAKE_PREFIX_PATH是找依赖包时的搜索根目录。Windows 上没有/usrCMake 默认只查Program Files和几处系统位置第三方库装在D:\libs\下的话必须显式告诉它cmake -S . -B build -DCMAKE_PREFIX_PATHD:/libs/opencv;D:/libs/protobuf多个路径用分号隔开同样用正斜杠。4.3 安装与打包configure 之后的两个动作3.15 之后cmake --install成了跨平台统一入口不用再记make install还是msbuild INSTALL.vcxproj:: 单配置生成器不需要 --config cmake --install build :: 多配置生成器VS、Ninja Multi-Config要指定配置 cmake --install build --config Release --prefix D:/work/demo/install--prefix会覆盖缓存里的CMAKE_INSTALL_PREFIX临时换安装位置时用它比重跑 configure 快。这里有个细节--prefix传入的路径同样建议用正斜杠混写反斜杠在某些生成器下会被当成转义字符吞掉。打包用cpackCPackConfig.cmake由项目里的include(CPack)生成cd /d D:\work\demo\build cpack -G ZIP -C Release-G ZIP指定产出一个 zip 包-C Release指定配置多配置生成器下必须给。产物落在build目录里文件名由CPACK_PACKAGE_FILE_NAME决定。5. 排查清单cmake 3.17.1 在 Windows 上最常踩的五个坑5.1 版本被旧路径劫持现象明明把新目录加进了 PATHcmake --version还是显示旧版本或者where cmake第一行是新路径版本号却是旧的。原因Windows 的 PATH 查找是「用户变量 系统变量」拼起来后按顺序匹配系统变量默认排在用户变量前面。你把新目录追加到用户 PATH 末尾前面任何一处有旧的cmake.exe都会先命中。还有一种情况是 IDE 的终端在启动时注入了自己的工具路径。解决where cmake看完整列表确认第一行。要强制新版本优先就在用户 PATH 里把它前置而不是追加第 2 章那段脚本就是前置的或者干脆把旧版本那条路径从对应作用域里删掉。别用改文件夹名的办法绕过下次更新还会撞上。5.2 生成器缓存锁死现象第二次 configure 时换了-G报Does not match the generator used previously或者换了编译器报CMAKE_CXX_COMPILER changed之后行为异常。原因CMakeCache.txt里记着首次 configure 的生成器和编译器身份CMake 不允许在同一构建目录上更换。解决rmdir /s /q build后重新 configure。这个操作零风险构建目录里的所有内容都能从源码重新生成唯一代价是重新编译时间。我一般把这条写进批处理凡是参数变化就先删目录。5.3 找不到 C 编译器现象configure 阶段报No CMAKE_CXX_COMPILER could be found或者The C compiler identification is unknown。原因三种可能——VS 只装了 IDE 没装「使用 C 的桌面开发」工作负载MinGW 装了但g.exe不在 PATH用了NMake Makefiles却从普通 cmd 里跑cl.exe根本不可见。解决VS 路线先去 Visual Studio Installer 里补工作负载补完不需要重启但需要新开命令行窗口MinGW 路线where g确认可见NMake 路线从开始菜单进 Native Tools 命令行。三条都排除还不行就看build\CMakeFiles\CMakeError.log里面会写清楚它尝试调用了哪个编译器、报了什么错比屏幕上的红字详细得多。5.4 中文路径与带空格路径现象configure 能过build 阶段在链接时失败报找不到.obj或.o或者mingw32-make报*** 目标不存在之类的怪错。原因MinGW 系列的 Makefile 对路径中的空格和中文处理很差路径里出现空格会被当成参数分隔符中文则涉及代码页转换不同工具链行为不一致。解决源码、构建目录、安装目录全部挪到纯 ASCII 无空格路径下。这条没有技术上的绕法-DCMAKE_OBJECT_PATH_MAX之类的参数只能缓解不能根治。把项目放在D:\work\下是最省事的习惯。5.5 Debug/Release 运行库混链现象编译通过运行时报应用程序无法正常启动 (0xc000007b)或者链接期报LNK2038: 检测到“RuntimeLibrary”的不匹配项。原因不同配置或不同库用了不同的 MSVC 运行库/MD对/MT、Debug 对 Release常见于一半依赖是 Debug 版、一半是 Release 版的情况。解决统一配置。VS 生成器下所有--build都带同一个--configNinja 下重新 configure 时改CMAKE_BUILD_TYPE必须先删缓存否则旧的编译选项还留着。第三方库尽量用同一套配置编译别把opencv_world.dll的 Release 版和 Debug 版混在一个 exe 里。6. 验证跑通用一个最小 C 工程把 configure、build、run 全链路走一遍装完最后一步不是看一眼版本号而是真编一个东西出来跑起来。这个最小工程我一般放在D:\work\smoke两个文件就够# CMakeLists.txt cmake_minimum_required(VERSION 3.17) project(smoke LANGUAGES CXX) # 要求 C17编译器不支持就直接失败而不是降级 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_executable(smoke main.cpp)// main.cpp #include iostream #include string_view int main() { std::string_view msg smoke test ok; std::cout msg \n; #if defined(_MSC_VER) std::cout compiler: MSVC _MSC_VER \n; #elif defined(__GNUC__) std::cout compiler: GCC __GNUC__ . __GNUC_MINOR__ \n; #endif return 0; }cmake_minimum_required(VERSION 3.17)是为了让这份工程天然只接受 3.17 及以上老版本会直接报错退出不会悄悄用旧策略编出行为不一致的东西。LANGUAGES CXX显式限定只启用 C省掉 C 编译器的探测时间。#if defined(_MSC_VER)那段是为了验证「到底哪个编译器接上了」——跑出来的输出会直接告诉你是 MSVC 还是 GCC。然后三条命令走完全链路cd /d D:\work\smoke cmake -G Visual Studio 16 2019 -A x64 -S . -B build cmake --build build --config Release D:\work\smoke\build\Release\smoke.exe预期输出smoke test ok加一行编译器信息。三条都通过说明 PATH、生成器、编译器、构建、链接全链路是通的后面再遇到项目编不过问题基本可以锁定在项目自己的CMakeLists.txt或依赖上不用再怀疑环境。想再确认一层可以顺手验证--install和ctest。在CMakeLists.txt里加一行install(TARGETS smoke RUNTIME DESTINATION bin)然后cmake --install build --config Release --prefix D:/work/smoke/out看out\bin\smoke.exe是否出现。这一步验证的是CMAKE_INSTALL_PREFIX有没有被正确解析很多人第一次做安装包时栽在这里。提示这份 zip 包不使用系统安装器卸载时不需要走控制面板把 PATH 里那条记录删掉、再把D:\tools\cmake\cmake-3.17.1-win64-x64整个目录删掉就干净了。留个备份 zip 在D:\tools\下重装时省一次下载。从那以后我每次给新机器铺这套环境都会先跑一遍这个 smoke 工程再动真项目宁可多花两分钟也不愿意在项目 configure 失败时去分辨到底是环境问题还是代码问题——这两种情况排查成本差了一个数量级。手上这份 cmake-3.17.1-win64-x64.zip 解压完bin和share\cmake-3.17\Modules都是齐的照上面顺序走一遍就能直接用。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑