Skip to content

龙芯的Arch Linux移植工作流程 ‐ Loong Arch Linux软件包开发者维护工具设计

wszqkzqk edited this page Jan 10, 2025 · 5 revisions

作者:wszqkzqk

本文将介绍目前LoongArch的Arch Linux移植的最小维护架构(不包括CI工具)和参与北京大学Linux俱乐部的Arch Linux龙芯移植工作的方式。

前言

Loong Arch Linux是Arch Linux的龙芯移植版本,目前龙芯Linux社区较普遍地认为,为龙芯Linux生态圈维护一个滚动更新的Arch Linux发行版具有重要意义,目前北京大学Linux俱乐部已经接手维护。

由于社区维护力量较为有限,Loong Arch Linux将会尽可能地实现上游化,来减少维护工作量。

预备工作

基本条件

本文默认读者至少已经满足以下条件中的一个(建议读者预先大致阅读笔者的另一篇博客在x86设备上跨架构构建LoongArch的Arch Linux软件包):

  1. 拥有原生龙芯编译机器,或者可以运行LoongArch的QEMU System虚拟机
  2. 拥有任意架构的64位设备且可以在设备上运行对应架构支持的Arch Linux操作系统或者容器
  • 例如x86_64的官方Arch Linux、x86_64的其他Linux发行版中的Arch Linux容器、WSL2中的Arch Linux等
  • 例如aarch64的Arch Linux ARM、aarch64的其他Linux发行版中的Arch Linux ARM容器等

如果对本文中涉及的某些基本概念不熟悉,可以参考ArchWiki

环境准备

文件系统

使用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,可以通过以下方式安装:

git clone https://github.com/lcpu-club/archlinux-lcpu-keyring.git
cd archlinux-lcpu-keyring
makepkg -si

笔者已经打包了devtools-loong64工具,并上传到了AUR,可以直接从AUR中安装:

paru -S devtools-loong64

对于在容器中运行x86_64 Arch Linux的用户,还需要参考笔者在另一篇博客中的binfmt_misc FLAGS说明一节进行设置。其他用户可以忽略。

维护仓库

我们的补丁维护仓库位于GitHub lcpu-club/loongarch-packages下,每个需要额外patch的软件包都有一个对应于包名的目录。该目录仅用于存放patch或龙芯特有的配置文件,不直接存放PKGBUILD或上游软件源代码文件

  • loong.patch是主要针对PKGBUILD的patch文件
    • 也可能包含其他Arch Linux官方软件包仓库git跟踪的文件
      • 不推荐
      • 如果直接修改非PKGBUILD的git跟踪文件将必然需要修改PKGBUILD的checksum数组
        • 上游更新后容易在loong.patch应用时带来冲突
      • 建议额外维护一个对应的.diff文件,在PKGBUILD中应用
  • 其他文件则可能是针对软件包的其他patch文件或者特别适用于龙芯的的配置文件,须添加在PKGBUILDsource数组中
  • 目前(自2024.12.17)devtools-loong64 >= 1.3.0.patch3-1已集成补丁导出工具export-loong64-patches。以上内容,包括loong.patch和其他补丁,均应当由export-loong64-patches自动导出。

特殊情况

  • 本部分是为了简化维护而特别设计的,如果初学者不理解这部分内容,可以跳过,几篇文档都看完以后会理解的()

部分软件包由于补丁内容非常一致、简单,而且有大量的软件包系统性地需要这些补丁,在这种时候,我们为了简洁与维护方便,并没有创建这些软件包的补丁维护目录。目前的这样特殊情况主要分为两种:

  • 特殊情况1:config.subconfig.guess
    • 开发不活跃的软件config.subconfig.guess过旧,需要更新才能在龙芯平台上正常构建
    • 需要更新config.subconfig.guess不用其他任何修改就能成功构建
  • 特殊情况2:使用cargo fetch的软件包的架构指定问题
    • cargo fetchPKGBUILD中使用了硬编码的x86_64,需要替换为uname -mloongarch64
    • cargo fetchPKGBUILD中使用了$CARCH(在本发行版是loong64),需要替换为uname -mloongarch64
  • 对于这些特殊情况,我们的包拉取工具get-loong64-pkgdevtools-loong64 >= 1.3.0.patch3-1)会自动处理,因此不需要单独维护补丁

补丁维护原则

