Arch Linux AUR 依赖地狱:调试 ICU 76 到 78 的迁移

发布: (2025年12月25日 GMT+8 08:01)
9 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的正文内容,我将为您翻译成简体中文并保留原有的格式、Markdown 语法以及技术术语。谢谢!

问题

我最近在我的基于 Arch 的系统(EndeavourOS)上尝试启动 Notepadqq 时遇到了令人沮丧的问题:

$ notepadqq
/usr/bin/../lib/notepadqq/notepadqq-bin: error while loading shared libraries:
libicui18n.so.76: cannot open shared object file: No such file or directory

这是一个经典的共享库依赖问题,在像 Arch Linux 这样的滚动发行版中尤为常见。

理解根本原因

什么是 ICU?

ICU(International Components for Unicode)是一套成熟、广泛使用的 C/C++ 库,提供 Unicode 和全球化支持。许多应用依赖它,包括 Qt 的 WebEngine 组件。

滚动发布的挑战

问题源于官方 Arch 软件库与 AUR 包之间的关键版本不匹配:

发生了什么细节
Arch 上游在官方仓库中已升级至 ICU 78
Notepadqq(AUR)仍然针对 ICU 76 编译
Qt5WebEngine已从官方仓库移除,但仍留在我的系统中,仍链接到 ICU 76

核心问题: Notepadqq 自 2018 年起未再积极维护。作为 AUR 包,在 Arch 更新系统库(如 ICU)时不会自动重新构建。这导致了以下不同步:

  • 官方仓库包(ICU 78)
  • 过时的 AUR 二进制(期待 ICU 76)
  • 孤立的仓库包(Qt5WebEngine 使用 ICU 76 链接)

这种级联的依赖不匹配是将官方包与未维护的 AUR 软件混用时的常见陷阱。

诊断步骤

1. 检查当前 ICU 版本

$ ls /usr/lib/libicui18n.so*
/usr/lib/libicui18n.so
/usr/lib/libicui18n.so.78
/usr/lib/libicui18n.so.78.1

这确认我使用的是 ICU 78,而应用程序需要的是 76 版。

2. 确认软件包来源

$ pacman -Ss notepadqq
# (no output)

$ yay notepadqq
1 aur/notepadqq 2.0.0beta-3 (+1 0.32) (Installed)

Notepadqq 是从 AUR 安装的,因此在系统库更改时不会自动重新构建。

3. 尝试重新构建

$ yay -S notepadqq --rebuild

导致链接错误:

/usr/bin/ld: /usr/lib/libQt5WebEngineCore.so: undefined reference to `icu_76::Normalizer::normalize(...)'
/usr/bin/ld: /usr/lib/libQt5WebEngineCore.so: undefined reference to `ucnv_open_76'

4. 找出真正的罪魁祸首

$ pacman -Qo /usr/lib/libQt5WebEngineCore.so
/usr/lib/libQt5WebEngineCore.so is owned by qt5-webengine 5.15.19-4

qt5-webengine 本身是针对旧的 ICU 版本编译的。

5. 仓库发现

$ sudo pacman -Syu qt5-webengine
error: target not found: qt5-webengine

关键发现: qt5-webengine 已从官方 Arch 软件库中移除,但仍作为孤儿软件包留在系统中。

解决方案

1. 删除冲突的包

sudo pacman -Rns qt5-webengine notepadqq

已删除的包

  • qt5-webengine (~ 159 MiB)
  • notepadqq (~ 5.9 MiB)
  • 相关依赖 (qt5-location, qt5-webchannel, qt5-websockets)

总共释放: ≈ 174.9 MiB

2. 从 AUR 重新构建 qt5-webengine

yay -S qt5-webengine

该软件包从源码编译,并链接到当前的 ICU 78 库。

3. 重新构建 notepadqq

yay -S notepadqq

由于 qt5-webengine 现在已正确链接到 ICU 78,Notepadqq 可以无错误地构建。

4. 验证链接

ldd /usr/bin/notepadqq | grep icu

输出:

libicui18n.so.78 => /usr/lib/libicui18n.so.78
libicuuc.so.78   => /usr/lib/libicuuc.so.78

该应用程序现在链接到正确的 ICU 版本。 🎉

