☰
Windows下MinGW-w64免安装版配置与GCC编译实战
2026/9/26 4:44:18 网站建设 项目流程

简介:一份已在Windows 64位环境下亲测可用的MingW64编译器工具集,面向需要在Windows平台编写C、C++或Fortran程序的开发者,可直接解压启用,免去官方安装流程的配置困扰,也适合作为便携式GCC环境随用随取。压缩包共3125个文件,以头文件(h/hpp)、静态库(a/lib)、编译器可执行文件(exe)及动态库(dll)为主,整体大小仅48.14MB,是一套精简但完整的GNU工具链,包内目录结构清晰,便于按需取用组件。该版本在CSDN已有10360人浏览学习,社区认可度较高,尤其适合新手开发者快速搭建Windows下的编译环境,进阶用户也可将其嵌入脚本或CI流程使用;整体兼容性与稳定性已得到较多用户验证,使用门槛较低。包内除gcc、g++等编译器本体外,还包含mingw32-make、ld、as、gfortran等辅助工具,以及丰富的标准库头文件,能满足日常C/C++/Fortran项目的编译、链接与调试需求;无需依赖Visual Studio等商业IDE,即可在命令行中完成从源码到可执行程序的完整构建。

1. 为什么我最终扔掉安装版,改用解压即用的 mingw64

做 Windows 下的 C/C++ 开发,绕不开 MinGW-w64 这套工具链。以前图省事,都是从某个安装器一路 Next,装完发现路径里带空格、系统 PATH 被塞了一堆东西,换机器又要重新点一遍安装向导。后来换成 mingw64 的免安装压缩包版本,直接解压、手动配一次环境变量,反而更可控,也更容易复现给同事。这篇文章就把我实际验证过可用、能直接解压使用的版本选择和解压后的配置步骤讲清楚。

需要说明的是,MinGW-w64 官方发布渠道其实长期没有统一的“绿色版”打包,社区里流传的免安装包质量参差不齐。我踩过不少坑,最后固定下来一套版本组合和目录规范,之后在好几台机器上都是同一个步骤搞定。如果你也在找 mingw64 下载和安装教程,或者正被各种安装器折腾得头疼,这篇笔记能让你少走两小时弯路。

2. 解压版 mingw64 的选型逻辑:先搞清楚你拿它干什么

2.1 为什么“直接解压无需安装”在 Windows 上更靠谱

通常我们装 GCC 工具链,安装器会往注册表写内容,把 DLL 复制到 System32,还会自动改全局 PATH。这套流程对普通用户友好,但对开发者并不理想:你同时需要多个 GCC 版本(比如 8.1.0 和 13.2.0)做交叉验证时,安装器之间会互相覆盖;卸载不干净,残留的 PATH 项可能把命令行工具指向一个不存在的路径。

解压版把整个工具链放在一个目录里,比如C:\mingw64,里面是bin、lib、include等标准布局。切换版本就是改一下当前会话的 PATH,或者用一个小脚本切换。这相当于把工具链变成了软件包管理器里的“便携应用”,不污染系统。我一般还会把这个目录放进 Git 仓库的tools文件夹里,新同事克隆下来就能编译,不用再跑安装向导。

另一个实际理由是:很多 CI 环境或者离线内网机器不允许执行安装器,但允许拷贝压缩包。解压版在这种场景下是唯一可行的办法。之前我在一台没有外网权限的测试机上配编译环境,就是靠 U 盘拷贝一个 prebuilt 的压缩包,解压后直接编译通过。

2.2 版本号怎么挑:不要盲目下载“最新版”

mingw64 的代码仓库本身是 MinGW-w64 项目,实际发布的是 GCC、binutils、gcc-libs 等组件的组合。很多免安装压缩包其实是第三方从 MSYS2 里抽出来,或者用 w64devkit 这类项目打的包。社区里流传较广的版本有这么几类:

  • Sourceforge 上 mingw-w64 官方发布页的压缩包,例如x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z。这是老牌版本,稳定但因为 GCC 8 年代较早,对 C++20/23 支持不全。
  • w64devkit 的发布包,比如w64devkit-x64-1.17.0.zip,自带 GCC、make、gdb,体积小,解压即用,适合做练习题或小项目。
  • MSYS2 的mingw-w64-ucrt-x86_64-toolchain安装后,将整个mingw64目录拷出来当便携版用。这种方式能取得较新的 GCC(比如 13.x),但依赖的 DLL 也比较多。

