前言
Arch Linux主要使用devtools来构建软件包。为了方便拥有x86_64设备的开发者构建LoongArch的软件包,笔者制作了一个devtools-loong64
的AUR软件包,可以在龙芯或者x86_64设备上构建LoongArch的软件包。
- 事实上不只是x86_64设备,任何能够运行Arch Linux及其移植的设备都可以使用
devtools-loong64
构建LoongArch的软件包
特点
相比于原来的devtools
龙芯移植,devtools-loong64
保留了Arch Linux官方原版的devtools
作为依赖,通过patch的方式增加了部分LoongArch专属的文件,简化了维护的潜在工作量。
在x86_64平台上,devtools-loong64
还依赖qemu-user-static
软件包,以便在x86_64平台上使用QEMU用户模式模拟LoongArch的环境。通过在binfmt_misc的注册中额外添加C
标志,devtools-loong64
可以在x86_64平台上构建LoongArch的软件包,并避免了QEMU binfmt下的提权问题。
准备工作
文件系统
使用devtools构建软件包在每次构建时都会创建一个干净的chroot环境,该工具对Btrfs的快照进行了适配,创建新的chroot环境时会使用Btrfs的快照功能快速根据存放基本chroot环境的子卷创建新的chroot环境。因此,建议使用Btrfs文件系统。
PGP Key的导入
由于目前的Loong Arch Linux移植签名所用的PGP密钥并不在Arch Linux的archlinux-keyring
密钥环中,因此需要导入签名密钥。
目前笔者打包了北京大学Linux俱乐部Arch Linux用户组的密钥环archlinux-lcpu-keyring
。可以从AUR中安装:
paru -S archlinux-lcpu-keyring
安装devtools-loong64
从AUR中安装devtools-loong64
软件包:
paru -S devtools-loong64
binfmt_misc
FLAGS说明(仅针对在容器中运行x86 Arch Linux的用户)
- 只要不是在容器中运行x86 Arch Linux的用户,
devtools-loong64
完全开箱即用,可以忽略这一部分,请继续阅读测试打包一节 - 更多知识介绍见笔者的另一篇博客:
binfmt_misc
flags与QEMU用户模式下的跨架构构建环境 - 无论如何宿主都需要安装
qemu-user-static
软件包
笔者打包的devtools-loong64
软件包在x86平台上使用QEMU用户模式模拟LoongArch的环境,笔者附加了z-qemu-loong64-static-for-archpkg.conf
这一文件,该文件在/usr/lib/binfmt.d/
下,特意以z
开头以便最后注册qemu-loong64-static
的binfmt_misc规则,附加了C
标志,以避免QEMU binfmt下的提权问题。
需要注意的是,该软件包添加这一文件是假设用户的宿主环境是直接运行于x86(物理机或完整的虚拟机)上的Arch Linux系统,必须要有独立的内核。因为z-qemu-loong64-static-for-archpkg.conf
这一文件涉及对内核的binfmt_misc
的注册。
因此对于将打包所用到的x86的Arch Linux环境运行在systemd-nspawn
等容器中的用户(其他发行版用户想进行测试时可能有这一需求),如果将devtools-loong64
安装在了容器内而非宿主上,这一注册并不能够自动进行。在这种情况下,用户可以在以下方法中选择一种执行。
在宿主系统QEMU的binfmt注册文件中添加C
标志
- 注册文件一般在
/usr/lib/binfmt.d/
下,binfmt的注册一般由systemd-binfmt.service
负责 - 注册文件一般为
/usr/lib/binfmt.d/qemu-loongarch64-static.conf
,不同发行版可能有所不同
例如,原本的注册文件内容为:
:qemu-loongarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02\x01:\xff\xff\xff\xff\xff\xff\xff\xfc\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-loongarch64-static:FP
添加C
标志到末尾后为:
:qemu-loongarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02\x01:\xff\xff\xff\xff\xff\xff\xff\xfc\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-loongarch64-static:FPC
临时手动在宿主环境下注册binfmt规则
手动注册binfmt规则的方法可以仅在需要时启用binfmt的调用者的凭证,不需要时默认禁用,运行完成后也可以手动禁用,理论上可能会更加安全。
假设宿主存在注册文件,为/usr/lib/binfmt.d/qemu-loongarch64-static.conf
,执行命令:
echo -1 | sudo tee /proc/sys/fs/binfmt_misc/qemu-loongarch64 && echo "$(cat /usr/lib/binfmt.d/qemu-loongarch64-static.conf)C" | sudo tee /proc/sys/fs/binfmt_misc/register
以便重新注册qemu-loongarch64
的binfmt规则,并添加C
标志。
同理,如果想恢复原状,禁用C
标志,可以执行:
echo -1 | sudo tee /proc/sys/fs/binfmt_misc/qemu-loongarch64 && cat "/usr/lib/binfmt.d/qemu-loongarch64-static.conf" | sudo tee /proc/sys/fs/binfmt_misc/register
如果宿主仅安装了qemu-user-static
软件包,却没有安装qemu-user-static-binfmt
软件包,可能不存在/usr/lib/binfmt.d/qemu-loongarch64-static.conf
这一文件,此时需要指定完整的注册规则,例如:
echo -1 | sudo tee /proc/sys/fs/binfmt_misc/qemu-loongarch64 && echo ":qemu-loongarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02\x01:\xff\xff\xff\xff\xff\xff\xff\xfc\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-loongarch64-static:FPC" | sudo tee /proc/sys/fs/binfmt_misc/register
- 为了方便,可以自行编写脚本,以便实现在启动容器时自动注册binfmt规则
测试binfmt_misc
注册结果
执行以下命令,观察输出中flags
的内容是否含有C
标志:
cat /proc/sys/fs/binfmt_misc/qemu-loongarch64
如果输出中含有flags: POCF
,则表明目前已经启用了C
标志;如果仅含有flags: PF
,则表明目前没有启用C
标志,后续的构建过程将会出现提权问题:
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?
==> ERROR: 'pacman' failed to install missing dependencies.
这一报错极具迷惑性,实际上如果binfmt_misc
的标志没有设置正确,无论文件系统、挂载参数如何都会提示这一错误。如果在实际构建过程中出现了如上问题,可以通过本节内容中的方法解决。
测试打包
PKGBUILD的获取
目前(自2024.12.17)devtools-loong64 >= 1.3.0.patch3-1
已集成获取软件包的工具get-loong64-pkg
,可以直接使用,详细使用方法可以运行get-loong64-pkg -h
查看。该工具可以自动从Arch Linux官方仓库拉取构建文件,自动同步更新,切换到相应的版本,并自动应用我们的补丁集中维护的补丁。需要注意的是,传递的参数是软件包的pkgbase
,而不是pkgname
。
get-loong64-pkg <package>
首次运行
首先,进入软件包的目录,然后进行构建:
extra-loong64-build
首次运行时,程序会在/var/lib/archbuild/
下创建目录extra-loong64
,如果是Btrfs文件系统,会在extra-loong64
下创建一个名为root
的子卷,用于存放LoongArch Linux的基本chroot环境,在后续每次运行构建时,将会对这一子卷中的环境进行升级同步,并创建一个新的快照子卷进行构建。(其他文件系统则是创建普通目录、复制目录)
此时如果在同步数据库阶段就提示PGP签名错误,可能是因为没有导入PGP密钥,请自行按照上文PGP签名的导入一节进行检查。如果仅有下载的部分软件包提示签名校验失败,可能是网络问题,重试即可。首次运行无论是否失败,均会在/var/lib/archbuild/extra-loong64
下创建一个名为root
的子卷,如果创建并没有成功,在重试时会提示该路径并非Arch Linux的chroot环境,此时请运行extra-loong64-build -c
清理环境,或者手动删除/var/lib/archbuild/extra-loong64
下的所有子卷以及/var/lib/archbuild/extra-loong64
目录本身,然后再次运行。
当基本的chroot环境创建成功后,后续的构建均无需从头创建环境,应该能够顺利进行。
其他注意事项
构建期间的PGP签名问题
许多软件包在PKGBUILD中会指明需要验证PGP签名,如果在构建时没有导入相应的PGP密钥,会导致构建失败。这一问题较为复杂,目前有以下几种解决方案:
- 在宿主机的
~/.gnupg/gpg.conf
中添加auto-key-retrieve
选项,这样在构建时会自动从密钥服务器下载PGP密钥。- 缺点是某一特定的PGP服务器上可能没有相应的密钥
- 可以考虑多添加几个PGP服务器
- 一般来说,软件包的PGP密钥会在软件包
keys
子目录下提供,可以在构建前从keys
中导入密钥- 缺点是
keys
下的密钥一般是devtools
的export-pkgbuild-keys
自动导出的,可能会有一些问题
- 缺点是
- 考虑到Arch Linux官方上游会对软件包的PGP密钥进行验证,而在我们的构建环境中使用hash验证已经可以基本保证源的完整性与可靠性,因此我们可以考虑在构建流程中跳过PGP验证
extra-loong64-build
参数组中在--
后的参数会传递给makechrootpkg
,而makechrootpkg
参数组中在--
后的参数会传递给makepkg
- 因此使用
extra-loong64-build -- -- --skippgpcheck
可以跳过PGP验证
QEMU的性能问题
在QEMU适配龙芯的LSX指令集后,QEMU的性能似乎出现了严重下降(适配了LSX指令集的QEMU 9.0似乎性能比没有适配LSX的QEMU 8.0差):
运行环境1 | 7z Compression/MIPS | 7z Decompression/MIPS |
---|---|---|
x86原生 | 47307 (100%) | 57979 (100%) |
QEMU 8.0.0, 2023.05 | 16295 (34%) | 21927 (38%) |
QEMU 9.0.2, 2024.08 | 10699 (23%) | 12492 (22%) |
Longsoon 3A6000 | 19295 (41%) | 19295 (33%) |
考虑到当前QEMU下16线程的多核性能都明显不如龙芯3A6000,单线程性能更是远远落后,因此在构建时可能会出现性能瓶颈,导致打包耗时较长。
维护参与
欢迎大家参与北京大学Linux俱乐部的Loong Arch Linux移植工作!
-
x86原生及QEMU测试所用的CPU为AMD Ryzen 7 5800H (16) @ 4.46 GHz,所用的软件为
p7zip
,测试命令为7z b
,表中列出的是多线程性能。 ↩