关键经验教训

  1. AUR 包不会随系统库自动更新

    • 当 Arch 更新核心库(例如 ICU)时,官方包会自动重新构建。
    • AUR 包则不会;必须由用户或维护者手动重新构建。
    • Notepadqq 最后一次上游更新是在 2018 年,因此它从未针对 ICU 76、 77 或 78 进行重新构建,每次 ICU 更换都会导致该包破坏。
  2. 部分升级很危险

    • 即使系统经常更新,二进制不兼容仍可能残留在磁盘上。
    • 仅重启并不能解决 ABI 不匹配的问题。
  3. 滚动发行需要包的一致性

    • ICU 等库更新频繁;所有依赖这些库的包必须同步重新构建或更新。
    • 来自已移除仓库的孤立包可能会引发隐藏问题。
  4. ABI 兼容性很重要

    • 共享库名称中的版本号(libicui18n.so.76libicui18n.so.78)表明了 ABI 的破坏。
    • 将一个版本的符号链接到另一个版本是不安全的,可能导致崩溃或未定义行为。

分析 ABI 破坏

我是如何知道这不仅仅是缺少符号链接的问题?

  1. 库文件名中的版本

    libicui18n.so.76  vs  libicui18n.so.78
    • .76.78SONAME 主版本号
    • 不同的主版本号意味着有意的 ABI 不兼容。
  2. 链接错误中的带版本符号

    icu_76::Normalizer::normalize   ← 版本已嵌入符号名
    ucnv_open_76                   ← 函数名包含版本号
    • 库提供 icu_78:: 符号,但二进制文件需要 icu_76:: 符号。
    • 再多的符号链接也无法解决这种不匹配。
  3. 为什么符号链接会失败

    即使我们创建了符号链接:

    sudo ln -s libicui18n.so.78 libicui18n.so.76
    • 二进制文件可以加载,但它会尝试调用 icu_76:: 函数。
    • 库只提供 icu_78:: 函数。
    • 结果:立即崩溃或出现未定义行为。

依赖链层层深入

看似简单的 Notepadqq 问题实际上需要:

  • 诊断 ICU 版本不匹配。
  • 发现 qt5‑webengine 依赖。
  • 确认孤立的仓库软件包。
  • 重新构建整个依赖链。

什么 要做

❌ 创建符号链接

# DON'T DO THIS
sudo ln -s /usr/lib/libicui18n.so.78 /usr/lib/libicui18n.so.76

虽然这可能让程序启动,但它可能导致:

  • 运行时崩溃
  • 未定义行为
  • 数据损坏
  • 难以调试的问题

❌ 忽视更新错误

定期运行 pacman -Syu 是好的,但你还必须:

  • 检查孤立(未被依赖)的软件包:pacman -Qtdq
  • 在系统库更新后验证 AUR 软件包
  • 查看失败的事务日志

防止策略

1. 定期清理孤立软件包

pacman -Qtdq | pacman -Rns -

2. 监控 AUR 软件包构建失败

当系统库更新时,立即重新构建受影响的 AUR 软件包:

yay -S --rebuild

重要提示: 未维护的 AUR 软件包(例如 Notepadqq,最后更新于 2018 年)在系统库更新后始终需要手动重新构建。可考虑:

  • 寻找活跃维护的替代方案。
  • 自行维护该 AUR 软件包。
  • 使用捆绑了依赖的 AppImage/Flatpak 版本。

3. 使用二进制软件包替代方案

对于对稳定性要求极高的应用,考虑使用 AUR 中的 -bin 软件包,这类软件包会捆绑其依赖(代价是占用更多磁盘空间)。

4. 检查库依赖

在进行重大库更新后,确认没有缺失必需的库:

ldd /usr/bin/<binary> | grep "not found"

<binary> 替换为您想要检查的可执行文件。

结论

这个问题完美地展示了为什么 Arch Linux(及其衍生版)被视为 “高级” 发行版。滚动发布模型提供了最前沿的包,但也要求用户了解:

  • 共享库版本控制(ABI 兼容性)
  • 依赖链
  • 官方仓库与 AUR 之间的关系
  • 何时重新编译而不是重新安装包

解决方案并非快速修复,而是对依赖链进行系统性的诊断和重建。虽然当时令人沮丧,但此类问题能够加深对 Linux 系统底层工作原理的理解。

你在 Arch 上遇到过类似的依赖问题吗?
面对库版本不匹配时你会怎么处理?欢迎在评论中分享你的经验!

系统信息

  • 发行版: EndeavourOS(基于 Arch)
  • 包管理器: pacman + yay
  • 受影响的版本: ICU 76 → 78,Qt5WebEngine 5.15.19‑4
Back to Blog

相关文章

阅读更多 »