我最终固定使用的是w64devkit-x64 的免安装 zip 包。原因是它的 bin 目录里同时带了gcc.exe、g++.exe、gdb.exe、mingw32-make.exe和ld.exe,压缩包不到 300MB,解压完直接放到任意路径就能用。如果你需要编译 FFmpeg 4.4 这种大型 C 项目,我建议用 MSYS2 的便携目录而不是 w64devkit,因为 FFmpeg 的 configure 脚本会检测make、yasm、pkg-config等工具,w64devkit 虽然带了 make,但缺少 yasm,还得另外准备。

提示:选择解压版本时,重点看构建时依赖的运行时。MSYS2 的 ucrt 或 msvcrt 版本,会影响生成 exe 在目标机器上是否需要 UCRT 运行库。Windows 10 和 11 自带 UCRT,但老系统可能缺。

2.3 解压后目录结构的最小自检

拿到压缩包,不要急着解压即用,先检查几个关键文件。常见的打包方式有两种:压缩包根目录直接是bin/gcc.exe,或者根目录是mingw64/bin/gcc.exe。第一种解压到C:\后,你得到C:\bin\gcc.exe;第二种解压到C:\后,得到C:\mingw64\bin\gcc.exe。我习惯统一整理成D:\dev\mingw64作为最终根目录,里面必须能看到bin、lib、include、libexec这四个子目录。

自检命令在 PowerShell 里执行:

# 进入你解压后的根目录,例如 D:\dev\mingw64 cd D:\dev\mingw64 # 列出 bin 目录下关键可执行文件 ls bin\gcc.exe, bin\g++.exe, bin\gdb.exe, bin\mingw32-make.exe # 查看 gcc 版本 .\bin\gcc.exe --version

如果版本输出正常,说明这个压缩包的核心文件没有缺失。如果提示缺少libgcc_s_seh-1.dll或libstdc++-6.dll,那说明解压目录里没有把这些运行时 DLL 放在bin下,或者系统 PATH 找不到它们。此时不要去网上找单独 DLL 塞进 System32,正确做法是回到原始包,确认解压时没有漏文件。之前我遇到一次七牛云下载的压缩包解压后文件数少了一半,就是因为下载过程中 zip 被截断,重新下载才解决。

3. 用免安装 mingw64 在本地跑通第一个 C 程序

3.1 下载与解压的操作步骤

如果你决定跟进 w64devkit,先去它的发布页找后缀为.zip的包,比如w64devkit-x64-1.17.0.zip。下载后放在一个不包含中文和空格的路径下,例如D:\downloads。然后用 PowerShell 解压,不建议用 Windows 自带的“全部提取”,因为自带解压对长路径和符号链接处理不好。

# 创建目标目录 New-Item -ItemType Directory -Path D:\dev -Force # 将下载好的 zip 解压到 D:\dev Expand-Archive -Path D:\downloads\w64devkit-x64-1.17.0.zip -DestinationPath D:\dev -Force # 查看解压出来的顶层目录名 Get-ChildItem D:\dev

解压完成后,你会看到D:\dev\w64devkit或D:\dev\w64devkit-x64-1.17.0这样的目录。为了统一,重命名一下:

# 如果目录名是 w64devkit,就用这个;如果是别的,先改 Rename-Item D:\dev\w64devkit D:\dev\mingw64

逻辑说明:Expand-Archive会把 zip 内所有内容解压到DestinationPath下,如果压缩包根目录带一个文件夹,那解压结果就在D:\dev\对应文件夹。重命名成mingw64是为了之后配置环境变量时路径短且好记。注意Rename-Item的路径要和实际解压出来的目录名保持一致,建议先Get-ChildItem看看再动手。

