FEATURED · 精选文章

MinGW-w64版本名详解:从x86-64到UCRT,手把手配置VSCode C/C++环境

发布时间 / 2026/9/7 2:31:16
来源 / 创域科博编辑部
栏目 / 资讯中心
MinGW-w64版本名详解:从x86-64到UCRT,手把手配置VSCode C/C++环境 简介MinGW-w64 x86-64 15.2.0 正式版工具链面向64位Windows平台上的C/C开发者和跨平台项目维护者。该版本引入SEH结构化异常处理与UCRT通用C运行时并针对Visual Studio 2019提供RT v13修订使编译生成的程序具备更好的稳定性与Windows兼容性。整个资源包共2000个文件、173.71MB以C/C头文件h/hpp、Python脚本py和Shell辅助脚本sh为主另有少量CSS、HTML、JSON、Markdown等辅助文件内容覆盖GCC/G编译器、调试与构建工具以及sqlite3、AVX512等常用开发头文件。解压后即可获得一套完整的本地编译环境尤其适合不愿忍受GitHub慢速下载、需要快速搭建Windows工具链的中高级开发者。目前已有743人浏览学习。 如果你下载过 MinGW-w64 工具链大概率见过这类文件名mingw64-x86-64-15.2.0-release-win32-seh-ucrt-rt-v13-rev0。我第一次看到这串字符的时候也愣了一下它不是 .exe 也不是普通压缩包看起来像一堆参数拼在一起。后来用多了才明白这根本不是什么随机版本号而是把编译器最关键的选型参数全写进了文件名里目标架构、GCC 版本、线程模型、异常处理模型、C 运行时库。说白了看懂这串名字你就能判断这条工具链适不适合你的项目。这篇文章就从这串版本名拆起逐段解释每个词到底在说什么然后带你把它装进 VSCode配出一套能编译、能调试、能发布的 C/C 开发环境。不管你是刚开始学 C/C 的新手还是被各种 MinGW 分支搞晕的老开发者这篇都值得往下看。1. 这个版本名其实是一张选型清单1.1 三段式版本号架构、GCC 版本与运行时版本x86-64表示目标架构是 64 位。对应地如果你看到i686那就是 32 位版本。这个区别很直观但有个地方容易踩坑64 位编译器编出来的 .exe 在 32 位 Windows 上跑不了反过来 32 位编译器在 64 位系统上倒是能跑只不过性能吃不满也编不了需要大内存的程序。新手如果拿不准直接选 x86-64 是合理的默认选择。15.2.0是 GCC 编译器的版本号也就是这条工具链底层用的编译驱动版本。GCC 15 算是比较新的主版本了对 C23 和 C23 的支持比 14 代更完善像std::format、协程这类特性在 15.2 里已经可以直接用。rt-v13-rev0则是 MinGW-w64 项目自己维护的运行时版本号rt是 runtime 的缩写rev0表示这是第 0 次修订。你可以把 GCC 版本号理解成“发动机型号”把 rt 版本理解成“变速箱标定”两者共同决定了最终编译行为。顺带说一下MinGW-w64 并不是 GCC 官方直接发布的而是社区维护的一个 Windows 移植分支所以版本名里会出现两套版本号并存的情况。看到这种命名不要慌重点只需要关心最后三个后缀它们才是真正影响你日常开发的关键。1.2 真正决定兼容性的三个后缀win32、seh、ucrt这三个词分别对应线程模型、异常处理模型和 C 运行时库。它们在文件名里看着只是三个小单词实际上代表了三条完全不同的技术路线。后缀常见取值影响什么线程模型win32 / posix是否默认支持 C11 的 std::thread是否依赖 winpthreads 库异常处理seh / sjlj / dw2异常抛出和捕获机制影响性能和兼容性C 运行时ucrt / msvcrt链接哪个 C 标准库影响 printf 格式支持、系统版本兼容性打个比方编译器选型就像是挑一台车x86-64 是车身尺寸15.2.0 是发动机排量win32/posix 是变速箱类型seh 是刹车系统ucrt 是油箱规格。光看排量没用刹车和油箱选错了车照样开不顺。2. 为什么我建议先搞清楚线程模型再动手2.1 win32 线程模型省依赖但限制 C 线程库这个版本文件名里的win32指的不是 32 位系统而是线程模型。MinGW-w64 的线程模型分为 win32 和 posix 两类win32 模型的意思是GCC 的 C 标准库libstdc在编译时关闭了 C11 线程支持想用多线程只能直接调用 Windows APICreateThread 那套或者自己下载第三方 pthread 库。如果你在 VSCode 里敲了这样一段代码#include thread #include iostream int main() { std::thread t([] { std::cout hello std::endl; }); t.join(); return 0; }然后用这个 win32 线程模型的编译器去编译很可能会看到这样的报错fatal error: thread: No such file or directory或者链接阶段出现一堆undefined reference to pthread_create之类的错误。原因就是线程模型不对标准库根本没提供这个头文件。这不是 VSCode 配错了而是工具链本身就不支持。posix 线程模型则是在 Windows 线程基础上封装了一层 pthread 兼容层让std::thread、std::mutex、std::condition_variable这些 C 标准线程组件可以工作。代价是编译出的程序通常需要附带一个libwinpthread-1.dll或者在编译时静态链接进去。所以如果你计划写多线程 C 代码尤其是一开始学并发编程直接选 posix 版本会少走很多弯路。2.2 异常模型对 64 位项目几乎只有一个正确答案异常处理模型这边seh是 Structured Exception Handling结构化异常处理这是 Windows 操作系统原生支持的异常机制。64 位程序在 Windows 上使用 SEH 几乎是不二之选因为 x64 架构下 Microsoft 的 C/C 编译器默认就是这套模型GCC 采用 SEH 后跨语言、跨编译器的异常兼容性最好性能也最稳定。另外两个选项是 sjlj 和 dw2sjlj 基于 setjmp/longjmp没什么平台限制但性能吃亏异常抛出路径会拖慢整个程序dw2 依赖 DWARF 调试信息展开栈帧在 32 位 Linux 上很常见但在 Windows 32 位程序里兼容性没那么好。很多老教程会教人“64 位选 seh32 位选 sjlj 或 dw2”这个经验到今天依然成立。版本名里的 seh 说明发布者已经帮你把最合理的选项定好了直接用就行。3. UCRT 运行时到底改了些什么3.1 MSVCRT 的历史包袱与 UCRT 的现代化ucrt是 Universal C Runtime 的缩写。在 UCRT 出现之前MinGW-w64 默认链接的是 MSVCRT那是 Visual C 6.0 时代定下来的 C 运行时库年代久远对 C99 之后的标准支持非常残缺。最直观的例子是printf家族函数。MSVCRT 的printf对%zusize_t 专用格式和%lldlong long的支持是有问题的已经进入 C99 标准很多年了它依然不完善。MinGW-w64 靠内部实现__mingw_printf来弥补但涉及到第三方原生库时坑还是不少。UCRT 是微软在 Windows 10 时代重新设计的通用 C 运行时底层实现了完整的 C99/C11 格式化输入输出%zu、%lld、十六进制浮点这些都能正确工作。如果你经常跟文件流、字符串格式化打交道从 MSVCRT 换到 UCRT 的感受会非常明显。之前需要各种 workaround 的代码换成 UCRT 版本后直接就能编过跑对。3.2 系统兼容性与部署时要不要带 DLLUCRT 并不是所有 Windows 版本都原生自带的。Windows 10、Windows 11 以及 Windows Server 2016/2019/2022 都默认包含 UCRT但在 Windows 7 和 Windows 8.1 上微软提供过补丁比如 KB2999226系统没装这个补丁就可能提示缺少ucrtbase.dll。如果你的目标用户里有大量老系统这一点必须提前想清楚。还有一种极端情况是你在做绿色软件希望拷一个 exe 到任何机器上双击就能跑。用 UCRT 版编译的程序目标系统必须已经具备 UCRT 运行时否则就需要分发 DLL。相比之下 MSVCRT 在绝大多数 Windows 系统上都是存在的老兼容性更好但功能残缺。我的建议是个人学习和开发优先上 UCRT不用为历史包袱买单做需要广撒网分发的商业软件反而要评估一下目标系统的 Windows 版本分布。编译发布版的时候可以在 g 命令里加-static-libgcc -static-libstdc把 GCC 自己的支持库静态链接进 exe减少对libgcc_s_seh-1.dll、libstdc-6.dll这些 DLL 的依赖。对于 win32 线程模型版本通常连libwinpthread-1.dll都不会有发布起来更清爽。4. 在 VSCode 里把这条工具链真正跑起来4.1 解压安装与编译器验证拿到mingw64-x86-64-15.2.0-release-win32-seh-ucrt-rt-v13-rev0之后先把压缩包解压到一个没有中文和空格的路径比如C:\mingw64。然后把这个目录下的bin文件夹路径加入系统 PATH 环境变量这样在终端里直接敲gcc就能调用。打开新的终端改了 PATH 之后必须重开执行gcc --version g --version gdb --version如果都能打印出版本信息就说明工具链基本可用了。这里有个小坑PATH 里如果有多个版本的 MinGW命令会优先命中前面的那个。建议把这条 UCRT 版本放在前面或者在 VSCode 里用绝对路径指定编译器别让环境变量替你瞎猜。4.2 三个关键配置文件properties、tasks 和 launchVSCode 配 C/C 开发环境本质就是配好三个 JSON 文件。第一个是.vscode/c_cpp_properties.json它是给 IntelliSense 智能提示用的告诉编辑器头文件在哪、用哪个编译器、按什么标准提示{ configurations: [ { name: Win64, includePath: [ ${workspaceFolder}/**, C:/mingw64/include, C:/mingw64/lib/gcc/x86_64-w64-mingw32/15.2.0/include/c ], compilerPath: C:/mingw64/bin/g.exe, cStandard: c17, cppStandard: c17, intelliSenseMode: windows-gcc-x64 } ], version: 4 }第二个是.vscode/tasks.json负责编译。下面这个配置把当前打开的文件编成同名 exe并且把 GCC 支持库静态链接进程序{ version: 2.0.0, tasks: [ { label: build active file, type: cppbuild, command: C:/mingw64/bin/g.exe, args: [ -fdiagnostics-coloralways, -g, -stdc17, ${file}, -o, ${fileDirname}/${fileBasenameNoExtension}.exe, -static-libgcc, -static-libstdc ], options: { cwd: ${fileDirname} }, problemMatcher: [$gcc], group: { kind: build, isDefault: true } } ] }第三个是.vscode/launch.json负责调试{ version: 0.2.0, configurations: [ { name: Debug C/C, type: cppdbg, request: launch, program: ${fileDirname}/${fileBasenameNoExtension}.exe, args: [], stopAtEntry: false, cwd: ${fileDirname}, environment: [], externalConsole: false, MIMode: gdb, miDebuggerPath: C:/mingw64/bin/gdb.exe, preLaunchTask: build active file, setupCommands: [ { description: Enable pretty-printing for gdb, text: -enable-pretty-printing, ignoreFailures: true } ] } ] }如果你要写 C20 或 C23记得把tasks.json里的-stdc17换成对应的标准。这里最容易忽略的是compilerPath和miDebuggerPath必须指向同一个 MinGW 安装目录否则可能出现“智能提示是 A 版本、编译器是 B 版本、调试器是 C 版本”的混乱状态。4.3 中文乱码问题与终端编码用 VSCode 写 C/C中文乱码基本是必经之劫。根源在于 Windows 终端默认代码页是 936GBK而 VSCode 编辑器默认按 UTF-8 读取源码。两者对同一串字节的解释不一致控制台输出就变成了乱码。最简单的处理方法是让终端和源码统一到 UTF-8。在launch.json的environment里加不了chcp指令我会在tasks.json的编译任务前通过 VSCode 终端手动执行或者在源码开头写上#include windows.h int main() { SetConsoleOutputCP(CP_UTF8); std::cout 中文输出测试 std::endl; return 0; }这个函数会强制把当前进程的标准输出切到 UTF-8 代码页比每次手敲chcp 65001省事得多。如果仍然乱码再看一下源文件保存时是不是 UTF-8 with BOMVSCode 右下角可以切换编码统一成 UTF-8 之后基本不会再出问题。5. 我实际踩过的坑与选型建议5.1 一次印象深刻的 pthread 链接失败我之前图省事用 win32 线程模型写了一个多线程网络小工具。代码本身没问题std::thread也没用用的是 Windows API 的CreateThread所以编译一直正常。后来同事把一段带std::mutex的模块丢进来一编译就报错错误信息翻到最后只有一句undefined reference to pthread_mutex_lock排查了很久才发现根本不是代码问题而是这条 win32 线程模型的工具链根本不带 pthread 兼容层。临时解决方案是把所有std::mutex改成CRITICAL_SECTION最后还是换成了 posix 线程模型的 MinGW 版本才彻底解决。那次之后我学乖了不管是写自己的项目还是编译第三方库先确认库依赖的线程模型和运行时再决定用哪条工具链。5.2 什么情况下你应该换其他后缀的版本没有哪个 MinGW-w64 版本是万能的选型完全取决于项目性质。如果你只是写纯 C 算法练习、或者写不涉及线程的 C 小工具这个win32-seh-ucrt版本非常合适依赖少、启动快、发布简单。但如果你是下面这几类情况建议换个后缀再下载项目里直接用std::thread、std::mutex、std::future优先选posix线程模型版本。要编译 Qt、Boost 这类重度依赖 pthread 语义的库同样选 posix 版本。目标用户是 Windows 7 老系统而且不能保证系统补丁齐全考虑 msvcrt 版本替代 ucrt。给开源项目提交构建产物先看项目 CI 用的是哪种线程模型保持工程内统一省得交叉编译时出现莫名其妙的 ABI 不一致。至于 SEH64 位下直接选 seh 就好不用纠结。最后再分享一个小技巧我安装工具链时不会把所有版本堆在一个目录里而是按后缀区分目录比如D:\toolchains\mingw64-ucrt-posix、D:\toolchains\mingw64-ucrt-win32。平时开发在 VSCode 的settings.json里就可以给不同项目指定C_Cpp.default.compilerPath随时切换不需要反复改 PATH。这样既能享受 win32 版本发布时的干净简单又在需要现代 C 并发特性时能无缝切到 posix 版本两边的好处都吃到。本文还有配套的精品资源点击获取
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