简介:MinGW for Win64是一套面向Windows 64位系统的GCC工具链整合包,基于TDM-GCC-64分支优化,主要面向需要在本地编写、编译C++程序的开发者、学生与初学者,可用于替代重型IDE进行命令行编译、调试与自动化构建,技能层级覆盖入门到中高级。压缩包采用zip格式,整体约156.05MB,因上游未提供文件总数与类型明细,具体目录结构暂未列出。目前已有115人学习浏览。包内集成64位GCC、C++标准库(libstdc++)、Binutils、Make等核心组件,支持C++11/14/17及部分C++20特性,附带头文件与静态/动态库,能够帮助使用者快速搭建轻量级编译环境,深入理解预处理、编译、汇编、链接的完整过程,并获得较强的跨平台代码兼容性。相比原版MinGW,该版本更新更频繁,集成了较新的GCC与库文件,适合希望在Windows上保持标准支持与编译性能的开发者,但需注意其不包含WinAPI等Windows专属接口,深度依赖系统特性时还需配合其他方案。
1. MinGW for Win64:Windows 上跑通 C++ 编译,先把这套工具链装明白
很多 C++ 开发者在 Windows 上第一次敲g++命令时,看到的不是编译结果,而是「不是内部或外部命令」的一行红字。这不是代码写错了,而是机器上根本没有可用的 C++ 编译工具链。MinGW for Win64 要解决的正是这个问题:在 64 位 Windows 上原生编译 C++ 程序,不需要打开虚拟机、不依赖任何 IDE,解压配置好之后直接用命令行跑通编译。适合用 VSCode 写 C++ 的学生、需要跨平台编译的从业者,以及想在 Windows 上复现 Linux 编译行为的人。本文从选型、安装、配置到避坑,把这份工具链从压缩包变成可用的编译环境。
2. 选型先于安装:MinGW-W64 和 MSVC、类 Unix 环境差在哪
2.1 三大 C++ 工具链阵营怎么分
Windows 上编 C++ 常见有三条路:Windows 官方工具链(MSVC 及其配套 IDE)、类 Unix 兼容环境、以及 MinGW-W64 这套面向 Windows 的原生 GCC 移植。三条路都能编出 exe,但生成物和依赖关系完全不是一回事。
MSVC 的cl.exe编出来的程序依赖官方运行时,在装有对应版本的 Windows 上通常没问题,但命令风格和 Linux 下的 GCC 差异很大,很多开源项目的 Makefile 在 MSVC 下没法直接跑。类 Unix 环境下编译出的程序通常要带着整套兼容层的动态库才能运行,做完的 exe 拷贝到别的 Windows 机器上容易缺 dll。MinGW-W64 则是一套直接用 Windows API 的 GCC 移植版,编出来的 exe 依赖系统自带的 kernel32 等基础库,分发出去不需要额外安装运行时。
从纯 C++ 开发和交叉编译的角度讲,MinGW-W64 最大的优势是「命令行为和 Linux 下的 g++ 几乎一致」。同一套-std=c++17 -O2 -Wall参数在两个平台都能跑,Makefile 基本不用改就能在 Windows 上执行。我用表格把三个方向的主要差别列一下:
| 对比项 | 官方工具链 | 类 Unix 兼容环境 | MinGW-W64 |
|---|---|---|---|
| 生成 exe 的依赖 | 官方运行时 | 兼容层动态库 | 系统基础 dll |
| 命令风格 | cl.exe 专有参数 | UNIX 风格完整 | 类 UNIX 风格 |
| 跨平台编译 | 仅限 Windows | 跨平台但依赖重 | Windows 原生二进制 |
| 适用场景 | 大型 Windows 应用 | 从 Linux 迁移的旧工程 | 轻量开发、CI、教学 |
MinGW-W64 不是性能上碾压谁,而是「低成本、低依赖、接近 Linux 习惯」。很多开源库在 Windows 上编译首选它,就是因为 CMake 里只需要指一下生成器和编译器路径,剩下的流程和 Linux 完全一致。
2.2 线程模型与异常模型:选错一个,后面全是坑
下载 MinGW-W64 时,压缩包名字里通常会带两个关键标识:线程模型和异常模型。这两个参数决定了工具链能不能正常支持 C++11 之后的 std::thread,以及异常处理在运行时怎么实现。
线程模型常见的是 posix 和 win32。posix 版本内部通过 Windows 线程实现 POSIX 线程接口,能完整支持std::thread、std::mutex这类 C++11 线程库;win32 版本更轻量,但在较老的 GCC 版本里对 C++11 线程支持不完整,编译带std::thread的代码很可能直接报错。我一般无脑选 posix,付出的成本是编译出的程序在运行时可能多依赖一个libwinpthread-1.dll,这个后续可以通过静态链接解决。
异常模型常见的是 seh 和 sjlj。seh 是 64 位 Windows 原生的结构化异常处理,性能好、栈回溯准确,但只适用 x86_64 架构;sjlj 通过 setjmp/longjmp 实现,能同时跨 32/64 位,但性能略差。64 位环境下优先选 seh,32 位只能用 sjlj 或者 dwarf。这个参数编译时看不出差别,但程序崩溃时栈回溯的信息完整度会不一样,调试阶段才体现得出来。
2.3 确定目标架构:x86_64 与 i686 的边界
MinGW-W64 的压缩包命名里还有架构标识,x86_64 表示 64 位目标,i686 表示 32 位目标。64 位版本的编译器默认编出 64 位 exe,32 位版本默认编出 32 位 exe。现代机器上建议直接装 x86_64 版本,并确认操作系统是 64 位。
有人会想:装了 64 位工具链,加个-m32参数能不能编 32 位程序?答案是大部分情况下不能。MinGW-W64 的 64 位工具链默认不附带 32 位运行库和头文件,加了-m32会报找不到头文件。要编 32 位程序就单独下 i686 版本,或者装完整的多库版本。这是个典型的环境边界,别在这上面浪费时间去试,翻车概率极高。
3. 安装与环境变量:从压缩包到跑通 g++ 的三步
3.1 下载什么文件:压缩包命名规则
MinGW-W64 的官方发布包里,文件名一般长这样:x86_64-posix-seh这种格式,含义就是 64 位架构、posix 线程模型、seh 异常模型。如果你要完整版,有些发布包还会带-crt之类的标识。下载时优先选 x86_64 开头的稳定版本,认准文件名里的这三个标识就够了。
文件一般是 7z 或 zip 压缩包,解压后是一个完整的工具链目录,里面有 bin、lib、include、libexec、share 这几个核心文件夹。bin 目录下放着g++.exe、gcc.exe、mingw32-make.exe等可执行文件;include 是 C/C++ 头文件;lib 是标准库的静态库和导入库。整个目录可以随意放到任意盘符,不需要管理员权限。
这里有一个我自己的习惯:把解压后的目录单独放在一个没有空格和中文的路径下,比如C:\mingw64。后面配置环境变量、写 Makefile 时都能少很多转义和编码问题。
3.2 解压与 PATH 配置
解压完成后,把bin目录的路径加到系统环境变量 PATH 里。在 cmd 里可以这样临时设置:
set PATH=C:\mingw64\bin;%PATH%临时设置只对当前窗口生效,关掉就没了。要持久生效,用 setx 写进用户环境变量:
setx PATH "C:\mingw64\bin;%PATH%"注意 setx 会把当前 PATH 值读出来再写回去,如果 PATH 太长超过 1024 字符,setx 有截断风险。我一般建议去系统设置里的环境变量编辑界面手动新增一条,虽然多一步点击,但比命令行更稳妥。
配置完 PATH 之后,所有新开的 cmd 或 PowerShell 窗口才会读到新值,已经开着的旧窗口里执行g++仍然会报找不到命令。这个不是配置失败,是终端没有刷新环境变量,别反复重装。
3.3 验证安装:三条命令确认工具链可用
配置完 PATH,先跑三条命令确认基础环境:
g++ --version gcc --version where g++--version输出 GCC 的版本号,能看到就说明编译器本体可以执行;where g++会输出 g++ 的实际路径,确认 PATH 指向的是你刚解压的那个目录。如果where输出多个 g++ 路径,说明机器上装过多个 MinGW 版本,后面编译时要用which g++仔细确认当前生效的是哪一个。
到这一步,工具链已经能用了。注意这两条命令只验证了 g++ 和 gcc 存在,没验证 make 工具。MinGW-W64 自带的 make 一般叫mingw32-make.exe,因为 Windows 上可能装了其他品牌的 make,直接用make命令可能指错。这个差异后面实操时会遇到。
4. 第一个 C++ 编译任务:从 hello 到带参数的生产编译
4.1 单文件编译的常见命令组合
写一个最简单的 hello.cpp,内容就是标准输出一行字符。编译命令:
g++ -std=c++17 -O2 -Wall -o hello.exe hello.cpp这条命令里-std=c++17指定用 C++17 标准;-O2开优化;-Wall打开常见警告;-o hello.exe指定输出文件名;最后的源文件是hello.cpp。编译完当前目录下会生成 exe,直接命令行执行hello.exe就能看到输出。
新手阶段很多人只写g++ hello.cpp,这样也能编出默认名 a.exe,但生产环境里-std、-O2、-Wall这三个参数几乎是默认套餐。-Wall不是把警告当错误,只是把可疑代码提示出来,建议永远不要省。
如果是在 Windows 上和 Linux 双平台切换开发,这套命令在两边完全一致。唯一的差别是输出文件名后缀:Windows 显式写成.exe,Linux 下可以直接-o hello。
4.2 多文件与 Makefile 的最小配合
项目拆成多个 cpp 之后,单条 g++ 命令会把所有源文件一起编译链接:
g++ -std=c++17 -O2 -Wall -o app.exe main.cpp utils.cpp多个 cpp 文件直接列在命令里,g++ 会分别编译再链接。文件多了之后命令行越来越长,这时候用 Makefile 更合适。MinGW-W64 环境下的最小 Makefile 长这样:
CXX = g++ CXXFLAGS = -std=c++17 -O2 -Wall TARGET = app.exe SRCS = main.cpp utils.cpp $(TARGET): $(SRCS) $(CXX) $(CXXFLAGS) -o $@ $^ clean: del $(TARGET)注意 Makefile 里$(TARGET):下面的命令行必须以 Tab 开头,不能用空格代替,这是 Make 工具的硬性要求,也是新手经常翻车的点。在这个目录下执行:
mingw32-make它会自动找 Makefile,读依赖关系,把 main.cpp 和 utils.cpp 编成 app.exe。执行mingw32-make clean会调用del删除 exe,这里用的是 Windows 的 del 而不是 Linux 的 rm,是因为当前环境是 Windows shell。
mingw32-make是 MinGW-W64 自带的 make 程序名。如果你手头只有 Linux 下的 Makefile 要在 Windows 上跑,大概率不用改语法,只需要把执行命令从make换成mingw32-make。
4.3 CMake 指认 MinGW 编译器的一行参数
实际项目里直接用 Makefile 的不多,CMake 是更主流的构建工具。在 Windows 上用 CMake 配合 MinGW-W64,关键是指定生成器为 "MinGW Makefiles",并显式给出编译器路径:
cmake -G "MinGW Makefiles" -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Release ..这条命令在 build 目录下执行,-G "MinGW Makefiles"让 CMake 生成适配 mingw32-make 的构建脚本;-DCMAKE_CXX_COMPILER=g++指定 C++ 编译器;..指向源码目录。配置完成后,执行:
cmake --build .CMake 会自动调用 mingw32-make 完成构建并输出 exe。这里有个常见错误:有人直接执行cmake ..,CMake 默认选择 Visual Studio 生成器,后面再 build 就会去找 MSVC 的 cl.exe,导致一堆编译参数不兼容。解决方案就是构建前明确-G "MinGW Makefiles",简单粗暴。
如果 CMake 报找不到 g++,通常是 PATH 没生效或者 CMake 缓存了之前的编译器路径。可以删掉 build 目录重新配置,这一步能解决绝大多数 CMake 和 MinGW 配合的问题。
5. 避坑记录:MinGW-W64 最常见的六个翻车现场
5.1 g++ 不是内部或外部命令
现象:新开的命令行窗口里执行g++ --version,报错「g++ 不是内部或外部命令,也不是可运行的程序或批处理文件」。
原因:PATH 环境变量没有包含 MinGW-W64 的 bin 目录,或者改完 PATH 之后没有开新窗口。还有一个容易忽略的场景:系统里有多个 MinGW 版本,PATH 里靠前的那个目录里没有 g++。
解决:先确认C:\mingw64\bin\g++.exe存在,再去环境变量编辑界面检查 PATH 里是否有一条指向这个目录的记录。确认无误后新开一个终端试一次。如果 PATH 有多条 MinGW 相关路径,把当前要用的那一条上移到最前。
5.2 编译出的 exe 运行时报缺 libwinpthread-1.dll
现象:编译成功,但双击 exe 或命令行运行时弹出错误「找不到 libwinpthread-1.dll」。
原因:选的是 posix 线程模型的 MinGW-W64,编译时用了std::thread或相关库,运行时需要这个 dll。如果这台电脑没装过 MinGW-W64,或者 dll 不在 exe 同目录,就会加载失败。
解决:最简单的是把 bin 目录里的 libwinpthread-1.dll 复制到 exe 同目录,或者把 bin 目录加到目标机器的 PATH。更干净的做法是编译时加静态链接参数:
g++ -static -o app.exe main.cpp-static会把 libwinpthread、libstdc++ 等静态库直接链进 exe,生成的文件体积会大一些,但换来了免依赖分发。发布给别人的程序我基本都开这个参数。
5.3 64 位编译器编出 32 位程序
现象:在 64 位 Windows 上编译运行都正常,但把 exe 放到别的机器上报「不是有效的 Win32 应用程序」。
原因:下载的是 i686 版本的工具链,默认编出来就是 32 位;或者装的是 x86_64 工具链但编译时加了-m32,而工具链没带 32 位库,实际没编成功只是你没注意检查输出格式。
解决:编译后用file命令(如果安装了)或者用 dumpbin 检查 exe 的头部标识。我更常用的是在代码里输出检查:
#include <iostream> int main() { std::cout << sizeof(void*) * 8 << std::endl; return 0; }编译运行后如果输出 64,说明是 64 位程序;输出 32 就是 32 位。确定目标后,回到第 2 章的选型标准,下载对应的 x86_64 或 i686 版本,别指望-m32能跨架构。
5.4 中文路径和空格路径引发编译失败
现象:源代码放在D:\项目代码\测试\main.cpp,g++ 编译报错,奇怪的是错误信息里路径显示成乱码,或者直接提示找不到文件。
原因:MinGW-W64 的命令行工具对非 ASCII 路径处理不一致,中文、日文等多字节字符路径容易出问题;路径里有空格时如果没有正确加引号,命令行解析也会错位。
解决:建立两个约定:所有 C++ 项目路径只用英文和数字;路径不要有空格。比如统一放D:\cpp\project1。如果源文件确实在带空格的目录,编译命令里用引号包住完整路径:
g++ -o D:/output/app.exe "D:/my projects/main.cpp"这里用了正斜杠,MinGW 和 Windows 的命令行都认,能减少转义问题。但最好还是从源头避免。
5.5 旧版 GCC 与新版 C++ 标准不兼容
现象:代码里用了 C++20 的concepts或ranges特性,编译直接报一堆看不懂的模板错误,但同样的代码在另一台机器上跑得好好的。
原因:MinGW-W64 发布的版本里捆绑的 GCC 版本不是越新越统一,有些发布包还停留在 GCC 12 左右,对新标准支持不完整。很多人装的压缩包版本偏旧,代码却按最新标准写,就会出现这个问题。
解决:编译时先确认g++ --version的版本号,再看代码里用的标准特性是否在这个版本的可支持范围内。编译时显式指定标准版本,比如用 C++20 特性时加-std=c++20,避免 GCC 默认标准太老导致特性没开。如果必须用最新标准,去下载对应更新版本的 MinGW-W64 工具链。
5.6 mingw32-make 找不到但是 make 存在
现象:执行make有反应,但行为异常,比如执行的是别的 GNU make 版本,或者直接报找不到 Makefile;执行mingw32-make才正常。
原因:MinGW-W64 安装包里自带的 make 叫mingw32-make.exe,这是为了避开 Windows 系统里可能装过的其他 make 程序。很多人习惯敲make,结果调用的根本不是 MinGW 的那个。
解决:统一用mingw32-make。如果想偷懒,可以复制一个别名:
copy C:\mingw64\bin\mingw32-make.exe C:\mingw64\bin\make.exe但要注意如果 PATH 里有别的 make,这个复制出来的 make 还是会被路径顺序影响。推荐的做法是在 Makefile 里显式写MAKE = mingw32-make,或者直接在项目的编译文档里注明命令。
6. 进阶用法:把 MinGW 变成日常 C++ 工具链的几个习惯
6.1 每次配置完新环境,先跑一遍完整性检查
换电脑、换项目、重装系统之后,我都会先执行一组命令确认工具链状态:
g++ --version mingw32-make --version where g++ where mingw32-make前两步确认编译器和构建工具可用,后两步确认 PATH 指向的是我预期的那套 MinGW-W64,避免机器上残留了旧版本。这组检查三十秒内完成,比编译到一半报诡异错误再去排查省得多。
6.2 区分 -static 与 -static-libgcc -static-libstdc++
-static是整体静态链接,gcc、stdc++、winpthread 全部静态化,exe 体积最大但完全免依赖;-static-libgcc -static-libstdc++只静态链接 GCC 和 C++ 标准库,其他库保持动态。我一般发布小工具用全静态,开发调试用部分静态,省编译时间又能暴露运行时问题。
6.3 用 strip 缩小发布体积
调试版 exe 里有大量符号表信息,发布前可以执行:
strip app.exe文件体积能缩小三分之一左右,不影响程序运行。我习惯在 Makefile 里加一个release目标,把 strip 打包进去。从那以后我每次配完 MinGW-W64 环境,都强制走一遍验证命令再动手写代码,省下过太多因为环境问题浪费的时间。希望这套流程对你也管用。
本文还有配套的精品资源,点击获取