参数说明:-Force在Expand-Archive里表示如果目标目录里有同名文件则覆盖,但通常DestinationPath不存在时,这个参数会静默创建目录。如果你遇到“目标目录已存在且非空”的报错,说明之前解压过,建议先删除目录再解压,避免残留文件混淆。

3.2 配置环境变量:临时生效与会话生效

环境变量配置有两个层级:当前终端临时生效,适合一次性的编译任务;永久写入用户 PATH,适合日常开发。我建议先试临时,确认没问题再写永久,避免配错了影响全局。

# 临时设置,只对当前 PowerShell 窗口有效 $env:Path = "D:\dev\mingw64\bin;" + $env:Path # 验证 gcc 可用 gcc --version

如果命令输出类似gcc (GCC) 13.2.0这样的信息,说明工具链已经就绪。接下来写一个最小 C 程序试试。

// hello.c #include <stdio.h> int main(void) { printf("mingw64 portable works\n"); return 0; }

用 gcc 编译并运行:

gcc -Wall -Wextra hello.c -o hello.exe ./hello.exe

参数说明:-Wall和-Wextra开启常用警告,保证代码里没有潜在隐患;-o hello.exe指定输出文件名。如果编译后运行提示找不到libgcc_s_seh-1.dll,说明你的 PATH 没有包含 mingw64 的 bin 目录,或者这个 DLL 不在 bin 里。正常解压的包,bin 目录下会有这个文件,因为 gcc 生成的 exe 默认动态链接异常处理库。

提示:临时环境变量在 PowerShell 里只对当前会话有效。你关掉终端再开,需要重新设置。但这反而是一个安全验证方式:如果临时设置能编译,但重新开终端后不行,说明问题就在永久环境变量没配好。

3.3 把 mingw64 写进用户 PATH 的两种方法

确认临时方案没问题后,再写永久路径。最稳妥的是通过系统设置界面操作,但命令行方式更容易复现。以下是在 PowerShell 里写入用户级 PATH 的命令,注意它不会覆盖已有条目,而是追加到末尾。

# 读取当前用户 PATH 到一个变量 $oldPath = [Environment]::GetEnvironmentVariable("Path", "User") # 如果还没包含 mingw64,就追加 if ($oldPath -notlike "*D:\dev\mingw64\bin*") { [Environment]::SetEnvironmentVariable("Path", $oldPath + ";D:\dev\mingw64\bin", "User") }

执行完,新开的终端才会生效。当前终端里如果要立即用,可以刷新一下:

# 用当前进程的环境变量重新加载 $env:Path = [Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [Environment]::GetEnvironmentVariable("Path", "User")

逻辑说明:上面的刷新语句把系统级和用户级 PATH 拼接后赋给当前进程,这样就不用重启终端。但注意如果之前手动设置过临时 PATH,这个操作会覆盖它,所以建议在干净终端里执行。

参数说明:[Environment]::SetEnvironmentVariable的第三个参数"User"表示作用于当前用户,不会影响其他用户。如果你希望所有系统用户都能用,可以改成"Machine",但普通用户对C:\或D:\下的目录没有写权限,运行时可能会遇到权限问题,所以我不推荐全局设置。

4. 用免安装 mingw64 编译 FFmpeg 4.4:完整命令与参数要点

4.1 为什么 FFmpeg 4.4 是验证工具链的好目标

很多人拿到 mingw64 后第一件事就是编译 FFmpeg,因为 FFmpeg 的 configure 脚本会调用编译器、汇编器、归档器,还能顺带检测你的工具链是否接近 Linux 行为。我选择 FFmpeg 4.4 作为验证项目,是因为它相比最新的 6.x 或 7.x,对编译器版本要求没那么激进,GCC 8 以上都能过,而且网上能搜到的“mingw64 编译 ffmpeg4.4”教程很多,碰到问题容易对照。

