MSYS2 不是编译器,是给 Windows 装 GNU 工具链的包管理器加三个 shell。 三个 shell 选错,编出来的东西会带着 msys-2.0.dll 到处跑。
1.2.1 讲了三条路,这一篇把 MinGW 那条路落地。 下一篇 1.2.3 更新它,再下一篇用 pacman 装依赖。
一、MSYS2 到底是什么
一句话:它是 Windows 上的 pacman 加一套 POSIX 环境。
装完你会得到 C:\msys64,里面同时住着三套互不干扰的工具链,每套有自己的 /bin。
这是理解 MSYS2 的关键——它不是一层,是三层。
启动方式 编译器路径 装的包前缀
MSYS2 MSYS /usr/bin pacman 直接装,如 make MSYS2 MINGW64 /mingw64/bin mingw-w64-x86_64- MSYS2 UCRT64 /ucrt64/bin mingw-w64-ucrt-x86_64-
MSYS 那层是给构建脚本用的:configure 是 bash 脚本,里面一堆 test -f、$(...),
得有个能跑 bash 的环境。
MINGW64 与 UCRT64 才是编译器住的地方,区别只在 C 运行库:MINGW64 用老的 msvcrt.dll,
UCRT64 用 Windows 10 起的 ucrtbase.dll。
2026 现状:MSYS2 现在把 UCRT64 立为默认。
教材成书时默认是 MINGW64,所以照书敲的包名可能是 mingw-w64-x86_64-gcc,
装进 UCRT64 那层要换成 mingw-w64-ucrt-x86_64-gcc。
二、装完先确认自己在哪个 shell
开错窗口是这一节最常见的坑,而且报错很晚才出现。
在 MSYS 窗口里 pacman -S gcc,装进来的是 MSYS 版 gcc,
用它编的 FFmpeg 会依赖 msys-2.0.dll——一个只在 MSYS2 环境里存在的 DLL。
拿到别的机器上,第一句就是「找不到 msys-2.0.dll」。
一条命令判断自己在哪层: echo $MSYSTEM,只会回三个值之一。
$MSYSTEM 你在哪层 该用它编 FFmpeg 吗
MSYS MSYS 层 不该,只拿来跑脚本 MINGW64 MinGW64 层 可以 UCRT64 UCRT64 层 可以,且是现在推荐
另一条更直接: which gcc。
回 /usr/bin/gcc 就是错层,回 /mingw64/bin/gcc 或 /ucrt64/bin/gcc 才对。
三、装完的目录长什么样
下面这些路径是本课列出来的清单,本机一个都没有——这台机器没装 MSYS2,也没有 Visual Studio。 路径 是什么
C:\msys64\msys2.exe 启动 MSYS 层 C:\msys64\mingw64.exe 启动 MINGW64 层 C:\msys64\ucrt64.exe 启动 UCRT64 层 C:\msys64\ucrt64\bin\gcc.exe 编译器本体 C:\msys64\etc\pacman.conf 包管理器的配置文件
记不住路径没关系,记这一条: 哪个窗口里敲 gcc --version 有输出,就固定用那个窗口。
换窗口等于换工具链,别在两套之间跳。
四、第一个 FFmpeg 前的十五分钟
装完 MSYS2,按这个顺序走一遍,能省掉后面一半的报错: 序 做什么 验什么
1 开 UCRT64 窗口 echo $MSYSTEM 回 UCRT64 2 pacman -Syu 更新一遍 重开窗口后再跑一遍 3 装 make diffutils yasm nasm make --version 有输出 4 装 gcc 与 pkg-config gcc --version 有输出 5 git clone ffmpeg 源码 ls 能看到 configure
第三步别跳过 diffutils。 configure 里到处是 cmp 与 diff,少了它们,
configure 会报一个跟依赖完全无关的错。
五、动手 Demo:装 MSYS2——三种 shell 选错,后面全白干
本机没装 MSYS2,所以 Demo 做两件事:查路径在不在,摆对照表。 查完会看到六个候选路径一个都没命中。
import os
cands = ["C:\\msys64", "C:\\msys2", "C:\\MinGW", "C:\\mingw64",
"C:\\Program Files\\Microsoft Visual Studio"]
for c in cands:
print("%-50s %s" % (c, "在" if os.path.isdir(c) else "不在"))
实跑输出:
--------------------------------------------------------------------
装 MSYS2——三种 shell 选错,后面全白干
--------------------------------------------------------------------
**① MSYS2 装完不是一个环境,是三个**
启动方式 编译器前缀 装的包 编什么
-----------------------------------------------------------------------------------
MSYS2 MSYS /usr/bin pacman -S make 只用来跑构建脚本
MSYS2 MINGW64 /mingw64/bin mingw-w64-x86_64-* 传统 MinGW 路
MSYS2 UCRT64 /ucrt64/bin mingw-w64-ucrt-x86_64-* 新默认,推荐
**② 本机检查:装没装**
路径 在不在
-------------------------------------------------------------
C:\msys64 不在
C:\msys2 不在
C:\MinGW 不在
C:\mingw64 不在
C:\Program Files\Microsoft Visual Studio 不在
C:\Program Files (x86)\Microsoft Visual Studio 不在
六个路径里命中 **0 个**。
本机既没 MSYS2 也没 Visual Studio,所以这一节的命令,只能在有那台机器的电脑上照做。
**③ 选错 shell 会怎样**
在 MSYS shell 里敲 `pacman -S gcc`,装进来的是 MSYS 版 gcc,编出的程序依赖 `msys-2.0.dll`;
拿这个产物去发版,用户机器上一定缺 DLL。
**判断自己在哪个 shell,一条命令就够:** `echo $MSYSTEM`,
回 `MINGW64` / `UCRT64` / `MSYS` 三个值之一。
**④ 2026 现状**
教材成书时默认走 MINGW64;
MSYS2 现在把 **UCRT64** 立为默认,因为它的 C 运行库是 Windows 自带的 ucrtbase.dll,不再拖 msvcrt。
新装的话选 UCRT64,包名把 `mingw-w64-x86_64-` 换成 `mingw-w64-ucrt-x86_64-`。
六个路径全不在。 这条结果不是缺陷,是本课所有编译命令只能「给清单」的原因。 有 MSYS2 的那台机器上,同样的检查会有一两条回「在」。
30 秒实验
- 装完 MSYS2 后,分别开三个窗口敲
echo $MSYSTEM,看三个值。 - 在 MSYS 窗口里
pacman -S gcc,再which gcc——确认它装到了 /usr/bin。 - 在 UCRT64 窗口里
pacman -Ss gcc,看包名是不是以mingw-w64-ucrt-x86_64-开头。
常见误区
- 三个窗口随便挑一个用。 编 FFmpeg 必须用 MINGW64 或 UCRT64,MSYS 层的 gcc 会产出依赖 msys-2.0.dll 的东西。
- 以为 MSYS2 就是 MinGW。 MSYS2 是包管理器与环境,MinGW 是它里面那套编译器。
- 装完立刻编 FFmpeg。 先
pacman -Syu更新,否则老包与新脚本会对不上。
自测三问(点开对答案)
1. 怎么一句话确认自己在哪一层? —— `echo $MSYSTEM`,回 MSYS / MINGW64 / UCRT64 三者之一。回 MSYS 就换窗口。 2. UCRT64 与 MINGW64 的差别在哪? —— C 运行库不同。前者用 Windows 10 起的 ucrtbase.dll,后者用老 msvcrt.dll。新装一律选 UCRT64。 3. 为什么编 FFmpeg 不能只在 MSYS 层装 gcc? —— MSYS 层的 gcc 产出依赖 msys-2.0.dll,那个 DLL 只在 MSYS2 环境里存在,产物没法分发。- ☐ (本节完,下一节 1.2.3 更新 MSYS2)