本项目始终以上游化为目标,因此我们的软件包构建过程中,尽量不对软件包进行patch;对于共性问题,应当视具体情况提交到软件上游或者Arch Linux上游。但是,由于龙芯平台的特殊性,有些软件包可能不可避免地需要patch才能在龙芯平台上正常运行,而上游可能并不能够及时接收这些修复,此时我们不得不在我们的补丁维护仓库暂时维护patch。

因此对这两种特殊情况:

  • 特殊情况1:如果没有对应的补丁,但软件包名在update_config文件中,需要对PKGBUILD进行修改
    • 需要对config.subconfig.guess进行更新
  • 特殊情况2:如果没有对应的补丁,但软件包使用cargo fetch,需要将$CARCH替换为uname -m,并且将
    • 硬编码的x86_64也要替换为uname -m

工作流程

构建及测试流程示例

我们以erofs-utils软件包为例,展示如何构建和测试软件包。

获取软件包

目前(自2024.12.17)devtools-loong64 >= 1.3.0.patch3-1已集成获取软件包的工具get-loong64-pkg,可以直接使用,详细使用方法可以运行get-loong64-pkg -h查看。该工具可以自动从Arch Linux官方仓库拉取构建文件,自动同步更新切换到相应的版本,并自动应用我们的补丁集中维护的补丁。需要注意的是,传递的参数是pkgbase,而不是pkgname

get-loong64-pkg erofs-utils

软件包PGP签名的导入与验证

许多软件包在PKGBUILD中会指明需要验证PGP签名,如果在构建时没有导入相应的PGP密钥,会导致构建失败。目前有以下几种解决方案:

  1. 宿主机~/.gnupg/gpg.conf中添加auto-key-retrieve选项,这样在构建时会自动从密钥服务器下载PGP密钥。
    • 缺点是PGP服务器上可能没有相应的密钥
  2. 一般来说,软件包的PGP密钥会在软件包keys子目录下提供,可以在构建前从keys中导入密钥
    • 缺点是keys下的密钥一般是devtoolsexport-pkgbuild-keys自动导出的,可能会有一些问题
  3. 考虑到Arch Linux官方上游会对软件包的PGP密钥进行验证,而在我们的构建环境中使用hash验证已经可以基本保证源的完整性与可靠性,因此我们可以考虑在构建流程中跳过PGP验证
    • extra-loong64-build参数组中在--后的参数会传递给makechrootpkg,而makechrootpkg参数组中在--后的参数会传递给makepkg
    • 因此使用extra-loong64-build -- -- --skippgpcheck可以跳过PGP验证

其中,1、2两种方法可结合使用。

构建尝试

切换到克隆下来的示例软件包目录:

cd erofs-utils

一般来说,软件包的构建命令是extra-loong64-build。由于原软件包PKGBUILD是针对x86_64的,其arch数组并不包含loong64,未经修改并不能够直接用无参数的extra-loong64-build构建。虽然说修改arch数组也可以算是需要针对PKGBUILD的patch,但是我们默认在我们的移植中,所有arch字段不为any的软件包的arch字段都应该包含loong64,因此对arch的修改不应当出现在维护的patch中。

对此,我们可以有两种选择,一种是先修改PKGBUILD,将loong64添加到arch数组中,然后再使用extra-loong64-build构建(如果需要导出补丁则需要改回来,不推荐)。

为了避免麻烦,我们推荐向extra-loong64-build传递参数来解决问题:

  • extra-loong64-build参数组中在--后的参数会传递给makechrootpkg,而makechrootpkg参数组中在--后的参数会传递给makepkg
  • makepkg-A参数表示忽略arch字段不兼容的情况以便继续构建

因此,我们推荐使用以下命令构建:

extra-loong64-build -- -- -A
  • 如果需要core-testingextra-testing中的包,请使用extra-testing-loong64-build
  • 如果需要core-stagingextra-staging中的包,请使用extra-staging-loong64-build
    • 目前(2024.09.05)我们的工作进度仍存放于testingstaging
    • 如果要针对最新的维护状况构建,请使用**extra-testing-loong64-build**或者extra-staging-loong64-build
    • 目前我们只跟进Arch Linux官方的coreextra仓库,因此一般只使用extra-loong64-build

如果想要保留对构建时间的记录,以及更加完整的构建日志,可以使用script命令:

script -c "time extra-loong64-build -- -- -A" build-log-all.log

首次构建可能问题

