在 VS Code 里写 C/C++:Windows + WSL2 双环境搭建指南

发布时间:2026/6/25 14:22:52
在 VS Code 里写 C/C++:Windows + WSL2 双环境搭建指南 在 Windows 上写 C/C大多数刚刚开始接触计算机的学生或者是平时不咋写c/cpp的人的第一反应是装个 Dev-C 或者 Visual Studiovs2022可能很多初接触计算机的大学生会在网上看到推荐不过现在可能都是vs 2026了哈哈dev-c更是经典各种算法比赛的指定编译器和大一初次接触c语言学校电脑装的编译器但如果你写的代码涉及fork()、pthread_create()这类 POSIX 接口Windows 原生编译器是编译不过的——这些是 Linux 系统调用Windows 根本没有对应的实现。反过来如果你只装了 WSL 里的 GCC写 Windows APIwindows.h、CreateProcess也跑不起来。比较高效的做法是Windows 侧装 MinGW GCC 处理原生代码WSL2 侧装 GCC 处理 POSIX 代码VS Code 作为统一编辑器两边都能编译调试。这篇文章记录从零开始搭建这套环境的完整路径以及过程中容易搞混的几个概念。动手之前要理清的几个概念POSIX 和 Windows 是两套体系POSIX 是一套 Unix/Linux 系统 API 标准。fork()创建进程、pthread管理线程、semaphore.h做同步、sys/ipc.h做进程间通信——这些接口只存在于 Linux/Unix 系统中。Windows 有自己的一套CreateProcess创建进程、CreateThread创建线程、CreateSemaphore做同步。两套代码不能交叉编译。写 POSIX 代码必须有 Linux 编译环境写 Windows API 代码必须有 Windows 编译器。Dev-C 的局限Dev-C 内置的编译器是 MinGW GCC能编译标准 C/C 和 Windows API 代码。但它不带 POSIX 头文件pthread.h、sys/ipc.h这些会直接报找不到。如果你只写 Windows 侧的代码Dev-C 够用如果还要写 POSIX 代码它解决不了问题。EasyX 是什么EasyX 是一个 Windows 图形库封装了initgraph()、circle()、setfillcolor()这些函数让 C 程序能画窗口、画图形。它主要在国内高校教学中使用是对 Turbo C 时代graphics.h的现代替代。EasyX 只支持 Visual Studio 和 Dev-C不支持 MinGW 命令行编译。如果你的项目不需要图形界面完全用不到它。即使需要也建议先确认有没有更通用的替代方案比如 SDL。MSYS2、MinGW、pacman 的关系这是最容易被绕晕的一组概念。简单说MSYS2 安装器 包管理环境类比一个应用商店 | -- pacman 包管理器负责下载安装软件类比apt | -- MinGW-w64 通过 pacman 安装的 GCC 工具链类比gcc 软件包 | -- gcc / g / gdb 编译器本体MSYS2 本身不带编译器。装完 MSYS2 你得到的是一个终端和 pacman 这个包管理器。需要用 pacman 执行一条安装命令才会把 gcc 下载到本地。打个比方MSYS2 是 Steampacman 是 Steam 的下载功能MinGW GCC 是你要下载的游戏。装了 Steam 不代表你有游戏还得点安装。ucrt 和 msvcrt 的区别在 MSYS2 里装 gcc 时会看到两个版本前缀mingw-w64-ucrt-x86_64-gcc和mingw-w64-x86_64-gcc。区别在于 C 运行时库ucrtUniversal C RuntimeWindows 10 自带的新版运行时和 Visual Studio 用的是同一套msvcrtMicrosoft Visual C Runtime老版运行时兼容性更广但功能较旧新项目选 ucrt 就对了。Windows 侧安装 MinGW GCC第一步安装 MSYS2从 msys2.org 下载安装包安装到默认路径C:\msys64。安装完成后会弹出 MSYS2 MSYS 终端。第二步用 pacman 安装 gcc在 MSYS2 MSYS 终端中输入pacman-Smingw-w64-ucrt-x86_64-gcc注意终端类型管理软件包要用MSYS2 MSYS终端不要选 UCRT64 终端。UCRT64 终端是用来使用编译器的不是用来安装编译器的。包名各段含义片段意思mingw-w64GCC 的 Windows 移植版ucrt使用 Universal C Runtimex86_6464 位架构gccGNU C/C 编译器安装完成后编译器位于C:\msys64\ucrt64\bin\gcc.exe。第三步添加 PATH 环境变量Win S搜索环境变量打开编辑系统环境变量点环境变量在用户变量中选中Path点编辑点新建填入C:\msys64\ucrt64\bin确定保存注意两点添加的是目录路径C:\msys64\ucrt64\bin不是C:\msys64\ucrt64\bin\gcc.exe。PATH 的工作方式是系统在目录下找可执行文件不需要指定到具体.exe用户变量就够了不用动系统变量第四步验证新开一个cmd 或 PowerShell 窗口旧窗口读不到新的 PATH输入gcc --version能看到版本号即安装成功。踩坑记录终端选错MSYS2 安装后在开始菜单里有好几个入口——MSYS2 MSYS、MSYS2 UCRT64、MSYS2 MINGW64 等。pacman 命令只能在 MSYS2 MSYS 终端里用UCRT64 终端里会报command not found。两者的分工是MSYS 管理软件包UCRT64 使用编译器。包名粘贴带乱码从网页或聊天工具复制命令到终端时可能带入不可见的 Unicode 字符。终端会把这些字符当成命令名的一部分报command not found。遇到这种情况手打一遍就行。包名中间的空格mingw-w64-ucrt-x86_64-gcc是一个完整的包名。如果在x86_64和gcc之间加了空格pacman 会把它当成两个包第一个不存在就报target not found。Linux 侧WSL2 GCC前提WSL2 已安装如果还没装 WSL2在管理员 PowerShell 里执行wsl--install安装完重启会自动装好 Ubuntu。安装编译器打开 WSL 终端或在 PowerShell 里执行wsl运行sudoaptupdatesudoaptinstall-ybuild-essentialbuild-essential是一个元包包含gcc/g— C/C 编译器make— 构建工具libc6-dev— C 标准库开发头文件装完后pthread.h、semaphore.h、sys/ipc.h、sys/shm.h、unistd.h等 POSIX 头文件全部可用不需要额外安装任何东西。验证gcc--version编译 POSIX 代码涉及多线程的代码需要链接 pthread 库gcc program.c-oprogram-lpthread不加-lpthread会报undefined reference to pthread_create之类的链接错误。VS Code 插件配置C/C 插件在 VS Code 扩展面板CtrlShiftX搜索 “C/C”安装微软官方的那个。它的作用语法高亮没有它.c文件是纯白文本代码补全和智能提示红色波浪线标记编译错误F5 一键调试WSL 插件搜索 “WSL”安装微软官方的 WSL 扩展。不装这个插件也能在 VS Code 终端里手动切到 WSL shell 执行编译但体验是割裂的不装 WSL 插件装 WSL 插件文件浏览器看 Windows 文件看 WSL 里的 Linux 文件IntelliSense用 MinGW 的 gcc 分析代码用 WSL 的 gcc 分析代码调试器跑在 Windows 上跑在 WSL 里写fork()报红线吗报因为 MinGW 没有不报WSL gcc 认识装了之后VS Code 左下角会出现绿色图标点在 WSL 中重新打开整个编辑器就切换到 Linux 模式。IntelliSense、调试器、终端全部基于 WSL 的 gcc信息一致。关于 VC6.0有些教程会推荐 VC6.0Visual C 6.01998 年的软件作为 C/C 入门 IDE。网上还有各种免安装绿色版。几个事实免安装只意味着跳过了 setup 向导运行时仍然会往注册表写入 COM 组件注册、文件关联等信息VC6.0 的编译器对 C99 标准支持不完整变量必须在函数开头声明、//单行注释可能报错它的调试器、代码补全功能和 VS Code C/C 插件相比差了一个时代MinGW GCC 支持最新的 C/C 标准命令行编译简洁直接。配合 VS Code 后编辑、补全、调试的体验远好于 VC6.0。不值得花时间在二十年前的工具上。总结整个环境搭建可以压缩为三步WSL 里一条命令sudo apt install -build-essentialMSYS2 里一条命令pacman -S mingw-w64-ucrt-x86_64-gcc再加一条 PATHVS Code 装两个插件C/C 和 WSL真正容易卡住的不是操作步骤而是搞清楚 MSYS2、MinGW、pacman 之间的关系以及 POSIX 代码和 Windows API 代码为什么不能用同一个编译器编译。理清这些概念之后剩下的就是敲命令的事。