尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Windows 11下VSCode+CMake+MinGW-w64配置C/C++开发环境全攻略

Windows 11下VSCode+CMake+MinGW-w64配置C/C++开发环境全攻略 别的不说光“配置C/C开发环境”这七个字就劝退过不少刚入门的同学。明明代码照着书敲的结果连个Hello World都跑不起来卡在装环境这一步就折腾一下午。我这些年帮人排查过太多类似的案例发现大部分人并不是不会写代码而是倒在了环境配置这座山脚下。所以今天这篇我就把自己在Windows 11上配VSCode、CMake和MinGW-w64这套组合拳的完整流程整理出来按照这个思路走下来基本就是一次过的事。这套方案解决的是Windows下C/C开发的“环境焦虑”问题。无论你是刚学C语言的大学生还是在Windows上做跨平台开发的老手只要你不想装体积庞大的Visual Studio又想用上CMake这个事实上的构建标准那这篇文章就是给你写的。整个流程配置完你只需要在VSCode里点一下按钮CMake会自动帮你完成编译、链接、运行真正做到后续“一键式”操作。1. 为什么是这套组合环境选型思路解析1.1 Windows下C/C开发的几个方向对比2025年这个节点Windows上做C/C开发基本就三条路Visual Studio全家桶、LLVM/Clang配VSCode、MinGW-w64配VSCode。我用过前两种实话说各有各的好但都不如第三种来得轻巧。Visual Studio包括VS Code那个同名编辑器注意这俩真不是一个东西确实是Windows平台的亲儿子调试器强大到没朋友但它的体量实在太大了一个完整安装动辄十几个GB而且有些学校的老机器根本带不动。这几年很多学生来找我说老师让装全功能VS装完电脑卡得跟PPT一样跑个课程设计项目风扇狂转。这玩意适合企业级开发但你让我为了跑一个一百行的链表作业去装它我是拒绝的。Clang配VSCode这条路适合对编译原理有执念的极客Clang的报错信息清晰、诊断友好但它配套的调试工具链在Windows上还是有点折腾你需要额外搞定LLDB和CodeLLDB插件的配合问题对新手不太友好。1.2 MinGW-w64为什么是Windows下的最优解MinGW-w64是GCC编译器套件在Windows上的移植版它的核心价值在于你在Linux上写的代码拿到Windows上用这套工具编译基本不用改就能跑。对于需要跨平台的项目这能省掉无数个“在Windows上编不过”的坑。重要的是MinGW-w64配套的GCC已经跟上了上游发布节奏。以我现在用的版本为例GCC内核已经是较新的主线版本完整支持C17、C20甚至部分C23特性。这意味着你在网上看到的很多现代C写法不需要额外加编译选项就能直接跑。还有个很多人没意识到的点MinGW-w64编译出的exe是原生的Windows程序不依赖任何运行时环境。你把这个exe拷到另一台没装任何开发工具的Windows电脑上双击就能跑。这在交作业或者给同事演示小工具时特别好使。1.3 CMake在现代化开发里的角色定位早些年做C项目最常见的就是自己写Makefile。手写Makefile这个东西小项目还能应付项目一复杂起来各种依赖关系、编译选项、平台差异能让人写到怀疑人生。我自己就见过一个运维写的Makefile足足四百行每次改需求都要小心翼翼生怕碰坏哪个依赖关系。CMake解决的就是这个问题你不用花大量精力去写平台相关的构建脚本只需要用CMake自己的描述语言告诉它你的项目有哪些源文件、链接哪些库、用C哪个标准剩下的各种编译命令生成、平台差异处理CMake会自己搞明白。而且CMake现在已经发展到了构建系统生成器的角色它可以生成Ninja构建脚本、Unix Makefile、Visual Studio解决方案等一套CMakeLists.txt通吃所有平台。用CMake还有一个隐性的好处它逼着你把项目的目录结构理清楚。你的源文件放哪、头文件放哪、第三方库怎么组织这些在写CMakeLists.txt的时候必须明确。这种“清晰”会从项目结构一路传导到你的代码风格我自己写小工具时用CMake实测下来反而比随手扔在一起的代码好维护得多。2. 环境准备与工具下载MinGW-w64、CMake、VSCode2.1 MinGW-w64的下载与版本选择很多人卡在MinGW-w64的第一关其实是下载。这个项目的官方托管在SourceForge上但国内直接访问时经常慢如蜗牛。这里我给一个更靠谱的思路去国内一些知名的开源镜像站下载。不过镜像站的具体地址可能会变化我更推荐直接搜索“winlibs mingw-w64”这个关键词它的发行版做了持续集成验证下载速度也相对可接受。选版本的时候有四个点你要注意不然下载完也没法用架构选x86_64现在的电脑99%都是64位除非你有一台十年前的32位老古董不然闭眼选x86_64。线程模型选posix这个非常关键。MinGW-w64的线程模型分win32和posix两种win32模型下没有完整的C11线程标准库支持std::thread相关功能会缺失选posix就不会有这个问题。如果你以后要接触大量C并发编程这个必须选对。异常处理模型64位版本提供seh和sjlj两个选项我建议直接选seh。它跟系统的结合更好性能也更高。版本号标题里我写的是“MinGW-w64”但别光看这个名字进去之后要找对应的GCC版本。我的建议是选最新的稳定版。GCC的版本号不用跟什么对齐越新越好新版本对C标准支持更完整修复的bug也更多。下载下来的是一个压缩包解压到一个纯英文路径这点很关键。比如我习惯放在D:\mingw64千万别放在含中文或空格的路径下比如D:\Program Files\mingw64或者D:\工具\mingw64都会有隐患。问就是血泪教训CMake对路径里的空格处理经常有各种兼容问题尤其是那些第三方库的CMake模块。2.2 CMake 3.31.4安装细节CMake的安装相对简单去官网下载Windows x64的安装包双击运行执行以下两步安装选项里一定要勾选“Add CMake to the system PATH for all users”。这一步是很多新手吊坑的重灾区如果不勾选后续在命令行里输入cmake会直接报“无法识别”到时候还得手动去改环境变量多一道工序。安装路径同样建议改为C:\Program Files\CMake这类固定位置或者像我一样自定义到D:\CMake确保无中文无空格。如果说安装MinGW-w64像是埋了一颗有各种选项的种子那安装CMake就轻松多了只要你记得勾选加入PATH后面基本就是一路下一步。2.3 VSCode的安装与基础设置VSCode的安装包下载同样简单直接到官网下载User Installer版本即可。安装时建议勾选“添加到PATH”和“在文件资源管理器上下文菜单中打开”这两个选项会极大便利后续操作。装完VSCode第一件事我一直习惯先切中文界面。这个操作很多人不知道装完西洋键盘界面后你去扩展商店搜索Chinese (Simplified) (简体中文) Language Pack安装后右下角会弹窗问你“是否切换语言”点“更改语言并重新启动”就行。注意这个语言包是纯界面翻译不影响代码编辑和调试功能。VSCode还有一个隐藏要求它的C/C插件需要.NET Runtime一般最新版VSCode会自动帮你装好如果遇到插件装完没法用的优先去微软官网把“.NET Desktop Runtime”装上。3. 环境变量配置成败的关键一步3.1 PATH配置的正确姿势这一步是整个流程里最重要的没有之一。很多人的环境配置失败九成都是栽在环境变量这里。我们的目标是把MinGW-w64和CMake的bin目录加进系统PATH让命令行能够直接找到gcc、g、make、cmake这些程序。操作路径如下右键“此电脑” → 属性 → 高级系统设置 → 环境变量。这里注意系统变量和用户变量里都有PATH我建议改系统变量里的PATH因为这样对这台电脑的所有用户都生效避免后续你用管理员模式跑VSCode时配置丢失。在PATH里新增三行或者两行取决于你的实际路径D:\mingw64\binC:\Program Files\CMake\bin根据你的安装路径调整有些MinGW-w64发行版还会自带make工具不用单独加但如果你下载的版本bin目录下没有mingw32-make.exe那就需要额外下载make工具。但说实话我们后面用CMake作为构建系统生成器让CMake去管编译make工具反而不需要直接出现在PATH里。改完之后关键的一步来了一定要关掉当前所有命令行窗口再重新打开否则环境变量不会生效。新手在这一步最容易栽跟头明明配好了一验证还是“不是内部或外部命令”结果发现是自己没重开终端。3.2 验证环境配置是否成功环境变量配完打开一个新的CMD命令行窗口注意是CMD不是PowerShell因为PowerShell有时候对路径的解析策略跟CMD不同容易误导新手依次输入以下验证gcc --version g --version cmake --version正确的结果应该分别显示GCC和CMake的版本信息。比如我机器上gcc显示的是GCC 14.2.0cmake显示的是cmake version 3.31.4。如果这三条命令都能正常输出版本号说明环境变量配置成功了可以进入下一步。如果提示无法识别先别慌检查两件事第一你重开终端了没有第二你的PATH路径拼写对不对有没有多一个空格少一个分号。这两步排查掉90%的问题。4. VSCode侧配置三个json文件搞定4.1 安装必要插件VSCode本质上就是一个高级文本编辑器它自己不认识C代码。要让VSCode具备C/C的编辑、编译、调试能力必须装插件。我建议按以下优先级装C/C作者是Microsoft官方这个插件提供了语法高亮、IntelliSense智能提示、代码跳转和调试功能。核心中的核心。CMake Tools也是Microsoft官方这个插件让VSCode能够识别CMakeLists.txt并提供一键配置、构建、运行的能力。CMake作者是twxs主要提供CMakeLists.txt的语法高亮配合CMake Tools一起用。Code Runner可选如果你只想快速跑个单文件测试不想每次都走完整的CMake构建流程这个插件能帮你一键运行当前文件。但对于正经项目我还是推荐走CMake流程。装完插件后C/C插件第一次打开项目时右下角会弹窗提示选择工具链Select a kit / 选择编译器套装。在这里就应该能看到我们刚才配置的GCC编译器。如果没弹也可以手动按CtrlShiftP打开命令面板输入“CMake: Select a Kit”选择GCC。4.2 理解VSCode C项目的三层配置很多新手第一次看到VSCode生成的.vscode文件夹时被里面一堆json文件搞得云里雾里其实这些文件就三个职责搞清楚之后配起来手到擒来c_cpp_properties.json负责告诉C/C插件的IntelliSense你的编译器路径是什么系统头文件在哪里用哪种C标准进行代码提示。它只管编辑器侧的代码理解和智能提示不参与实际编译。tasks.json负责配置编译任务告诉VSCode点击“终端 → 运行生成任务”时具体执行什么编译命令。launch.json负责配置调试器当你按F5启动调试时它知道去调用哪个调试器、加载哪个可执行文件。如果你用CMake Tools插件那tasks.json和launch.json可以被简化为相当精简的模式因为大量构建逻辑由CMake接管了。不过很多习惯传统Makefile的同学喜欢手动配置tasks我这里推荐坚持用纯CMake流程一劳永逸。4.3 c_cpp_properties.json配置实战我的.vscode/c_cpp_properties.json配置如下你可以直接抄只要把编译器路径改成你自己的MinGW-w64路径{ configurations: [ { name: Win64_GCC, includePath: [ ${workspaceFolder}/**, D:/mingw64/include/** ], defines: [], compilerPath: D:/mingw64/bin/gcc.exe, cStandard: c17, cppStandard: c17, intelliSenseMode: windows-gcc-x64 } ], version: 4 }其中D:/mingw64/include/**是GCC自带的C/C标准库头文件位置${workspaceFolder}/**表示当前项目文件夹下所有子文件夹。编译标准我这边默认选了C17和C17如果你要用C20的新特性改成c20即可。4.4 tasks.json与launch.json的极简配置如果你决定直接使用CMake Tools插件来构建项目那么你其实不需要手动编写tasks.json中冗长的编译命令。CMake Tools插件会在你按下构建按钮时自动调用cmake配置和cmake --build操作。不过我还是建议配置一个简洁的tasks.json原因在于有时你需要在命令行场景下快速构建或者想用CtrlShiftB快捷键触发构建。最简版tasks.json{ version: 2.0.0, tasks: [ { label: CMakeBuild, type: shell, command: cmake --build ${workspaceFolder}/build --config Debug, group: { kind: build, isDefault: true } } ] }launch.json的配置要稍微复杂一点主要是配置调试器路径和程序路径。以GDB调试为例{ version: 0.2.0, configurations: [ { name: C/C Debug, type: cppdbg, request: launch, program: ${workspaceFolder}/build/项目名.exe, args: [], stopAtEntry: false, cwd: ${workspaceFolder}, environment: [], externalConsole: false, MIMode: gdb, miDebuggerPath: D:/mingw64/bin/gdb.exe, preLaunchTask: CMakeBuild, setupCommands: [ { description: 为gdb启用整齐打印, text: -enable-pretty-printing, ignoreFailures: true } ] } ] }这里的${workspaceFolder}/build/项目名.exe路径取决于你的CMake配置输出目录这个我们下一步再说。5. 用CMake跑通第一个项目实操环节5.1 创建CMakeLists.txt现在已经万事俱备动手写项目。我一般这么建目录结构MyDemo/ ├── CMakeLists.txt └── src/ └── main.cppmain.cpp就先写一个最简单的Hello World注意一定要写std::endl或者在std::cout后手动换行不然运行结果可能看不到输出或者缓冲未刷新导致显示不全。CMakeLists.txt最简版如下cmake_minimum_required(VERSION 3.20) project(MyDemo VERSION 1.0 LANGUAGES CXX) # 设置C标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 创建可执行文件 add_executable(MyDemo src/main.cpp)这段脚本的逻辑非常直白声明CMake最小版本要求定义项目名称和编程语言只用C把C标准固定为C17最后把src/main.cpp编译成一个名为MyDemo的可执行文件。5.2 在VSCode中一键式的构建与运行打开你的项目文件夹先按CtrlShiftP打开命令面板输入CMake: Delete Cache and Reconfigure执行一次重新配置。这步的目的是让CMake生成build目录和构建缓存相当于告诉CMake“我们项目长这样”。配置成功后VSCode底部状态栏会多出几个选项包括Build构建按钮。点击BuildCMake就会开始执行编译链接。如果你的代码没有语法错误几秒钟后你就会在终端看到构建完成的信息。运行方式有两种在终端里手动执行.\build\MyDemo.exe注意Windows下要用反斜杠路径。配置了上面说的launch.json后直接按F5VSCode会先自动构建因为preLaunchTask然后启动GDB调试器运行程序你可以设置断点、查看变量。我个人更推荐从第二天开始就直接用F5开发。因为F5那套东西一旦跑通你写代码→按F5→看结果的循环会非常顺畅可以省下大量切换窗口的时间。而且遇到真实项目里的崩溃、段错误GDB调起的那一瞬间你就知道前期的配置没有白弄。5.3 深入理解CMake的一个小技巧默认构建类型与输出路径CMake默认生成的构建类型是空字符串这会导致编译器不开启任何优化选项Debug和Release行为跟预期不符。我建议在CMakeLists.txt里直接声明if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug CACHE STRING Build type FORCE) endif()这段的意思是如果没有指定构建类型默认用Debug模式保留调试信息方便你调试程序。等以后需要发布Release版可以在命令行传入-DCMAKE_BUILD_TYPERelease。关于输出路径CMake Tools插件默认会把二进制生成到build目录下一般用相对路径引用即可。如果你的项目需要把exe统一输出到某个bin目录可以在CMakeLists.txt中设置set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)。这个小习惯在很多工具型项目中非常实用时间长了你就明白好处了。6. 常见报错与解决方案排查思路实录前面把该配的配完了但实际开发中报错是难免的。这一节我把这些年遇到的高频率报错整理成了一张速查表每一条都附带了排查逻辑照着做基本能解决。报错表现根因分析解决方案实战备注cmake 不是内部或外部命令CMake未加入PATH或加了但终端没重开检查PATH是否包含cmake的bin路径关掉所有终端重开CMD和PowerShell都试一遍如果CMD能用而PowerShell不行需要在PowerShell中检查其环境变量刷新机制gcc 不是内部或外部命令MinGW-w64的bin目录没加入PATH检查环境变量PATH里的D:\mingw64\bin是否拼写正确注意路径中是mingw64还是mingw解压时文件夹名经常会有出入Cannot find source file: src/main.cppCMakeLists.txt中源文件路径不对检查add_executable里的路径跟实际目录是否匹配注意路径大小写和OS对大小写的敏感度问题Windows上虽然不区分大小写但CMake有时会严格匹配undefined reference to WinMain16编译器找不到Windows程序入口如果是控制台程序检查main函数签名是不是int main()或int main(int, char**)不能是void main()有时链接器还会报这个是因为项目里没有任何源文件定义了main函数检查CMakeLists里是否漏加了源文件cannot open output file MyDemo.exe: Permission denied上次运行的程序还在占用exe关闭正在运行的程序窗口或者结束进程管理器里对应的进程我最常犯的错误是开着调试会话没关直接重新构建狂按Build也没用先停掉调试再构建This file requires compiler and library support for the ISO C 2017 standardCMake里C标准没设或编译器版本过旧在CMakeLists.txt里加set(CMAKE_CXX_STANDARD 17)更新GCC版本实测下来GCC 13.0以上对C20支持才比较完整老版本GCC频繁出现标准库报错中文输出乱码源码编码与Windows终端代码页不一致在CMakeLists.txt中给编译选项加上-finput-charsetUTF-8 -fexec-charsetUTF-8或者在main函数开头执行SetConsoleOutputCP(CP_UTF8)这个坑在Windows上几乎人人都会踩我建议写代码时用UTF-8 with BOM配合终端里chcp 65001Failed to launch debuggerlaunch.json里miDebuggerPath路径错误或未安装GDB确认MinGW-w64的bin目录下有gdb.exe并将其路径填入新版MinGW-w64发行版一般自带GDB如果不带额外下载GDB 15版本即可6.1 “cmake无法识别”的深层排查思路上面表格里也说了“cmake不是内部或外部命令”的第一层解决办法但有时候你会发现PATH里明明有终端里就是报错。这种情况有两种可能第一种是你用的是PowerShell而PowerShell的PATH是从注册表里读取的如果你是通过“编辑系统环境变量”的方式改了PATHPowerShell通常能识别到但如果你直接改的用户变量PowerShell会有权限缓存导致在新开的窗口里依然看不到最新值。解决办法是强制刷新环境变量或者干脆重启电脑最直接。第二种更阴间你同时装了两个版本的CMake一个在C:\Program Files\CMake\bin另一个可能被某个软件塞进了C:\Windows\system32而PATH里system32的优先级更高。这时候命令行里敲cmake --version看到的可能是旧版本运行起来就会有各种奇怪行为。实锤方式用where cmake查看实际解析到的是哪个路径。6.2 编译器相关报错从源头减少90%问题编译器类报错里最让我无语的不是什么语法错误而是“编译器版本和项目配置不匹配”。比如你的CMakeLists里写了project(MyDemo LANGUAGES CXX)但CMake在配置阶段找到一个gcc却找不到g就会报找不到编译器。检查方法在终端单独验证g --version如果能输出版本那么CMake配置也应该能自动找到。还有一个高频坑很多人的MinGW-w64是从国内各种“绿色版”“免安装版”下载的解压后确实能编译但没有带上完整的C标准库头文件。这样的编译器在编译带#include iostream的代码时会报找不到头文件。建议去正规镜像重新下载完整版这个不要图省事。6.3 链接错误的类型与破解思路链接错误是C/C初学者接触到的第一道综合性难题。我观察下来绝大多数可以归结为两类符号未定义和符号重复定义。符号未定义的典型场景是你写了foo()函数的声明但没有实现或者用了一个第三方静态库但忘了在CMakeLists里加target_link_libraries。排查思路是看错误信息里那个undefined reference to xxx里带不带v开头如果是vtable for xxx一般是虚函数没有实现如果是普通函数那就去检查对应源文件有没有参与编译链接。符号重复定义一般是你在头文件里写了函数实现然后多个源文件包含这个头文件导致链接器看到同一个符号被定义了多次。解决办法函数实现移到.cpp或者加inline关键字或者用static限定为文件内可见。6.4 闪退问题为什么我的程序一运行就消失Windows下双击exe一闪而过的经典问题在VSCode里也会让你头疼按了F5运行窗口出现几毫秒就关闭你根本来不及看到输出。这个问题的根因是程序正常执行完main函数退出了所有打印信息一闪而过。解决办法有三种在main函数末尾加一个std::cin.get()阻塞等待回车。用VSCode的调试模式F5GDB停住后控制台是停留在调试界面里的。在CMakeLists里定义编译宏比如add_compile_definitions(_WIN32_WINNT0x0A00)之类的不解决根本问题真正管用的是在main前包装一层系统调用system(pause)但这玩意在正式代码里最好不要出现会被同事骂的。我个人的习惯是学习阶段为了看效果会在return 0之前加std::cin.get()做正式项目时用调试器。这样既能快速看到结果又不污染代码。6.5 Windows 11特定问题终端字体与驱动兼容有几个热词我注意到是关于Windows 11上特定设备不能使用的问题比如CH340串口芯片在Windows 11下被识别成未知设备。这虽然不是C编译环境的问题但很多玩嵌入式开发的同学是同一批人经常卡在“程序编译好了但板子连不上”。如果你的板载串口识别异常先从设备管理器里确认是“CH340”还是“PL2303”然后去芯片厂商官网下载签名版最新驱动不要用Windows自动搜驱动那个经常匹配到旧签名版本导致被系统拒掉。另外Windows 11的终端默认使用新版的Windows Terminal有些用户反馈在旧版终端中正常显示的UTF-8字符到新版终端里出现乱码。建议直接在Windows Terminal设置里将默认编码改成UTF-8或者在你的main函数中调用SetConsoleOutputCP(65001)来显式设置代码页。6.6 报错排查的通用心法读错误信息的前三行这部分算是我送给大家的私房经验。很多新手一看到终端里一大片红色英文就开始慌其实是不知道“重点读哪里”。编译器的错误信息是有规律可循的第一行通常是错误类型和文件名行号第二行是具体错误描述第三行可能带一个^符号指向出错的代码位置。所以当报错信息糊你一脸的时候不要从头读到尾跳着读前三个“error:”把每个error对应的文件路径和行号记下来再去代码里找。记住编译器的错误信息是按时间顺序打印的最早的错误往往是真正的根因后面的错误经常是前面的错误引发的连锁反应。所以看到一个莫名其妙的错误时先往上翻找到最早的error那才是真正的元凶。7. 尾声我踩了半年坑之后的心得配置这套环境的初衷其实就是想让开发这件事变得“轻”。我用Visual Studio写过项目也用过CLionImpressive的是Visual Studio在大型项目里的调试体验但每次启动那缓慢的加载过程确实有点消磨耐心。后来换到VSCode CMake MinGW-w64这套轻量组合给我的感觉是启动快、占资源少、而且配置文件完全由自己掌控出了问题我能知道它为什么出问题这比在黑盒式的IDE里乱点有用得多。现在我在Windows上的日常开发流程已经非常固定新建项目 → 写CMakeLists → 在VSCode里按F5直接进调试。整个流程一气呵成再也不用在“折腾环境”这件事上浪费一分钟。希望这篇文章能让你也达到这个状态。最后再说一个小技巧找个周末的下午把这篇文章里的配置流程从零到尾自己完整走一遍不要复制我的文件尽量自己敲一遍路径、配置、写CMakeLists。只有亲手配置过一次你才会真正理解每个环节的意义。当你以后换新电脑基本十分钟就能把环境恢复原样这个能力比代码本身值钱多了。
返回列表