不过有一件事必须提前说明:用 w64devkit 直接编译 FFmpeg 4.4 比较痛苦,因为 FFmpeg 需要yasm或nasm,而 w64devkit 默认不带。所以这一步我用的是 MSYS2 的便携 mingw64 目录,或者你可以在 w64devkit 里额外放一个yasm.exe。常见的做法是下载yasm-1.3.0-win64.exe改成yasm.exe放进bin目录,但注意版本要匹配,太新的 yasm 反而可能不支持旧的 x86 汇编语法。

4.2 用 MSYS2 的 mingw64 目录当便携工具链

MSYS2 安装器虽然是一个安装程序,但它装完后的C:\msys64\mingw64目录本身就是完整的工具链目录,你可以把这个目录整个复制到别的盘当便携版。我不推荐直接动安装器本身,而是先在一台机器上完成 MSYS2 的安装,然后运行以下命令更新工具链:

# 在 MSYS2 终端里执行 pacman -Syu --noconfirm pacman -S --needed base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-yasm mingw-w64-x86_64-pkg-config

更新完成后,C:\msys64\mingw64\bin里就有了gcc.exe、yasm.exe、pkg-config.exe等。然后把这个目录复制出来:

# 在 PowerShell 中执行,注意路径 Copy-Item -Recurse -Force C:\msys64\mingw64 D:\dev\msys64-mingw64

复制过程中可能会遇到个别符号链接或硬链接损坏的问题,但通常不影响编译。复制完成后,把D:\dev\msys64-mingw64\bin放在 PATH 的靠前位置,确保gcc和yasm都来自这个目录,而不是系统自带的其他版本。

4.3 configure 与 make 的完整参数,以及我踩过的坑

下载 FFmpeg 4.4 源码,进入目录后按以下步骤执行。注意一定要在 MinGW 环境里执行,不能直接使用 Windows 自带的 PowerShell 跑./configure,因为脚本依赖sh和 POSIX 命令。你可以用 MSYS2 的 bash 终端,或者把C:\msys64\usr\bin\bash.exe单独调起来。

# 假设我们已进入 ffmpeg-4.4 源码根目录 export PATH="/d/dev/msys64-mingw64/bin:$PATH" ./configure \ --toolchain=mingw32 \ --arch=x86_64 \ --target-os=mingw32 \ --enable-cross-compile \ --cross-prefix=x86_64-w64-mingw32- \ --disable-doc \ --disable-debug \ --enable-gpl \ --enable-version3 \ --disable-d3d11va \ --disable-dxva2 \ --disable-schannel make -j8

参数说明:--cross-prefix指定工具链前缀,如果你的gcc.exe名字就叫x86_64-w64-mingw32-gcc.exe,那前缀就是x86_64-w64-mingw32-。MSYS2 的工具链通常同时提供无前缀和多前缀的版本,如果只有一个gcc.exe,你可以去掉--cross-prefix和--cross-compile,直接让 configure 检测本机编译器。--disable-d3d11va和--disable-dxva2是关掉 Windows 硬件加速解码,我这样做的原因是这两个模块在纯 mingw 环境下经常遇到 dxva 头文件版本冲突,如果不关,编译时会在libavcodec/d3d11va.h和dxva2.h附近报一堆错。

make -j8的-j参数表示并行编译任务数,一般设为本机 CPU 核心数或稍大。但 FFmpeg 的某些源文件有前后依赖,并行数过大偶尔会出现“header 文件找不到”的假报错。遇到这种情况,先执行make -j1复现一次,如果通过就说明不是源码问题,而是并行编译的资源竞争,把数字缩到核心数一半即可。

4.4 编译结果验证:生成 ffmpeg.exe 与 ffprobe.exe

如果一切顺利,编译结束后在源码目录的ffmpeg.exe、ffprobe.exe会生成出来。验证它们是否正常工作,不能只看文件存在,还要跑一次实际转码测试:

# 生成一个 3 秒的测试视频 ./ffmpeg.exe -f lavfi -i testsrc=duration=3:size=640x480:rate=30 -f lavfi -i sine=frequency=440:duration=3 -c:v libx264 -c:a aac -movflags +faststart test.mp4 -y

