ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Windows下MinGW-w64完整包安装教程:从选型、配置到避坑全指南

Windows下MinGW-w64完整包安装教程:从选型、配置到避坑全指南 简介面向Windows平台C/C开发者的MinGW mingw64完整配置包适合刚接触GNU工具链、需要快速搭建本地编译环境的初学者。压缩包共2000个文件约129.46MB以h/hpp头文件和Python脚本为主另有c源码、txt说明、shell脚本与doc文档基本覆盖GCC编译运行所依赖的库文件与辅助工具。已有3796人学习下载。相比官方在线安装器需要手动勾选组件、配置PATH该完整包解压后设置环境变量即可投入编译使用省去逐项下载的麻烦内含的头文件、构建脚本与说明文档也有助于理解MinGW64目录结构、排查配置问题是Windows下启动C/C开发的高性价比资源。1. Windows 上配 MinGW 为什么容易翻车先分清三个名字再说花半小时下了一个 MinGW 完整包解压后照着教程加好环境变量敲 gcc --version 却提示「不是内部或外部命令」——这种翻车我修过太多次了十有八九是下到的和你要装的并不是同一个东西。MinGW 是 GCC 编译器在 Windows 上的移植版而大家真正在用的其实是它的 64 位后继项目 MinGW-w64。这份完整包把编译器本体、头文件、库、gdb 和 mingw32-make 打包在一个目录里解压、配一条 PATH、编译第一个 hello.exe半小时内能把整条工具链跑通。适合在 Windows 上写 C/C 但不想被 Visual Studio 拖住的开发者也适合从 Linux 切到 Windows 临时编译开源库的人。2. 选型篇MinGW-w64、MSVC 与「完整包」到底选哪个2.1 还在下 MinGW 官网那个项目早就停更了很多人搜「mingw 官网下载」点进去看到的页面其实还挂在 SourceForge 或者 OSDN 上项目名写着 MinGW安装工具叫 mingw-get。这个项目是 2000 年前后启动的目标是让 GCC 能在 Windows 上跑起来但它的主分支长期停留在 32 位更新频率很低。装 mingw-get 的过程中要在线拉一堆组件包网络一波动就卡在某个「downloading gcc-core」的进度条上最后装出来只有 gcc 没有 gdb 的情况很常见。更尴尬的是这个在线安装器把编译器拆成几十个组件新手根本分不清哪些是必选装完一编译报缺头文件心态直接炸。真正在社区里被广泛使用的是 MinGW-w64这是后来的一个分叉目标明确支持 64 位目标、适配新的 Windows 运行时。你现在在各类课程资料、开源项目说明里看到的「MinGW」几乎都是指这一系。因为历史原因它的官网域名还叫 mingw-w64.org下载入口散落在 SourceForge 和各家打包发行版。怎么区分一个包是老 MinGW 还是 MinGW-w64看 bin 目录下的可执行文件名就行老项目叫 mingw32-gcc.exeMinGW-w64 系叫 x86_64-w64-mingw32-gcc.exe64 位或 i686-w64-mingw32-gcc.exe32 位。文件名里带 w64 字样的放心用。项目老 MinGWMinGW-w64定位GCC 的 Windows 初期移植支持 64 位的后继分叉可执行文件命名mingw32-gcc.exex86_64-w64-mingw32-gcc.exe / i686-w64-mingw32-gcc.exe目标架构32 位为主32 / 64 位维护状态长期停滞活跃多个发行版并存「mingw 官网下载」这组词现在搜出来前排也大多是 MinGW-w64 相关的资源站点老官网只是被搜索引擎保留了权重。看到页面风格停留在 2005 年前后、下载按钮指向 mingw-get 的留个心眼那不是你要的完整包是历史遗留物。2.2 MSVC 与 MinGW-w64 的本质差异运行时、ABI 与构建工具决定用 MSVC 还是 MinGW-w64其实是在选「运行依赖」和「工具链习惯」。MSVC 是 Visual Studio 自带的编译器编出来的程序依赖 VC 运行库 vcruntime140.dll、msvcp140.dllMinGW-w64 用的是 GCC支持两种 C 运行时MSVCRT 和 UCRT。MSVCRT 是 Windows 95 时代就跟着系统走的 C 运行库Win10 之前的系统全带但功能停留在很老的 C 标准UCRT 是 Windows 10 引入的通用 C 运行库Visual Studio 2015 之后也在用C99/C11 的函数支持明显更全。现在新发布的 MinGW-w64 发行版大多默认走 UCRT选包时认准 ucrt 字样。ABI 层面两者完全不相通MSVC 和 GCC 的 C 符号修饰规则不同异常处理模型也不同。MSVC 用自己的异常处理机制MinGW-w64 在 x64 下用 SEH。所以你没法把一个 VS 编出来的静态库直接丢给 gcc 链接反之也一样。项目里碰到 .lib 文件时先确认它是 MSVC 格式还是 MinGW 格式混用会报一堆 unresolved symbol这属于两个生态之间最经典的「黑匣子」问题。构建工具也不一样MSVC 生态里是 MSBuild 和 nmakeMinGW 生态里是 mingw32-make和 GNU make 同源特意改名是为了避免和其它 make 冲突。调试器对应关系更直接MSVC 用 VS 自带调试器读 PDB 格式信息MinGW 用 gdb 读 DWARF 格式信息。Eclipse CDT、VS Code 的 C/C 插件都能接 gdb这也是 GNU 工具链在编辑器生态里顺滑的原因。维度MSVCMinGW-w64编译器命令cl.exegcc.exe / g.exeC 运行时UCRTVS2015 之后MSVCRT 或 UCRTC 标准库Microsoft STLlibstdcGCC 自带Make 工具nmake / MSBuildmingw32-make调试器VS DebuggerPDBgdbDWARF许可证专有GPL 系典型场景Windows 桌面应用、商业闭源开源库、跨平台 C/C、教学纯 Windows 桌面业务、用 C 做 GUI选 MSVC 没毛病。但从 Linux/macOS 过来的项目、CMake 工程、以及需要 gcc 优化行为一致的场景MinGW-w64 是补位选择。判断逻辑很简单你的源码里有没有 Makefile、有没有 GCC 特有的编译选项、要不要在 Windows 上复现 Linux 下的编译结果——命中任何一条直接考虑 MinGW-w64。2.3 完整包与在线安装器的取舍能离线就赢了在线安装器最大的痛点是把编译器拆成几十个组件gcc-core、gcc-g、binutils、mingwrt、w32api……命名抽象关系复杂装完缺什么全靠编译时报错反向发现。网页版的引导下载器还看网络脸色SourceForge 在国内的连通性时好时坏下到一半断掉是常态。完整包的价值就是把这一切变成离线 zip一次解压得到一个完整的工具链目录bin/include/lib/share 齐全。这也是课程资源里常见「lua5.1 基础环境包luaforwindows_v5.1.5-52 及 mingw.zip」这类文件存在的原因——讲师把工具链和依赖打包在一个 zip 里学生解压就能编译省去环境折腾。同样逻辑的还有「带 mingw 的 codeblocks 安装包」IDE 和编译器打包在一起内部其实就是同一套工具链目录。选完整包时我一般检查四个点哪个缺了后面都是坑架构x86_64 还是 i686对应你的系统位数线程模型posix 还是 win32决定 std::thread 能不能正常用运行时ucrt 还是 msvcrt决定 C 标准库新旧组件bin 里是否同时存在 gcc.exe、g.exe、gdb.exe、mingw32-make.exe这四个点比版本号重要得多。版本号只影响新特性这四个点直接决定能不能编译、能不能调试、能不能跑 Makefile。下一章安装步骤里我按这四个点逐个过。3. 完整包安装从解压到 gcc --version 一次跑通3.1 先确认两件事系统位数和线程模型打开 cmd先确认系统位数echo %PROCESSOR_ARCHITECTURE%输出 AMD64 说明系统是 64 位选 x86_64 开头的包输出 x86 就只能用 32 位的 i686 包。这一步几乎不会错真正容易错的是第二个选择——线程模型。MinGW-w64 发行包的完整名称里通常会出现 posix 或 win32 字样例如 x86_64-w64-mingw32-posix 和 x86_64-w64-mingw32-win32这指的是线程模型。程序里用了 std::thread、std::async 这类 C 多线程设施时libstdc 需要底层线程抽象win32 模型直接走 Windows 原生 API但 std::thread 的行为和 Linux 上有差异部分源码在 win32 模型下编译会报错posix 模型用 winpthreads 库模拟 pthread 接口std::thread 用起来和 Linux 上基本一致。结论除非你明确知道自己只写 C 语言、完全不碰线程否则一律选 posix 版。运行时方面如果下载页同时提供 msvcrt 和 ucrt 两个版本选 ucrt只有老项目需要兼容不带 UCRT 的 Win7 系统时才回头考虑 msvcrt。3.2 解压到固定目录bin、include、lib 三件套必须齐全完整包建议直接解压到 C:\mingw64理由有两个路径短、无空格。C:\Program Files\mingw64 这种带空格的路径会让不少老 Makefile 和 CMake 配置脚本在转义环节翻车路径短也方便后面 Eclipse、VSCode 配置时手敲少打一串字符就少一次出错机会。解压完不要急着配环境变量先对着目录做一次体检。目标目录结构至少要有C:\mingw64\bin\gcc.exe C:\mingw64\bin\g.exe C:\mingw64\bin\gdb.exe C:\mingw64\bin\mingw32-make.exe C:\mingw64\include\stdio.h C:\mingw64\lib\libstdc.a哪个缺失基本能判断这个包不够格没有 include 树的包编译任何带头文件的代码都会报 fatal error缺 gdb 只能编译不能调试有的发行版不把 make 放 bin 里或者文件名不叫 mingw32-make.exe这种包最好直接换一个。体检这一步花不了两分钟但能省下后面一晚上的排查时间属于我自己的血泪经验。3.3 环境变量设置setx 的截断坑与 PowerShell 更稳的做法PATH 分用户级和系统级用户变量只对当前用户生效系统变量全机器生效。普通开发机配用户级就够了不用管理员权限。最常见的做法是 cmd 里用 setxsetx PATH %PATH%;C:\mingw64\bin这条命令的逻辑是把当前环境的 PATH 完整展开追加 C:\mingw64\bin 再写回用户变量。坑就在「完整展开」四个字上Windows 10/11 的系统 PATH 默认就有一长串条目加上用户变量里的各种路径很容易超过 setx 的限制——setx 对变量值只保留前 1024 字符。一旦截断PATH 尾部一大半条目直接消失后续启动其它工具就会开始报各种「不是内部或外部命令」。这个坑极其隐蔽因为 gcc 可能恰好加上了但某天你发现 git 或 npm 突然找不到了回头一看 PATH 已经被截断得面目全非。我一般不用 setx 处理 PATH改用 PowerShell 里读取用户变量再追加绕开展开合并的坑$old [Environment]::GetEnvironmentVariable(Path, User) [Environment]::SetEnvironmentVariable(Path, $old ;C:\mingw64\bin, User)逻辑说明第一行只读取用户级的 Path不碰进程 PATH也不碰系统 PATH第二行在用户级 Path 尾部追加一条再写回。两个参数里的 User 指定了作用域所以不会把系统 PATH 带进来也不会有 1024 字符截断风险。配置完环境变量接下来做一件经常被忽略的事彻底关掉当前终端再重开。环境变量只对之后启动的进程生效已经开着的终端不会自动刷新很多新手配完直接在同一个窗口里敲 gcc报错「不是内部或外部命令」第一反应是配置没生效其实是终端缓存作怪。3.4 验收四连与第一个 hello.exe重开终端后敲四条命令每一条都要能看到版本输出gcc --version g --version gdb --version mingw32-make --version逻辑说明前两条确认 C 和 C 编译器就位第三条确认调试器第四条确认 Make 工具。接着单独跑一条 where gcc确认命中的是 C:\mingw64\bin 下的 gccwhere gcc如果 where 显示的是别的路径说明 PATH 里还有一个旧编译器排在本包前面比如 Git for Windows 自带的那套这属于第 4 章要处理的经典冲突。工具链没问题后建一个工作目录写最小程序验证整体链路#include stdio.h int main(void) { printf(mingw64 ok\n); return 0; }编译时我习惯从第一次就带上警告和调试参数gcc -Wall -g hello.c -o hello.exe参数说明-o 指定输出文件名 hello.exe-Wall 打开所有常见警告让代码问题在编译期暴露-g 生成 gdb 调试信息后面第 5 章进 Eclipse 调试时离不开它。运行./hello.exe能输出 mingw64 ok说明编译器、链接器、运行时三环全通。到这里这份完整包的安装就算落地了往后编译报错理论上都可以把责任归给代码而不是环境。4. 避坑PATH 残留、缺 DLL 与 make 玄学的五处翻车记录4.1 PATH 的两处经典翻车翻车点一新开的 cmd 敲 gcc 提示不是内部或外部命令。现象很直接教程一步步执行完重开终端仍然找不到 gcc。原因通常有两种一是终端窗口没有真正刷新很多终端软件开了「快速编辑」模式新开窗口会复用旧进程的环境块二是 PATH 根本没写进用户变量比如 setx 因为截断或权限问题只写了一半。解决先检查再动手改。在 cmd 里敲 set PATH确认 C:\mingw64\bin 在不在如果在就关掉所有终端窗口必要时注销一次重新登录如果不在回到第 3.3 节用 PowerShell 方法重新设置。注意 set PATH 查看的只是当前进程的 PATH不是永久配置两者要分清。翻车点二gcc --version 显示出一个完全陌生的版本号。现象是刚装的 MinGW-w64敲 gcc 却输出了别的版本。原因机器上本来就存在其它编译器常见来源包括 Git for Windows 自带的 mingw、CodeBlocks 自带的 MinGW、TDM-GCC、MSYS2 的 usr\bin还有某些 Python 包捆绑的编译器它们在 PATH 里的顺序排在了 C:\mingw64\bin 前面。解决用 where 把 gcc.exe 的命中路径全部列出来where gcc看输出顺序把本包的路径挪到 PATH 最前面或者把其它编译器从 PATH 里临时摘掉。这个问题同样适用于 g、gdb、make它们各自也有「李鬼」。4.2 编译运行期的三处踩坑问题一编译简单文件直接报 fatal error: stdio.h: No such file or directory。现象是 gcc 能输出版本一编译就炸头文件全找不到。原因手里的包没有完整的 include 目录这是残缺包常见于早期用 mingw-get 只装了 compiler 相关组件、漏装 runtime 的安装结果。解决检查 C:\mingw64\include\stdio.h 是否存在再检查 C:\mingw64\include\c 是否存在后者一旦缺失所有 C 源文件直接挂。如果确认包不全别补了换一个完整包。缺头的包修起来比换包还费时间这是我踩过最不值得的坑。问题二本机编译运行一切正常把 exe 拷到另一台电脑上双击报错「找不到 libgcc_s_seh-1.dll / libwinpthread-1.dll」。现象是目标电脑没装 MinGW程序依赖的动态链接库不在系统目录里。原因MinGW-w64 默认把 GCC 运行时动态链接进程序libgcc_s_seh-1.dll 负责异常处理和辅助函数libwinpthread-1.dll 只在 posix 线程模型包里出现。开发机上能运行是因为 C:\mingw64\bin 在 PATH 里换一台干净的机器就露馅了。解决把这两个 DLL 从 C:\mingw64\bin 拷到 exe 同目录或者编译时加 -static-libgcc -static-libstdc最彻底的是用 -static 全静态链接细节在第 6 章。问题三刚编译出的 exe 被 Windows Defender 直接隔离。现象是编译成功杀软弹窗文件从目录里消失常见于带 winpthread 等 DLL 引用的新编译文件。原因未经代码签名的本地编译产物容易命中 Defender 启发式规则的行为特征gcc 新生成的 PE 文件确实有些特征像恶意程序打包器。解决把开发工作目录加进 Defender 的排除路径编译产物统一放这个目录下验证真需要外发的文件再挪出来处理。注意这一步只需要加排除目录不需要关闭整个实时防护开发机安全底线还是要保留的。5. Eclipse MinGW-w64 实战从源码到 Debug 的完整闭环5.1 为什么用 Eclipse CDT 而不是硬把 GCC 塞进 VSVisual Studio 的工程体系、调试器都是围绕 MSVC 设计的GCC 编出来的程序带 DWARF 调试信息VS 调试器不认把 gcc 硬塞进 VS 不是不能用而是每次构建、断点、看变量都在和各种机制对抗体验很差。Eclipse CDT 不一样它从设计上就是给 GNU 工具链用的新建工程时直接扫描 PATH 里的 gcc/g自动拿到 include 路径列表调试器默认接 gdb。这套组合在 Linux 上什么样在 Windows 上还是什么样对从 Linux 学习环境切换到 Windows 的人来说几乎零学习成本。Eclipse CDT 从官方站点下载 Eclipse IDE for C/C Developers 这个版本就行自带 CDT 插件前提是本机有 JDK。单纯为了支撑 Eclipse 运行装一个 openjdk 发行版即可Eclipse 启动时会自动探测到 java.exe。Eclipse 本体解压即用不需要安装步骤这对刚被 MinGW 环境变量折腾过的人来说算是难得的省心环节。5.2 新建 C 工程与 Toolchain 探测打开 Eclipse第一次启动会让你选 workspace 目录建议单独建一个不要放在 C:\mingw64 里避免工具链目录被 IDE 配置文件污染。进入主界面后File → New → C Project项目类型最常用 Executable → Empty Project空工程能自己控制源文件结构。往下拉到 Toolchains 列表如果 CDT 正常工作会出现 MinGW GCC 这一项勾上它Finish。如果列表里没有 MinGW GCC或者显示 No Toolchains说明 Eclipse 进程的环境里看不到 gcc。最常见原因是 Eclipse 在配置 PATH 之前就启动了桌面快捷方式继承的进程环境还是旧的。解决分两步先完全退出 Eclipse 再重新启动让新环境变量生效如果重进仍然探测不到手动到 Window → Preferences → C/C → Build → Environment 里新增一条变量变量名写 PATH值写 C:\mingw64\bin;%PATH%。这一步的本质是让 CDT 的启动扫描能找到 gcc.exe和命令行里配 PATH 是同一个原理只是面向的进程不同。建完工程后在 src 目录下新建源文件把 hello.c 的代码放进去Eclipse 的编辑器自带语法高亮和错误标注。这时如果源码里出现红色波浪线先把鼠标悬停上去看提示多数是 include 头文件找不到在项目右键 Properties → C/C General → Paths and Symbols 里确认 GNU GCC 的自动发现是否勾选。5.3 编译与 Debuggdb 路径与断点单步点工具栏锤子图标Eclipse 在 Console 窗口输出完整构建命令和编译结果。能看到 gcc -O0 -g3 -Wall -c -fmessage-length0 这类默认参数这是 CDT 自带的构建配置。-O0 表示不优化调试时变量可读性最好-g3 生成完整调试信息比手动命令行里的 -g 更细。如果 Console 里报 gcc 不是内部或外部命令回到 5.2 的 PATH 设置别怀疑完整包。Debug 前先确认 gdb 路径。菜单 Run → Debug Configurations → C/C Application左侧选中工程对应的配置Main 标签页里确认 C/C Application 指向编译产物Debugger 标签页把 gdb 路径浏览到 C:\mingw64\bin\gdb.exe。如果调试启动后报 Error while launching十有八九是 gdb 路径指向了不存在的文件或者 gdb 版本太旧读不懂当前编译器生成的调试符号。调试的实际用法在源码行号左侧双击设断点按 F5 启动 Debug程序停到断点后按 F6 单步执行右侧 Variables 窗口实时看局部变量值。Windows 上用 gdb 调试时会弹出一个 Enter Debugger 窗口那是 gdb 的终端交互窗口正常现象不要关它承载着 gdb 的输入输出。整个流程跑通后Eclipse 里的开发体验和 Linux 上几乎一致断点、单步、变量观察都没有阉割。6. 进阶加一个 -static让 exe 脱离 DLL 依赖6.1 动态链接时你依赖了什么新装的 MinGW-w64 编译一个 hello worldexe 在自己机器上跑得欢拷到别人机器上就缺 DLL第 4 章讲了这个现象这一节给验证方法。用 binutils 自带的 objdump 查看 PE 文件的导入表objdump -p hello.exe | grep DLL Name逻辑说明objdump -p 输出 PE 文件头里的可选头信息grep DLL Name 把导入表里的 DLL 列表筛出来。动态链接版 hello.exe 的输出里除了 KERNEL32.dll 这类系统 DLL还会出现 libgcc_s_seh-1.dllC 程序会多出 libstdc-6.dll 和 libwinpthread-1.dll。这几个带 lib 前缀的 DLL就是 MinGW-w64 运行时的体外依赖分发给别人时漏掉它们程序就启动不起来。6.2 静态链接后的差异把同样的源码换一条编译命令gcc -static hello.c -o hello_static.exe再跑一遍导入表检查objdump -p hello_static.exe | grep DLL Name正常情况只剩 KERNEL32.dll 和少数 Windows 系统 DLLlibgcc、libstdc、libwinpthread 全部进了 exe 内部。文件体积会大几百 KB换来的是 exe 单文件直接分发。如果不想全静态、只想去掉 GCC 运行时的依赖可以用拆开的两个参数gcc -static-libgcc -static-libstdc hello.c -o hello.exe逻辑说明-static 把 C 库和 C 库一并静态化范围最大-static-libgcc 和 -static-libstdc 只把 GCC 运行时静态化C 库仍然动态。纯 C 代码用 -static 的行为差异很小大工程全静态链接偶尔会遇到 winpthread 的已知问题此时拆开参数更稳。从那以后我每次要交付一个 exe 出去都会在最后强制跑一遍 objdump -p 检查导入表看到 lib 开头的 DLL 就回去补编译参数养成习惯后「拷到别的电脑缺 DLL」这类售后问题基本绝迹。希望帮到你。本文还有配套的精品资源点击获取
返回列表