第一次更新要跑两轮,中间还得关窗口重开。
升级时比较版本号不是按字符串比,1.0.9 比 1.0.10 小。
装完 MSYS2 的第一件事不是装 gcc,是更新。 更新完才轮到 1.2.4 的 pacman 常用命令。
一、三条命令,别记混
-Sy 只刷新包数据库,-Su 只升级,-Syu 两件一起做。
命令 做什么 什么时候用
pacman -Sy 刷新数据库 想知道有哪些新包 pacman -Su 升级已装的包 数据库已刷新过 pacman -Syu 刷新加升级 日常就用这一条
为什么不能只 -Sy 不 -Su: 数据库说某包是 2.0,而你手上是 1.0,
接下来装一个依赖 2.0 的新包时,pacman 会认为「条件满足」直接装——结果就是半新半旧,
这种状态在 MSYS2 上叫做 partial upgrade,是官方明确不建议的。
这条规矩在 Arch 系上是大忌,MSYS2 沿用了同一套 pacman,规矩一样。
二、为什么第一次要关窗口重开
因为要升级的东西里,包含正在运行的自己。
msys2-runtime 是那层 POSIX 环境的核心,它本身也在升级名单里。
它一换,正在跑的 pacman 就成了「旧核心跑新脚本」,继续往下走会出各种奇怪错误。
所以流程是: pacman -Syu → 提示关窗口 → 重开 → 再 pacman -Su。
第二次跑完没有「请重开」的提示,才算更新完。
三、版本号怎么比:逐段比,不是按字符串比
pacman 的版本号格式是 epoch:pkgver-pkgrel,三段。
比较规则:先比 epoch(没有就当 0),再比 pkgver,最后比 pkgrel;
每一段里按「数字段当数字、字符段当字符」逐个比,谁先分出大小谁赢。
左 右 谁大 关键点
1.2.3-1 1.2.3-2 右 pkgrel 大 1.2.3-1 1.2.10-1 右 10 比 3 大,按数值比 5.1.2-1 5.1.2rc1-1 右 数字段之后还有字符段 2:1.0-1 1:9.9-9 左 epoch 先定胜负 1.0.9-1 1.0.10-1 右 当字符串比会反
最后一行是最值钱的一行。 字符串比较里 1.0.9 大于 1.0.10,因为字符 9 大于 1;
按段比较里 10 是数字十,就是比 9 大。写升级脚本、写自己的版本判断,栽在这一处的次数最多。
本机 Demo 里这五组全部与预期一致,比较器是本课自己写的,规则照 pacman 的 vercmp 复原。
四、更新之后先验三样
更新跑完不等于环境好了,三样都要验: 验什么 命令 期望
pacman 本身 pacman -Q pacman 有版本号 gcc 能不能跑 gcc --version 第一行有版本 make 在不在 make --version GNU Make 4.x
第三条常被忽略:make 的版本太老会让 FFmpeg 的 Makefile 解析出错,报的错却指向某个变量。
看见莫名其妙的 make 报错,先 make --version。
五、动手 Demo:更新 MSYS2——为什么第一次必须更新三遍
本机没有 pacman,所以这一段做的是「把 vercmp 的规则写出来跑一遍」。 五组对照全部断言,错一组就不会往下走。
def key(v):
epoch, rest = (v.split(":", 1) + ["0"])[:2] if ":" in v else ("0", v)
pkgver, pkgrel = (rest.rsplit("-", 1) + ["0"])[:2]
# 每段再切成「数字段 / 字符段」交替的序列
...
assert cmp("1.0.9-1", "1.0.10-1") == -1
实跑输出:
--------------------------------------------------------------------
更新 MSYS2——为什么第一次必须更新三遍
--------------------------------------------------------------------
**① 更新分三段,不是一条命令跑完**
步 命令 干什么
---------------------------------------------------
1 pacman -Sy 只刷新包数据库,不装东西
2 pacman -Su 按新数据库升级已装的包
3 pacman -Syu 两件一起做,最常用
**为什么第一次要重开窗口再更新一遍**:MSYS2 的核心包 `msys2-runtime` 自己也在升级名单里,它一换,
正在跑的 pacman 就成了「用旧核心跑新脚本」,所以程序会让你关窗口,
重开后 `pacman -Su` 把剩下的装完。
**② pacman 的版本号比较规则,是个真坑**
格式是 `epoch:pkgver-pkgrel`,比较时**从左往右按段比,数字段按数值比、字符段按字典序比**,
谁先分出大小谁赢。下面这套比较器是本课自己写的,规则跟 pacman 的 vercmp 一致。
左 右 谁大 为什么
----------------------------------------------
1.2.3-1 1.2.3-2 右赢 逐段比
1.2.3-1 1.2.10-1 右赢 逐段比
5.1.2-1 5.1.2rc1-1 右赢 逐段比
2:1.0-1 1:9.9-9 左赢 逐段比
1.0.9-1 1.0.10-1 右赢 逐段比
五组全部与预期一致——特别是 `1.0.9` 小于 `1.0.10` 这一组,**把它当字符串比就会比反**,
这是升级脚本写错最常见的一处。
**③ 更新完先别急着编**
`pacman -Q gcc` 看版本,`gcc --version` 看能不能跑。
两条都对了,再动 FFmpeg 的源码目录,否则 configure 报的错你分不清是源码问题还是工具链没装好。
五组断言全过,说明这套比较器与 pacman 的规则一致。 最后一组是最关键的:按字符串比会把结论比反。
30 秒实验
- 在装好的 MSYS2 里敲
pacman -Q pacman,再用pacman -Qi pacman看依赖。 - 把
1.0.9与1.0.10两个字符串直接>比较,看 Python 给出什么结果——和版本比较的结论正好相反。 pacman -Syu跑到提示重开时,先别关,看看报了什么,再关窗口重开跑-Su。
常见误区
- 只跑
-Sy不跑-Su。 数据库新、包旧,接下来装任何东西都可能装出半新半旧的状态。 - 更新时不关窗口。 msys2-runtime 升级后旧核心跑新脚本,会出各种奇怪错误。
- 用字符串比较版本号。
1.0.9会被判成比1.0.10大,升级判断直接反掉。
自测三问(点开对答案)
1. 为什么第一次更新要关窗口重开? —— 因为要升级的 msys2-runtime 是正在运行的那层核心,换掉它之后旧进程跑新脚本会出错。 2. `1.0.9` 与 `1.0.10` 哪个新?为什么字符串比较会得出相反结论? —— 1.0.10 新。字符串比较逐字符比,`9` 大于 `1`,所以在第三位就分出胜负;版本比较把 10 当数字十。 3. `-Sy` 单独用有什么风险? —— 数据库刷新了但包没升级,接下来装的包若依赖新版,会形成半新半旧的 partial upgrade 状态。- ☐ (本节完,下一节 1.2.4 Pacman 使用命令)