执行后如果没有报错,并且生成的文件大小超过 100KB,基本说明你这套 mingw64 工具链已经具备编译真实项目的能力。比这更严格的做法是用ffmpeg.exe -decoders查看解码器列表,确认没有因为禁用d3d11va导致解码器数量异常;其实那个开关只影响硬件加速,软件解码器不受影响。

注意:如果你在 configure 后修改了工具链路径,或者把 mingw64 目录移了位置,必须删掉config.*和编译产物重新 configure。FFmpeg 的配置会记录绝对路径,移动后直接 make 会报“No such file or directory”。

5. 解压版 mingw64 的常见故障排查:现象、原因、解决

5.1 现象:运行 gcc 报 “不是内部或外部命令”

这是最典型的 PATH 配置问题。表现为你在任意目录输入gcc,系统提示找不到命令,但直接进到D:\dev\mingw64\bin目录下执行gcc.exe却正常。

原因:当前终端的 PATH 环境变量里没有包含D:\dev\mingw64\bin。可能是你只设置了临时 PATH,重开终端后失效;或者你设置了用户 PATH,但当前终端没刷新。

解决:先用绝对路径确认工具本身没问题:

D:\dev\mingw64\bin\gcc.exe --version

如果这个能跑,再按上面 3.3 的刷新命令重载 PATH。刷新后检查:

$env:Path -split ';' | Select-String -Pattern 'mingw64'

如果没有输出任何匹配,说明 PATH 写入没成功或写错了路径。注意检查路径里的分隔符,用户 PATH 的追加要用分号,不要用空格。

5.2 现象:编译出的 exe 运行时报缺少 DLL

有时候 gcc 编译正常,exe 也生成了,但双击运行或者从控制台运行时报libgcc_s_seh-1.dll not found或libstdc++-6.dll not found。

原因:这些 DLL 存在于 mingw64 的bin目录,但系统运行时找不到。常见原因有两个:PATH 没包含 mingw64 的 bin,或者你在编译时用了-static-libgcc -static-libstdc++也没有解决问题,因为还有libwinpthread-1.dll等额外依赖。

解决:先检查 DLL 是否真的在 bin 里:

Test-Path D:\dev\mingw64\bin\libstdc++-6.dll

如果不存在,说明这个解压包不完整,重新下载或者换一个打包来源。如果存在,确认 exe 和这些 DLL 在同一个目录下再运行。对于需要分发给别的机器的场景,我一般直接用:

gcc -o hello.exe hello.c -static -static-libgcc -static-libstdc++

这样生成的 exe 不再依赖任何动态运行时,文件会大几倍,但放到任何 Windows 机器上都能跑。代价是哈,编译出来的可执行文件体积从 100KB 变成 1MB 左右,这是常态。

5.3 现象:make 命令不存在或版本不对

很多项目用 Makefile 构建,你在解压版 mingw64 的 bin 目录里找到了mingw32-make.exe,但项目执行make时报找不到命令。

原因:mingw32-make 和 GNU make 在 Windows 上名字不同。MSYS2 的 mingw64 工具链提供的是mingw32-make.exe,而不是make.exe。有些项目写死了 Makefile 里的make命令,需要你额外创建别名或符号链接。

解决:在 bin 目录里复制一份:

Copy-Item D:\dev\mingw64\bin\mingw32-make.exe D:\dev\mingw64\bin\make.exe

然后验证:

make --version

如果项目里还用了pwd、rm、cp这些 Unix 命令,单纯的 mingw64 工具链也满足不了,建议直接换用 MSYS2 的环境,那里有完整的 POSIX 工具集。

5.4 现象:GCC 版本够新,但编译 C++17 代码报std::string_view找不到

这不是编译器版本太老,而是你的头文件搜索路径没有包含 GCC 自带的 C++ 标准库头文件。比如 std::string_view 在 GCC 7 以上就支持,但如果 include 路径被某个第三方库污染,就会出错。

原因:解压版目录如果被移动,lib\gcc\x86_64-w64-mingw32\<version>\include\c++的相对路径没有变化,但某些项目里通过-I手动指定了其他 include 目录,覆盖了默认搜索路径的第一项。

解决:先用 gcc 的预处理参数检查实际头文件路径:

