看到这个标题我先笑了一下,“不会安装MinGW64,rt”,这不就是论坛伸手党的经典开场吗。但说真的,MinGW64的安装还真不是右键解压那么无脑,网上教程抄来抄去,版本、线程模型、异常处理这几个概念一混,新手基本走到哪一步都有可能放弃。这篇文章我从头捋一遍,重点解决两件事:第一,怎么把MinGW64装到一个稳定可用的状态;第二,很多人装它就是为了编译FFmpeg 4.4,这个过程里有哪些隐藏坑。全程按我自己实操的习惯来写,该讲原理的地方讲原理,该给命令的地方给命令,适合那种“搜了一堆教程还是没整明白”的兄弟。
1. 装不上MinGW64的根源,八成在“四个选型”上
1.1 MinGW、MinGW-w64、MSYS2:先分清三个名字
很多人被这几个名字搞疯,是因为搜教程时根本没意识到它们是三个不同的东西。
MinGW的全称是Minimalist GNU for Windows,早期目标是让GNU工具链能在Windows上原生编译C/C++程序,不需要Linux虚拟机。老版本MinGW只支持32位。后来社区分叉出一个更激进的项目,叫MinGW-w64,同时支持32位和64位,维护也更活跃。你现在去任何地方搜“MinGW64”,实际下载到的几乎都是MinGW-w64的构建产物。民间管它叫MinGW64,官方项目叫MinGW-w64,这俩基本是一回事。
MSYS2则是另一条路线。它本身不是编译器,而是一个模拟Linux风格的软件包管理环境,里面带bash终端、pacman包管理器,以及可选的MinGW-w64工具链。你去MSYS2的“MinGW64”终端里操作,底层用的gcc其实就是MinGW-w64的编译器,但外面套了一层很完整的Unix-like环境。
一句话总结:如果你只是想让Windows上有gcc,装MinGW-w64就够了;如果你想像在Linux里一样敲make、configure然后编译大型开源项目,MSYS2更接近那个体验。
1.2 64位还是32位、posix还是win32、seh还是sjlj
下载MinGW-w64时,你会看到一堆类似x86_64-posix-seh这样的标签,每个字段都代表一个必须做的选择。
第一个字段是目标架构。默认选x86_64,即64位。别为了追求“兼容”去选i686,在64位系统上编译32位程序有别的方案,新手阶段用x86_64就对了。
第二个字段是线程模型,这是最容易被忽略但影响很大的选项。win32线程模型直接用Windows原生线程接口,对Windows API程序更“纯粹”,但很多开源库、包括C++11里的std::thread,在win32模型下玩不转;posix线程模型则提供了POSIX线程接口的兼容层,让大量跨平台代码能直接编译。如果你后续要碰FFmpeg这类重度依赖POSIX语义的开源项目,选posix几乎不会吃亏,这也是目前社区里最常见的选择。
第三个字段是异常处理模型,64位下主要是seh和sjlj。seh是Windows结构化异常处理,性能更好,MinGW-w64的工具链对它的支持已经很成熟;sjlj是老的setjmp/longjmp方案,主要用于兼容一些特殊调试场景。日常使用直接选seh。
所以最稳妥的组合就是:x86_64-posix-seh。我装过几十次,选这一组基本不会在编译环节出幺蛾子。
1.3 为什么总有人卡在线安装器
很多教程会让你去SourceForge下载mingw-w64-install.exe,运行后选择架构、线程模型,然后等它在线拉取文件。听起来挺合理,实际体验却很折磨。
首先,这个在线安装器需要拉取的文件不少,网络稍微波动一下就显示失败或卡在某个进度条,而且断点续传做得一塌糊涂。其次,它安装后默认会往C:\Program Files\mingw-w64\这类带空格的目录里塞文件,后续写Makefile或者让IDE自动搜索工具链时,路径带空格会带来各种莫名奇妙的引号问题。最后,部分杀毒软件还会对这个在线安装器的临时文件产生“误报情绪”。
所以我的结论很简单:别折腾在线安装器,直接下载离线压缩包,这是稳定性最高的方式。
1.4 新手最该选的版本组合
汇总一下我自己的选择标准,直接抄作业就行:
| 项目 | 选择 | 理由 |
|---|---|---|
| 架构 | x86_64 | 现代Windows基本都是64位 |
| 线程模型 | posix | 兼容更多开源库和C++11线程 |
| 异常处理 | seh | 64位下性能和兼容性更好 |
| 发行格式 | .7z离线包 | 避开在线安装器的一堆破事 |
| 安装位置 | C:\mingw64 | 无空格、无权限折腾、路径短 |
另外提一句,某些集成开发环境(比如较新版的Code::Blocks或Dev-C++)会自带一个MinGW工具链,但自带的版本往往偏老,甚至只支持32位。如果你不是非用不可,建议还是自己装一份干净的。
2. 实操:离线压缩包装MinGW64到C盘
2.1 下载文件的正确姿势
MinGW-w64的离线构建包一般可以在SourceForge项目页或GitHub上的社区构建仓库里找到。文件名通常长这样:gcc-x86_64-posix-seh-...或x86_64-posix-seh-...7z。下载时注意看后缀,别把.exe的在线安装器当压缩包给下了。
这里有一个实战细节:SourceForge页面上的大按钮经常会带你到广告下载页,要找“直接下载”或文件列表里对应的具体文件,鼠标悬停在文件名上确认链接末尾是.7z或.tar.xz。下完以后顺手校验一下文件大小,低于50MB的基本就不对,完整工具链压缩包一般在一两百MB上下。
如果你还在纠结要不要装7-Zip,这里直接给答案:必须装。Windows自带的资源管理器虽然能解压zip,但对7z格式的支持很差,MinGW-w64离线包大量使用7z格式,装个7-Zip一劳永逸。
2.2 解压到C:\mingw64而不是Program Files
把压缩包解压到一个清爽的目录,这一步比你想象的更重要。
推荐路径是C:\mingw64。解压完成后,你会看到C:\mingw64\bin这个目录,里面躺着gcc.exe、g++.exe、gfortran.exe、mingw32-make.exe、gdb.exe等一大票工具。后面所有环境变量配置、IDE工具链设置,指向的都是这个bin目录。
为什么不建议解压到C:\Program Files\mingw64?两个原因:一是路径里的空格,在Makefile和shell脚本里会被当成参数分隔符,你需要到处加引号;二是Program Files受系统权限保护,有些编译过程要生成临时文件时可能有权限报错。别给自己制造这种隐患。
2.3 环境变量Path配置的完整过程
把bin目录加到系统Path里,MinGW64才算真正“安装”了。Windows搜索环境保护变量,打开“编辑系统环境变量”,点“环境变量”,在系统变量列表里找到Path,点击“新建”,输入C:\mingw64\bin,确认保存。
有几个新手特别容易犯的错误,我单独拎出来讲:
- 不要把整个
C:\mingw64加进去,必须指向bin,因为系统要找到的是可执行文件,不是目录本身。 - 不要新建一个叫PATH的变量,而是复用已有的
Path,直接在条目里追加。 - 配置完后必须关掉当前命令行窗口再重新打开,因为新窗口才会加载最新的环境变量。如果你在PowerShell里改完就立刻测试,很自然就会撞上“gcc不是内部命令”,这锅不是MinGW的。
命令行没法立刻刷新环境变量时,还有个简单办法:直接用全路径调用测试。
C:\mingw64\bin\gcc.exe --version这一步能跑通,就说明工具链本身没问题,剩下的只是终端会话的环境变量加载问题。
2.4 验证安装的快速检查
配置好环境变量后,打开新的CMD或PowerShell,执行:
gcc --version g++ --version gdb --version看到版本号正常输出,说明基本装好了。再执行一下where gcc(CMD里是where gcc,PowerShell里可以是where.exe gcc),能看到gcc的实际路径,确认它指向你刚才配的C:\mingw64\bin\gcc.exe。如果你的机器上之前装过Qt、Git或其他开发工具,它们可能自带gcc,where gcc的结果里会出现多条路径,列表顺序决定了当前实际调用的是哪一个,这一点在后面的排错章节里会详细展开。
3. 让MinGW64真正能干活:从Hello World到依赖DLL
3.1 编译第一个C程序,确认工具链完整
装了编译器不实际编一次程序,等于白装。在任意英文目录下新建一个文件hello.c,内容就几行:
#include <stdio.h> int main(void) { printf("mingw64 works\n"); return 0; }然后执行:
gcc hello.c -o hello.exe hello.exe如果屏幕上打印出mingw64 works,恭喜,你的工具链已经完整走通。整个过程不过几秒钟,比用VS Code装一堆扩展再等IntelliSense半天要直接得多。
这里顺便说一句,编译器的核心链路是预处理、编译、汇编、链接四步。前面几步由gcc内部完成,最后链接阶段会用ld和相关的运行时库。MinGW-w64的离线包把所有东西都打包好了,所以你在Windows上不需要额外找什么SDK就能编出原生程序,这就是它最大的便利性。
3.2 动态链接的DLL问题与静态编译
MinGW64装好了,gcc也能编译了,但你可能会遇到一个非常经典的运行报错:编译出来的exe在自己电脑上跑得欢,复制到同事电脑或者某个裸机环境,双击提示缺libwinpthread-1.dll或libgcc_s_seh-1.dll。
原因很简单:MinGW64默认是动态链接运行时库的,exe需要依赖这些DLL,而这些DLL通常在C:\mingw64\bin里。如果你只是在自己机器上开发,把C:\mingw64\bin加入Path也够用;但如果你希望产物能独立分发,就得考虑静态链接。
分发给别人时,编译命令可以加静态链接参数:
gcc hello.c -o hello.exe -static-libgcc -static-libstdc++C语言程序还可以进一步加-static把C运行时也尽量静态化。这么做会让exe体积变大一些,但换来了“复制即运行”的省心。我早期发工具给别人,每次都忘记这个细节,被“缺DLL”的反馈追着跑了很久,后来直接把静态参数写进构建脚本里。
3.3 mingw32-make与项目的规模边界
MinGW-w64离线包里带了一个mingw32-make.exe,平时可以当Linux里的make用。为啥名字带个mingw32-前缀?就是为了和别的make区分开,避免你在命令行敲make时,命中的是某个IDE自带的make版本。
单独用MinGW64编译很少依赖复杂构建系统。如果你只是写几十个源文件的小工具,手动写个批处理或简单的Makefile都行。但一旦项目规模变大,需要通过configure脚本检测各类库和头文件,或者要拉取一堆第三方依赖时,纯Windows环境下的MinGW64就开始力不从心了。
我自己定位是:MinGW64离线包适合做轻量级本地开发工具,想真正舒服地编译FFmpeg这类大型项目,得切换到MSYS2这套环境里。下一节就是重头戏。
4. MinGW64编译FFmpeg 4.4的实战路径
4.1 FFmpeg 4.4对工具链的真实要求
如果你搜“MinGW64 编译FFmpeg4.4”,多半是因为需要自己定制FFmpeg,或者要给某个项目提供Windows版本的二进制文件。FFmpeg 4.4是2021年发布的一个稳定版本,源码包大概几十MB,用gcc编完全没问题,但它对构建环境有三个隐性要求。
第一,FFmpeg的构建入口是一个configure脚本,这是标准的Linux风格的shell脚本,在纯Windows命令行里没法直接运行。你必须身处bash环境,这就是很多人装上MinGW64后依然编不了FFmpeg的原因——不是因为编译器不够好,而是因为缺了个shell。
第二,FFmpeg在x86架构上默认启用汇编优化,需要nasm汇编器的参与,而且版本不能太老。如果你直接执行configure,最常看到的报错就是nasm not found或版本过旧。
第三,如果你还要启用x264、x265这些编码库,那还得先编译安装对应的库并让configure能找到它们。这又是一个依赖地狱,临时抱佛脚会很痛苦。
所以我的建议非常明确:如果目标就是编译FFmpeg 4.4,别在单独MinGW64上死磕,直接装MSYS2,用它的MinGW64终端来搞定。
4.2 建议路线:MSYS2里的MinGW64环境
MSYS2安装没什么好说的,下载官方安装包,一路下一步。关键在安装后的包管理:
打开MSYS2的“MSYS2 MSYS”终端(不是MinGW64终端),先更新核心包:
pacman -Syu如果提示你需要关闭终端或重启,就照做,再重新打开。接下来打开“MSYS2 MinGW64”终端,安装工具链和nasm:
pacman -S base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-nasmbase-devel提供make、pkg-config等基础构建工具;mingw-w64-x86_64-toolchain提供32位和64位两套编译器(如果嫌大,也可以只装gcc相关的几个包);mingw-w64-x86_64-nasm是FFmpeg汇编优化的关键依赖。
如果你网络下载很慢,MSYS2换用国内镜像源是个常规操作,这个自行搜索就有,不展开。
装完以后,在MinGW64终端里验证一下:
gcc --version nasm -v确认就位后,下载ffmpeg-4.4源码包(比如ffmpeg-4.4.tar.xz)。MSYS2终端里可以直接解压:
tar xf ffmpeg-4.4.tar.xz cd ffmpeg-4.44.3 configure、make、make install的全过程
在MinGW64终端里执行:
./configure --enable-gpl --disable-doc --disable-debug--enable-gpl开启GPL相关的功能组件;--disable-doc跳过文档构建,能省不少时间和依赖;--disable-debug去掉调试符号,让编译产物体积更小。如果想要自定义安装目录,可以加:
--prefix=/c/ffmpeg-buildconfigure脚本会检查所有依赖,并在最后汇总生成一个配置报告。如果提示缺少nasm,请先确认nasm -v是否可用。如果确实缺,就再执行一次:
pacman -S mingw-w64-x86_64-nasm然后重新configure。注意,只有前一次configure失败后,最好先make distclean清理现场再重新执行,否则残留的config文件可能干扰新配置。
configure通过后就是编译:
make -j4-j4表示用4个并行任务,如果你机器内存足够,8也行。但别一把梭直接-j64,FFmpeg编译的单位个体不小,并行任务太多容易把内存吃满,反而编译报错。正常情况下,FFmpeg 4.4全量编译大概需要5到20分钟,视机器性能而定。
编译完成后执行:
make installFFmpeg的二进制文件会安装到prefix指定目录的bin里。如果你直接放进MSYS2的system目录,还需要注意不要污染MSYS2自带的工具链。稳妥做法是自己指定一个独立prefix,后续使用时直接用全路径调用。
4.4 编译中常见的压轴错误
我编FFmpeg 4.4时实际碰到过的报错,集中整理一下:
- 报
nasm not found:缺少汇编器,按上面命令安装nasm即可。用--disable-x86asm也能跳过这个检查,但FFmpeg在x86平台上的很多优化代码会失效,性能差一截,不建议这么做。 - 报
Unknown option "--enable-xxx":configure检查到你的源码包可能不是4.4版本,某些参数在不同版本里名字有差异,确认下载的是4.4的release包。 - 报
C compiler test failed:常见于故意改PATH把MSYS2的gcc指向了外面装的MinGW64。两个工具链的头文件和库版本不同,串用很危险。解决办法:不要在MinGW64终端里手动改动PATH,或者干脆在干净的环境变量下运行。 - 报
ffmpeg: error while loading shared libraries: libavutil.so.56:编译出来的程序运行时找不到刚install的库,一般是因为没有把prefix下的bin或者lib路径加入运行时搜索路径。Windows下最简单的方式是把prefix下的bin里的DLL复制到exe同目录,或者把该目录加入PATH。
编译成功后测试一下:
ffmpeg -version看到一堆配置项和库版本输出来,就说明这条MinGW64编译FFmpeg 4.4的路线彻底走通了。
5. 安装排错:那些“装上却用不了”的真相
5.1 “gcc不是内部命令”的三种来源
这是新手遇见最多的报错,我拆开来讲。
第一种是Path变量根本没配好。可能你加的路径是C:\mingw64而不是C:\mingw64\bin,系统找不到gcc,当然报错。记住一句话:所有可执行文件都在bin里,Path加的是bin,不是上一级目录。
第二种是配完Path后没有开新终端。CMD和PowerShell在启动时读取环境变量,已经开着的窗口不会自动刷新。你改完环境变量,必须关掉所有老的终端窗口重新打开,这个细节能排掉一个百分比的求助帖。
第三种是环境变量编辑器把Path列表里原来的内容覆盖了。这个属于低级但会碰到的操作失误,尤其改系统变量时手滑删掉win10/win11自带的一堆系统路径。如果不小心覆盖了,报错可能同时包括ls、notepad都找不到,这时候检查Path里是否还有%SystemRoot%\system32。
排查时最有效的命令还是先定位:
where gcc如果输出为空,说明搜索路径里没有gcc;如果有输出,看路径符不符合你的预期。
5.2 多个gcc并存的混乱排查
很多电脑上会同时存在Qt自带的gcc、Git自带的MinGW、以及其他IDE捆绑的工具链。你的系统Path里可能有多个gcc。命令行调用时,Windows会按Path列表从上到下匹配,排在最前面的先被命中。
所以就算你的MinGW64装在C:\mingw64,只要Path里有个更靠前的Git的MinGW路径,在IDE里点击构建时可能调用的到底是谁就不一定了。这会导致一种很玄学的现象:用终端直接编译没问题,一进IDE就报各种内部错误。
解决方式有两条路。第一条,不管闲杂路径,在命令行用全路径调自己的编译器:
C:\mingw64\bin\gcc.exe hello.c第二条,把C:\mingw64\bin移到Path列表的顶部,让它优先命中。如果其他软件都在正常工作,不推荐随意删除它们的环境变量,只是调整顺序即可。
5.3 杀毒软件、中文路径与空格目录
杀毒软件对gcc这种“能生成exe的文件”存在天然敏感。个别安全软件会把MinGW64部分组件误判为可疑程序,轻则拦截执行,重则直接隔离文件。我自己在给新机器装环境时就被Windows Defender或第三方杀软拦过,所以遇到诡异报错时打开安全软件的查杀记录看一眼,确认没有“吞文件”行为,必要时把C:\mingw64加入白名单。
中文路径是个老生常谈的坑。编译器的源码编译、Makefile对路径的解析,很多情况下对非ASCII字符支持不好。你可能会遇到“头文件找不到”但明明路径人在那里,或者make解析路径时乱码的情况。不要跟工具链讲道理,直接养成项目路径全英文的习惯,顺便把用户名下的桌面、下载这些带有中文的目录避开。我的做法是项目直接放C:\work\,从根上解决问题。
空格目录前面已经提过,这里再强调一次,哪怕你妥协装了在线安装器,也请把安装目录手动改到无空格的路径,否则后续每次构建都要跟引号搏斗。
6. 用到现在,我对MinGW64安装方式的选择逻辑
6.1 只做C/C++开发:离线包最省心
如果用途只是写点本地小工具、做做算法验证、练练C/C++基础,离线包就够了。MinGW64离线包的好处是干净、独立、可控,不像MSYS2那样动辄几百上千个包,不需要时它只是个安静的开发工具。搭配VS Code或任何编辑器,都能很舒坦地写代码。
而且离线包方式对“版本洁癖”很友好。你想用哪个gcc版本就下载对应的7z包,不需要跟包管理器打交道。以后想升级,再下载新包解压覆盖,灰常直接。
6.2 要啃开源项目:直接MSYS2不要绕
但如果你跟我说“我要编译FFmpeg 4.4”,我会毫不犹豫地让你装MSYS2。这里面不只是MinGW64编译器的问题,而是整个构建体系是否顺畅的问题。你需要的nasm、pkg-config、make、shell、各种依赖库,在MSYS2环境下都是一条pacman命令的事。而在离线包里,每一个前置依赖都要手动下载、手动配路径、手动处理版本冲突,这其中的时间成本远超安装MSYS2本身的时间。
我之前也固执地觉得“装个离线包就够了”,直到编译FFmpeg时被nasm版本、pkg-config缺失、shell脚本无法执行这些事来回蹂躏,才明白一个事实:MinGW64只是编译器,MSYS2才是完整的构建生态。
6.3 我的安装习惯与避坑清单
最后,分享一个我自己沿用很久的习惯。新电脑装开发环境时,我会先问一个问题:未来三个月会不会碰任何需要configure的大型项目?会,就一次性装MSYS2;不会,就先装离线MinGW64。两个都装也不冲突,但千万别把两者的bin目录同时塞进一个Path里,否则gcc、make、甚至ld都存在同名竞争。
我这些年踩过的坑基本就这些。整个过程里最磨人的不是下载,不是解压,而是那种“装上了但用不了”的挫败感。一旦你把环境变量、动态库、nasm这几个关键点弄明白,往后不管是FFmpeg还是其他GitHub上的开源项目,都不会再有“不会装MinGW64”这种疑问了。