简介MinGW64 64位 gcc 4.9.2 是一套面向 Windows 平台的 GNU 编译工具链专为需要构建 64 位 C/C 程序的开发者准备。它基于 GCC 4.9.2 发行版支持 gcc、g 编译、静态与动态链接、GDB 源码级调试以及 Makefile 自动化构建适合从入门到中高级的 Windows 原生开发场景。压缩包为 rar 格式共 3541 个文件约 35.08MB其中以 1702 个 h 头文件、1280 个 a 静态库、243 个 hpp 头文件为主另含 36 个 exe 可执行工具、42 个 tcc 模板定义及少量 o 目标文件与 idl 接口描述文件完整覆盖编译、链接与调试所需组件。目前已有 1509 人学习下载。解压后配置 bin 目录到 PATH 即可使用读者可借此获得一套与 GNU/Linux 环境相近的 64 位编译开发工具链便于编写、构建和调试 Windows 应用程序。1. MinGW 64位 gcc 4.9.2为什么今天还有人死磕这套老工具链如果你在 Windows 上编译过 C/C大概率绕不开 MinGW。而“MinGW 64位 gcc 4.9.2”这个组合听起来像是上个时代的产物——确实gcc 4.9.2 发布于 2014 年距今已经超过十年。但现实是大量遗留项目、嵌入式 SDK、Qt 旧版本工程、甚至某些工业控制软件至今仍然锁死在这个版本上。你可能会问为什么不升级因为升级之后ABI 变了、C11 支持程度变了、链接脚本行为变了整个项目可能直接编不过。这就是为什么“MinGW 64位 gcc 4.9.2”至今仍有搜索量。它不是一个“推荐使用”的版本而是一个“不得不用”的版本。这篇文章面向的是那些手里拿着老代码、老 SDK、老构建脚本必须在 Windows 上把东西编出来的人。我会把安装、配置、编译、排错整条链路讲清楚包括我踩过的坑和绕过的弯。如果你正在找 MinGW 官网下载、纠结 msvc 和 mingw 区别、或者被 gcc 升级后为啥还是旧版本折磨过这篇内容应该能帮你省下几个晚上。2. 先把工具链装对MinGW-w64 与 gcc 4.9.2 的匹配逻辑2.1 为什么是 MinGW-w64 而不是老 MinGW很多人搜“MinGW 官网下载”结果找到的是 mingw.org 那个早已停止维护的项目。那个版本最高只到 gcc 4.8.1而且只有 32 位。你要的是 MinGW-w64——它是从 MinGW 分叉出来的独立项目支持 64 位目标也支持 32 位目标并且持续维护到了 gcc 13 以上。但 gcc 4.9.2 这个版本在 MinGW-w64 的发布历史里属于比较早期的 64 位构建。你需要找的是带x86_64前缀、posix或win32线程模型、seh或sjlj异常模型的构建包。常见命名格式是x86_64-4.9.2-release-posix-seh-rt_v3-rev1.7z这里每个字段都有含义字段含义选择建议x86_64目标架构为 64 位按你的项目需求选4.9.2gcc 版本号必须与项目要求一致posix线程模型用 std::thread 选 posix否则 win32seh异常模型64 位推荐 seh性能更好rt_v3运行时版本与 gcc 版本配套不要混用rev1修订号同版本优先选 rev 更高的如果你手里没有现成的包可以去 MinGW-w64 的 SourceForge 文件归档里翻旧版本。注意不要下成i686开头的那是 32 位。2.2 解压与环境变量配置下载下来通常是个 7z 压缩包。解压到一个没有空格、没有中文的路径比如C:\mingw64。解压后目录结构应该是C:\mingw64\bin\gcc.exe C:\mingw64\bin\g.exe C:\mingw64\include\ C:\mingw64\lib\然后把这个bin目录加到系统 PATH 的最前面。为什么要最前面因为如果你机器上已经装了别的 gcc比如 MSYS2 自带的、或者 Qt 自带的PATH 顺序决定了你调用的到底是哪个 gcc。# 在 cmd 或 PowerShell 里验证 where gcc gcc --version如果where gcc输出的第一行不是C:\mingw64\bin\gcc.exe说明 PATH 顺序有问题。gcc --version应该输出gcc (x86_64-posix-seh-rev1, Built by MinGW-W64 project) 4.9.2注意括号里的信息必须和你下载的包一致。如果显示的是其他版本说明你调到了别的 gcc。2.3 验证 64 位目标是否生效装完之后写一个最小程序验证目标架构// arch_check.c #include stdio.h int main(void) { printf(pointer size: %zu\n, sizeof(void*)); printf(compiled at: %s %s\n, __DATE__, __TIME__); return 0; }编译并运行gcc -m64 arch_check.c -o arch_check.exe arch_check.exe如果输出pointer size: 8说明 64 位目标生效。如果输出 4说明你调到了 32 位编译器或者-m64没被识别。gcc 4.9.2 对-m64的支持是完整的但前提是你下的包本身是 x86_64 版本。提示不要混用不同来源的 binutils。MinGW-w64 的 gcc 包通常自带 ld、as、ar如果你单独替换了某个组件链接阶段可能出现玄学错误。3. 用 gcc 4.9.2 编译真实项目从单文件到 CMake 工程3.1 单文件与多文件的编译命令单文件编译最简单gcc -m64 -O2 -Wall -o app.exe main.c参数说明-m64强制 64 位目标虽然 x86_64 版默认就是 64 位但显式写上避免歧义。-O2常用优化级别gcc 4.9.2 对 O2 的支持很稳定。-Wall打开常用警告老代码里能暴露出不少隐患。-o app.exe指定输出文件名Windows 下建议带.exe。多文件编译建议分步走方便定位错误gcc -m64 -c -O2 -Wall -o main.o main.c gcc -m64 -c -O2 -Wall -o util.o util.c gcc -m64 -o app.exe main.o util.o如果项目里有 C 代码链接阶段要用g而不是gcc否则标准库符号找不到g -m64 -c -O2 -stdc11 -o main.o main.cpp g -m64 -o app.exe main.o util.ogcc 4.9.2 对 C11 的支持已经比较完整但-stdc14只是部分支持-stdc17基本不可用。如果你的代码用了 C14 之后的特性这个版本编不过。3.2 CMake 与 MinGW 的配合方式搜“cmake与mingw”的人很多因为 CMake 默认在 Windows 上找的是 MSVC。你要显式指定生成器cmake -G MinGW Makefiles -DCMAKE_C_COMPILERgcc -DCMAKE_CXX_COMPILERg ..如果 PATH 里有多个 gcc建议写绝对路径cmake -G MinGW Makefiles ^ -DCMAKE_C_COMPILERC:/mingw64/bin/gcc.exe ^ -DCMAKE_CXX_COMPILERC:/mingw64/bin/g.exe ^ -DCMAKE_BUILD_TYPERelease ..然后在生成的目录里执行mingw32-make -j4注意mingw32-make这个名字有迷惑性它和 32 位没关系就是 MinGW 版的 make。如果你装了 MSYS2也可以用make但不要混用。CMake 里还需要注意CMAKE_RC_COMPILER如果项目里有.rc资源文件不设置这个会报错-DCMAKE_RC_COMPILERC:/mingw64/bin/windres.exe3.3 静态链接与运行时依赖MinGW 编译出来的 exe 默认依赖libgcc_s_seh-1.dll、libstdc-6.dll、libwinpthread-1.dll。如果你要把 exe 拷到别的机器上跑要么把这些 DLL 一起带上要么静态链接g -m64 -static -static-libgcc -static-libstdc -o app.exe main.o util.o参数说明-static尽量静态链接所有库。-static-libgcc静态链接 libgcc。-static-libstdc静态链接 libstdc。静态链接后 exe 体积会变大但部署省心。注意如果用了 posix 线程模型libwinpthread可能仍然需要动态链接除非你显式加-Wl,-Bstatic -lwinpthread -Wl,-Bdynamic。注意gcc 4.9.2 的静态链接在某些情况下会和-flto冲突如果开了 LTO 又静态链接链接时间会显著变长甚至报内存不足。4. 避坑与排查gcc 4.9.2 在 Windows 上的五个血泪教训4.1 现象编译报错 “undefined reference to__imp_xxx”原因链接阶段找不到对应的导入库。常见于调用了 Windows API 但没加-l参数。解决根据 API 所属的库补上链接选项。比如__imp_CreateFileW需要-lkernel32__imp_MessageBoxW需要-luser32。如果不知道某个符号属于哪个库可以用nm在C:\mingw64\x86_64-w64-mingw32\lib下搜nm -A C:/mingw64/x86_64-w64-mingw32/lib/*.a | grep __imp_CreateFileW4.2 现象gcc 升级后为啥还是旧版本原因PATH 里存在多个 gcc或者 shell 缓存了旧的路径。Windows 下常见于装了 MSYS2、Qt、Strawberry Perl 等自带 gcc 的软件。解决用where gcc列出所有 gcc确认第一个是你想要的。如果是 PowerShell执行$env:Path检查顺序。改完 PATH 后要新开终端旧终端不会自动刷新。如果用的是 CMake清掉CMakeCache.txt重新生成因为 CMake 会缓存编译器路径。4.3 现象中文路径导致编译失败或运行时崩溃原因gcc 4.9.2 对非 ASCII 路径的处理不完善尤其是链接阶段调用ld时。解决项目路径、MinGW 安装路径、临时目录全部用纯英文。如果项目在中文目录下可以映射一个虚拟盘subst X: D:\项目\中文目录 cd /d X:\编译完再subst X: /D解除映射。4.4 现象mingw32-make报 “multiple target patterns”原因Makefile 里用了 Windows 路径的反斜杠或者路径里有冒号比如C:\。解决Makefile 里统一用正斜杠/盘符可以写成/c/xxx或者直接用相对路径。如果必须用绝对路径用$(subst :,/,$(PATH))这类方式处理。4.5 现象编译通过但运行时报 “0xc000007b” 或缺少 DLL原因32 位和 64 位 DLL 混用或者运行时找不到libgcc_s_seh-1.dll。解决用objdump -p app.exe | grep DLL查看依赖的 DLL 列表确认每个 DLL 都是 64 位版本。可以用file命令MSYS2 下或dumpbin /headersVS 下检查 DLL 架构。最省事的办法还是静态链接把运行时依赖降到最低。5. 让老 gcc 4.9.2 在现代 Windows 上跑得更稳的几个技巧5.1 用-fno-omit-frame-pointer保留调用栈gcc 4.9.2 默认在 O2 下会省略帧指针导致崩溃时调用栈不完整。如果你需要调试老代码建议加上gcc -m64 -O2 -fno-omit-frame-pointer -g -o app.exe main.c这样配合 DrMinGW 或 ProcDump 能拿到更完整的栈信息。代价是性能略微下降但排查线上问题时这点损失值得。5.2 用-D__USE_MINGW_ANSI_STDIO1解决 printf 格式化问题MinGW 的printf默认走 MSVCRT对%lld、%zu这些 C99 格式支持不好。加上这个宏可以让 gcc 使用自己的 stdio 实现gcc -m64 -D__USE_MINGW_ANSI_STDIO1 -o app.exe main.c这个宏在 gcc 4.9.2 上效果稳定但要注意如果项目里混用了 MSVCRT 的文件句柄可能会有兼容性问题。5.3 用-Wl,--enable-auto-import处理数据符号导入老代码里经常直接引用 DLL 中的全局变量链接时会报undefined reference。加上这个链接选项可以让 ld 自动处理g -m64 -Wl,--enable-auto-import -o app.exe main.o但这个选项不是万能的如果符号是函数指针或者复杂结构体还是建议显式用__declspec(dllimport)声明。5.4 用-static-libgcc -static-libstdc减少部署麻烦前面提过静态链接这里再强调一次gcc 4.9.2 的运行时 DLL 版本和后续版本不兼容。如果你把 exe 拷到一台装了新版 MinGW 的机器上它可能会加载到新版 DLL 然后崩溃。静态链接能彻底避免这个问题。g -m64 -static-libgcc -static-libstdc -o app.exe main.o util.o如果还依赖libwinpthread可以再加-Wl,-Bstatic -lwinpthread -Wl,-Bdynamic5.5 用ccache加速重复编译老项目全量编译一次可能要十几分钟。在 MinGW 环境下可以配合 ccache 使用ccache gcc -m64 -c -O2 -o main.o main.cccache 会缓存编译结果第二次编译同样的文件几乎瞬间完成。注意 ccache 的缓存目录不要放在中文路径下否则可能失效。我自己的习惯是拿到一个老项目先不动代码用默认参数编一遍把错误记下来然后逐个加-fno-omit-frame-pointer、-D__USE_MINGW_ANSI_STDIO1、静态链接这些选项每加一个就重新编一遍确认没有引入新问题。这样虽然慢但能保证每一步都是可控的。希望帮到你。本文还有配套的精品资源点击获取