gcc -v -E -x c++ - < /dev/null 2>&1 | Select-String -Pattern "搜索|Search"

观察输出里 include 路径是否包含D:\dev\mingw64\include\c++\13.2.0这类目录。如果没有,检查环境变量CPATH或C_INCLUDE_PATH是否被设置了。我之前就是因为在系统变量里加了CPATH=C:\other\include,把它删掉后问题就消失了。

6. 把解压版 mingw64 用成“后悔药”:目录克隆与版本隔离

6.1 在同一台机器上并排多套工具链

既然解压版不污染系统路径,我倾向于在D:\gcc-toolchains下同时保留几个版本,比如一个 GCC 8 用于老项目,一个 GCC 13 用于新项目。每个版本用自己的目录,切换时只改当前终端的 PATH 前缀,互不干扰。

目录结构这样组织:

D:\gcc-toolchains\ ├── mingw64-gcc8\ │ └── bin\gcc.exe ├── mingw64-gcc13\ │ └── bin\gcc.exe └── switch.ps1

对应的切换脚本(PowerShell):

# switch.ps1 用法:.\switch.ps1 gcc13 param([string]$ver) $base = "D:\gcc-toolchains\mingw64-$ver\bin" if (!(Test-Path $base)) { Write-Host "版本不存在: $ver" exit 1 } $env:Path = $base + ";" + $env:Path

之后在任意终端执行. .\switch.ps1 gcc13,当前会话的 gcc 就变成对应版本。注意此处我用的是“点”加空格的方式调用脚本,这样环境变量的修改会保留在当前进程中,否则脚本结束后变量会被丢弃。

6.2 用gcc -v验证“当前用的是哪个版本”

多套工具链最容易出现“明明切了版本但编译时还是旧版”的情况。我常用的排查技巧是在项目根目录执行:

gcc -v 2>&1 | Select-String -Pattern "COLLECT_GCC="

输出里的COLLECT_GCC=/path/to/gcc.exe就是你当前实际使用的编译器路径。如果这个路径不是你预期的那套,检查 PATH 顺序:更靠前的 bin 目录会优先命中。PowerShell 里可以用:

$env:Path -split ';' | Where-Object {$_ -like '*gcc*'}

看看里面有几个 mingw64 路径,按照从上往下的顺序,第一个存在的 gcc.exe 会被选中。

6.3 一个让我少折腾两次的编译技巧:给 CMake 与 FFmpeg 单独传编译器路径

很多构建系统并不完全相信 PATH 环境变量,比如 CMake 一旦配置好,之后会记录编译器绝对路径。如果你移动了 mingw64 目录,CMake 缓存里的路径失效,就会报“CMAKE_C_COMPILER-NOTFOUND”。此时不要重新装 CMake,直接删除项目的CMakeCache.txt再重新 configure。我一般会养成习惯,在 CMake 命令行里显式指定:

cmake -S . -B build -G "MinGW Makefiles" \ -DCMAKE_C_COMPILER=D:/dev/mingw64/bin/gcc.exe \ -DCMAKE_CXX_COMPILER=D:/dev/mingw64/bin/g++.exe \ -DCMAKE_MAKE_PROGRAM=D:/dev/mingw64/bin/mingw32-make.exe

这个习惯也救过我一次:项目里其他人安装的 Visual Studio 自带了一个cl.exe,CMake 默认检测到了 MSVC,导致所有 GCC 专属编译选项被忽略。显式指定编译器后,整个项目回归正轨。

6.4 最后说句老实话

明确定位自己是“便携工具链使用者”,就不要试图把一个解压版优化成完全兼容 Unix 的完整环境。它能解决编译器的存在性问题,但解决不了所有项目的基于 POSIX 的构建脚本。真正把免安装 mingw64 用顺手的核心,是坚持同一目录、同一 PATH 顺序,并且把版本信息写进项目的 README。遇到再奇怪的报错,先执行gcc -v看当前到底是哪套编译器,再翻 config 日志,最后再骂变量。这套方法陪我从 GCC 8 一路用到 GCC 13,没走过弯路,希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询