首次运行时,程序会在/var/lib/archbuild/下创建目录extra-loong64,如果是Btrfs文件系统,会在extra-loong64下创建一个名为root的子卷,用于存放LoongArch Linux的基本chroot环境,在后续每次运行构建时,将会对这一子卷中的环境进行升级同步,并创建一个新的快照子卷进行构建。(其他文件系统则是创建普通目录、复制目录)

此时如果在同步数据库阶段就提示PGP签名错误,可能是因为没有导入PGP密钥,请自行检查软件包archlinux-lcpu-keyring是否正常安装。如果仅有下载的部分软件包提示签名校验失败,可能是网络问题,重试即可。首次运行无论是否失败,均会在/var/lib/archbuild/extra-loong64下创建一个名为root的子卷,如果创建并没有成功,在重试时会提示该路径并非Arch Linux的chroot环境,此时请运行extra-loong64-build -c清理环境,然后再次运行。

构建成功后

构建成功后,在原构建仓库目录下会生成*.pkg.tar.zst软件包文件,即为构建成功的软件包;*.log为各项构建过程的日志。更详细的编译日志则是在/var/lib/archbuild/extra-loong64/$USER/build/下。

如果读者是北京大学Linux俱乐部Arch Linux用户组的成员且在archlinux-lcpu-keyring中有签名密钥,可以手动对软件包进行签名:

for file in *.pkg.tar.zst
do
  gpg --detach-sign --use-agent "$file"
done

软件包的测试可以使用龙芯物理机、qemu-system-loongarch64虚拟机、使用QEMU User Mode Emulation的龙芯容器等方式进行,具体方法不再赘述。

patch导出流程

之前列出的软件包erofs-utils较为简单,不需要额外修复就能直接构建,然而仍然存在大量的软件包需要开发者进行一些修复适配(修复遇到困难可以查看笔者提供的软件包修复构建的相关指引)。

对于需要patch适配的软件包,开发者在适配完成并进行构建和验证后,需要将适配的patch导出,添加到我们的补丁维护仓库中。

导出的内容包括针对PKGBUILD的patch和软件包的其他patch或特别适用于龙芯的配置文件。除了loong.patch外,其他需要用到的patch文件或者其他配置应当注意添加到PKGBUILD中的source数组中,并且更新好PKGBUILD中的哈希值,具体操作可以参考ArchWiki的PKGBUILD条目

此外其他文件应当尽可能地命名得更具体,以便于其他开发者理解。

目前(自2024.12.17)devtools-loong64 >= 1.3.0.patch3-1已集成补丁导出工具export-loong64-patches,可以直接使用,详细使用方法可以运行export-loong64-patches -h查看。该工具可以自动导出软件包的patch,不需要手动导出。运行以下命令,可以将补丁导出到loong64-patches目录下:

export-loong64-patches

这个脚本的逻辑是:

  1. 将软件包目录下git diff的结果写入loong.patch
  • 即对上游git仓库已跟踪文件的修改,一般为PKGBUILD的修改
  1. 查找需要复制的其他文件
  • 需要复制的文件一定在PKGUILDsource数组中
  • 需要复制的文件一定在本地存在
  • 需要复制的文件一定不在Arch Linux官方软件包git仓库的跟踪文件中
  • 同时满足以上三个条件的文件一定需要复制,为充要条件
  1. PKGBUILDpkgrel字段的小版本号进行忽略
  • pkgrel字段的小版本号是我们在维护时用于版本控制的,不应当导出到patch中
  • patch中不能包含对pkgverpkgrel的修改

对于导出的补丁,需要注意补丁维护原则中列出的特殊情况:

  • 如果patch文件仅包含config.subconfig.guess的更新,不需要额外维护loong.patch,而是将包名添加到update_config文件中
    • 有关添加到update_config文件后的自动处理流程是否能够解决问题,可以预先使用以下命令验证:
      sed -i '/^build()/,/configure/ {/^[[:space:]]*cd[[:space:]]\+/ { s/$/\n  for c_s in $(find -type f -name config.sub -o -name configure.sub); do cp -f \/usr\/share\/automake-1.1?\/config.sub "$c_s"; done\n  for c_g in $(find -type f -name config.guess -o -name configure.guess); do cp -f \/usr\/share\/automake-1.1?\/config.guess "$c_g"; done/; t;};}' "PKGBUILD"
      • 如果能够解决问题,就不要单独维护loong.patch

软件包的手动上传

参见龙芯Arch Linux移植技巧 #软件包的手动上传一节

更多阅读材料