简介:MinGW for Win64 是面向 Windows 64 位平台的 GCC 编译器工具链资源,适合希望在本地编写、编译 C++ 程序的开发者与编程学习者,尤其适合不依赖大型 IDE、偏好命令行操作的人群。压缩包为 zip 格式,整体约 156.05MB,内含 TDM-GCC-64 分支,集成 64 位 GCC 工具链,支持 C++11、C++14、C++17 及部分 C++20 特性。资源涵盖 GCC 编译器、libstdc++ 标准库、Binutils 链接与汇编工具、Make 自动化构建工具,以及开发所需的头文件与静态、动态库,可满足从源码编译到可执行程序生成的完整流程。借助它,读者能快速搭建轻量级本地开发环境,通过命令行理解编译与调试过程,并利用 STL 容器、迭代器、算法等标准库能力完成日常练习与小型项目。目前已有 115 人学习下载,适合需要稳定 GCC 支持、追求 64 位编译性能的 C++ 开发者参考使用。
1. MinGW for Win64:把 GNU 工具链塞进 Windows 到底图什么
很多人第一次在 Windows 上写 C++,装完 Visual Studio 就以为万事大吉,直到某天拿到一份只带CMakeLists.txt和一堆#include <unistd.h>的源码,MSVC 直接报错,才发现自己缺的不是 IDE,而是一整套 GNU 工具链。MinGW for Win64 就是干这个的:它把 GCC、G++、GDB、make、binutils 这一套 Linux 上常见的编译调试工具,以原生 Windows 可执行文件的形式提供出来,让你在 Win64 上不依赖任何模拟层就能编译出.exe。它解决的核心问题是跨平台源码的本地构建,适合三类人:需要编译开源 C/C++ 项目的开发者、用 Qt/CMake 做跨平台构建的工程师、以及教学场景里想让学生统一用 GCC 语法的老师。热搜里反复出现的「msvc和mingw区别」「mingw安装」「cmake与mingw」,本质上都是同一个诉求:我到底该不该用它、怎么装、怎么和现有构建系统接上。这一章先把选型逻辑讲透,后面几章再落到具体操作和踩坑。
2. 选型与安装:x86_64-w64-mingw32 和 MSVC 到底怎么选
2.1 先搞清楚 MinGW、MinGW-w64、TDM-GCC 的关系
网上搜「mingw官网下载」会跳出一堆名字相近的东西,不搞清楚很容易下错。MinGW 最早是 MinGW.org 维护的项目,只支持 32 位,更新早就停了。现在 Win64 上真正能用的是 MinGW-w64,它是一个分支项目,支持 64 位和 32 位,头文件和运行时库也更完整。TDM-GCC 则是另一套打包,把 MinGW-w64 加了一些补丁和安装器,适合不想手动配环境变量的人。你如果只是要一个能编译 64 位 C++ 的工具链,认准 MinGW-w64 就够了,别去下那个老掉牙的 MinGW.org 版本。
判断一个发行版是否靠谱,看三个东西:目标三元组是不是x86_64-w64-mingw32、GCC 版本是否在 10 以上、是否自带posix线程模型。线程模型这个参数后面会专门讲,它直接决定你能不能正常用std::thread。
2.2 两种安装路径:MSYS2 包管理和独立压缩包
安装 MinGW-w64 常见做法有两种。第一种是走 MSYS2,它本身是个类 Unix 环境,用pacman管理包,升级方便,适合长期开发。第二种是直接下独立压缩包,解压后把bin目录加进 PATH,适合只想快速编译一个项目、不想装一整套环境的人。
先看 MSYS2 这条路,命令如下:
# 安装 MSYS2 后,在 MSYS2 MINGW64 终端里执行 pacman -Syu # 先整体更新,避免包版本冲突 pacman -S mingw-w64-x86_64-gcc # 安装 64 位 GCC/G++ 工具链 pacman -S mingw-w64-x86_64-gdb # 调试器,按需 pacman -S mingw-w64-x86_64-cmake # CMake,按需这里的关键是必须在「MSYS2 MINGW64」这个终端里执行,而不是 MSYS 终端。前者产出的可执行文件是原生 Windows 程序,后者会依赖msys-2.0.dll,拷到别的机器上就跑不起来。pacman -Syu第一次执行后可能会要求关闭终端重开,这是正常的,别跳过。
独立压缩包这条路更直接:从 MinGW-w64 的发布页下载x86_64-posix-seh结尾的压缩包,解压到比如C:\mingw64,然后把C:\mingw64\bin加到系统 PATH。验证方式是开一个新的命令行窗口:
gcc --version g++ --version where g++where g++的输出应该指向你解压的那个目录。如果指向了别的路径,说明 PATH 里有旧版本,顺序不对,需要把新路径提到前面。
2.3 线程模型和异常模型:两个必须看懂的参数
下载页上那些posix-seh、win32-sjlj的后缀不是随便起的。线程模型分posix和win32:posix支持 C++11 的std::thread、std::mutex,win32不支持,用了会链接失败。异常模型分seh和sjlj:seh是 64 位下的零开销异常,性能好;sjlj兼容性好但慢。Win64 上直接选x86_64-posix-seh,这是当前最通用的组合。
| 后缀组合 | 线程模型 | 异常模型 | 适用场景 |
|---|---|---|---|
| x86_64-posix-seh | posix | seh | 推荐,支持 std::thread |
| x86_64-win32-seh | win32 | seh | 不用 C++11 线程时可用 |
| x86_64-posix-sjlj | posix | sjlj | 老代码兼容,性能差 |
| i686-posix-dwarf | posix | dwarf | 32 位场景 |
选错了会怎样?最典型的现象是编译带std::thread的代码时报undefined reference to std::thread::_M_start_thread,这就是 win32 线程模型缺符号。遇到这个报错,别去改代码,换工具链。
2.4 和 MSVC 的边界:什么时候必须换回 MSVC
MinGW-w64 不是万能的。它编译出的程序链接的是msvcrt.dll或自带的libstdc++,和 MSVC 编译的库 ABI 不兼容。也就是说,你不能拿 MinGW 编译的.a去给 MSVC 的.lib链接,反过来也不行。如果你的项目依赖某个只提供 MSVC 预编译库的第三方 SDK,那 MinGW 这条路基本走不通。反过来,如果你的项目是纯源码、依赖 CMake、要在 Linux 和 Windows 上共用一套构建脚本,MinGW 就是更省心的选择。热搜里「msvc和mingw区别」问的就是这个边界,记住一句话:源码级跨平台选 MinGW,二进制级依赖 MSVC 库就老实待着。
3. 用 CMake 把 MinGW 接进构建流程
3.1 指定编译器:别让 CMake 猜
CMake 在 Windows 上默认会去找 MSVC,你不显式指定,它就不会用 MinGW。最稳的做法是在配置阶段用-G指定生成器,并显式给出编译器路径:
cmake -S . -B build -G "MinGW Makefiles" \ -DCMAKE_C_COMPILER=C:/mingw64/bin/gcc.exe \ -DCMAKE_CXX_COMPILER=C:/mingw64/bin/g++.exe \ -DCMAKE_BUILD_TYPE=Release-G "MinGW Makefiles"告诉 CMake 用 MinGW 的 make 而不是 MSVC 的生成器。两个CMAKE_*_COMPILER变量把编译器钉死,避免 PATH 里有多个版本时选错。CMAKE_BUILD_TYPE在单配置生成器下必须显式给,否则默认是空,优化选项不会生效。配置完执行:
cmake --build build -j 8-j 8是并行编译的核数,按你机器调整。如果报mingw32-make: command not found,说明C:\mingw64\bin没进 PATH,或者你装的是独立包但没把mingw32-make.exe一起带上。
3.2 处理路径分隔符和中文目录
MinGW 工具链对反斜杠和空格比较敏感。CMake 里写路径统一用正斜杠,C:/mingw64比C:\mingw64安全。项目路径里如果有中文或空格,mingw32-make有时会在依赖解析阶段翻车,报一些看不懂的No rule to make target。血泪经验是:把项目放在纯英文、无空格的路径下,比如D:/work/myproj,能省掉一大半玄学问题。
3.3 静态链接 libstdc++ 和 libgcc
MinGW 编译出的 exe 默认动态链接libstdc++-6.dll和libgcc_s_seh-1.dll,拷到没装 MinGW 的机器上就报缺 DLL。解决办法是在链接阶段加静态链接参数:
cmake -S . -B build -G "MinGW Makefiles" \ -DCMAKE_CXX_COMPILER=C:/mingw64/bin/g++.exe \ -DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++ -static"-static-libgcc和-static-libstdc++把这两个运行时静态链进去,-static进一步把其他依赖也静态化。代价是 exe 体积变大,但换来的是单文件可分发。注意如果项目还依赖别的动态库,-static可能引起冲突,这时只加前两个参数即可。
4. 避坑与排查:那些让编译失败的常见问题
4.1 现象:undefined reference to WinMain
原因:链接器默认按 Windows 子系统找WinMain,但你写的是控制台程序main。解决:在链接参数里加-mconsole,或者检查 CMake 里有没有误设WIN32_EXECUTABLE。命令行直接编译时用g++ main.cpp -o main.exe -mconsole。
4.2 现象:中文源码编译报错或乱码
原因:MinGW 默认按 UTF-8 读源码,但 Windows 下文件可能是 GBK。解决:统一把源文件存成 UTF-8,编译时加-finput-charset=UTF-8 -fexec-charset=UTF-8。如果必须用 GBK,加-fexec-charset=GBK,但更推荐统一 UTF-8。
4.3 现象:std::thread链接失败
原因:装的是 win32 线程模型。解决:换posix线程模型的工具链,或者改用std::async规避。这个前面选型章节讲过,属于装之前就该避开的坑。
4.4 现象:CMake 缓存了旧的编译器
原因:第一次配置用了 MSVC,第二次改 MinGW,但build目录里的CMakeCache.txt还记着旧路径。解决:删掉整个build目录重新配置,别试图手动改缓存。我一般会养成习惯,换工具链就rm -rf build。
4.5 现象:mingw32-make报multiple target patterns
原因:Makefile 里混进了 Windows 盘符路径,冒号被当成目标分隔符。解决:检查 CMake 生成的路径,确保没有C:\这种写法,必要时在 CMake 里用file(TO_CMAKE_PATH ...)转换。
5. 进阶技巧:用工具链文件固化配置并验证产物
每次敲一长串-DCMAKE_CXX_COMPILER太累,也容易漏参数。更工程化的做法是写一个工具链文件mingw64.cmake,把编译器、链接参数、线程模型全固化进去:
# mingw64.cmake set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_SYSTEM_PROCESSOR x86_64) set(TOOLCHAIN_ROOT "C:/mingw64") set(CMAKE_C_COMPILER "${TOOLCHAIN_ROOT}/bin/gcc.exe") set(CMAKE_CXX_COMPILER "${TOOLCHAIN_ROOT}/bin/g++.exe") set(CMAKE_RC_COMPILER "${TOOLCHAIN_ROOT}/bin/windres.exe") set(CMAKE_EXE_LINKER_FLAGS_INIT "-static-libgcc -static-libstdc++") set(CMAKE_CXX_FLAGS_INIT "-finput-charset=UTF-8 -fexec-charset=UTF-8") set(CMAKE_FIND_ROOT_PATH "${TOOLCHAIN_ROOT}") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)用法是配置时加-DCMAKE_TOOLCHAIN_FILE=mingw64.cmake,生成器仍然用MinGW Makefiles。CMAKE_FIND_ROOT_PATH_MODE_*这几行是防止 CMake 跑到系统目录去找 MSVC 的头文件和库,属于隔离措施。CMAKE_EXE_LINKER_FLAGS_INIT和CMAKE_CXX_FLAGS_INIT用_INIT后缀,保证只在首次配置时注入,不会覆盖用户后续手动指定的参数。
配置完怎么验证产物真的没问题?我一般走三步。第一步,objdump -p build/app.exe | findstr "DLL Name"看依赖了哪些 DLL,如果只剩系统 DLL 就说明静态链接生效了。第二步,把 exe 拷到一个没装 MinGW 的干净目录双击运行,能起来才算数。第三步,g++ -v看一遍实际用的线程模型和版本,确认和预期一致。
还有一个容易被忽略的点:windres.exe是资源编译器,如果你的项目带.rc资源文件(图标、版本信息),没有它 CMake 会在链接阶段报找不到资源对象。工具链文件里把CMAKE_RC_COMPILER一起设上,能省一次排查。
从那以后我每次新建跨平台项目,都会先把工具链文件写好、把build目录加进.gitignore、换编译器前强制删缓存,这三件事走一遍再开始写代码。希望帮到你。
本文还有配套的精品资源,点击获取