AOSC Wiki / 开发者 / 打包 / .
其他语言: English

软件包维护入门:进阶教程

本文由 Commit-O-Matic™ 强力驱动

所以您想、您渴望、您有勇气去打一个包,所以请开始打包,打出一个我们能用的包!

在学习了关于构建包的 基础 之后,我们现在可以开始探索一些高级技术了。

请注意,您不必逐字阅读本文档,因为这篇文档应该作为您未来工作的参考。您只需要快速浏览一下,记住这些概念,当您遇到问题时再回来查。

Autobuild3 中的高级操作

我们已经看到,对于许多包,Autobuild3 可以自动确定源代码树中使用的构建系统,然后相应地生成和执行构建脚本。但是有许多(复杂的或原始的)程序需要更多步骤来构建和安装,或者可能需要特定的构建参数和编译参数。

现在我们将介绍如何在 AOSC OS 的构建系统中处理这些问题。

手动选择不同的构建系统

有时 Autobuild3 可能对选择错误的构建系统,并可能会导致构建失败。比如当一个项目有多个构建系统可用时,Autobuild3 可能不会选择(对于构建时间或可靠性来说)最好的一个。

在这种情况下,我们可以通过在 autobuild/defines 文件中定义 ABTYPE= 来手动指定要使用的构建系统。

目前,支持这些构建类型:

自定义构建系统/编译器参数

Autobuild3 集成了一系列最佳构建参数。但是,有时这些参数与软件不完全兼容,可能会引起问题。在这种情况下,请查看 Autobuild3 的默认参数,并根据需要覆盖对应的参数。完整的参数列表可以在 Autobuil3 Wiki 中找到。

其中一个突出的问题是 LTO(链接时优化)。这种技术可以提高运行时的效率,并减小二进制文件的大小,但目前启用 LTO 可能导致构建失败(这种情况的数量在不断减少),并且在构建时消耗大量内存。Autobuild3 默认启用 LTO 以提高性能(有时也是为了减小二进制文件的大小)。但如果您遇到与 LTO 相关的问题,可以通过在 autobuild/defines 中添加 NOLTO=1 来禁用 LTO。

自定义构建脚本

在某些情况下,软件使用特殊的构建系统(或者根本不需要构建系统,如预构建的二进制文件)。在这种情况下,您可以通过使用 Bash 编写构建脚本来控制构建过程。

构建脚本位于 autobuild/build。如果存在该脚本,构建类型将被锁定为 self(除非通过定义了另一个 ABTYPE= 覆盖了构建类型),这意味着 Autobuild3 不会尝试确定构建系统并执行其集成的构建脚本,而是简单地执行这个脚本。

这个脚本应该看起来非常类似于手动编译程序的过程。但是有一个关键的区别:您 应该将编译后的程序安装到系统根目录。而是应该安装在 $PKGDIR 中,稍后 Autobuild3 将根据此目录中的文件创建 deb 包。例如,如果编译后的二进制文件在构建目录的根目录中称为 hugo,那么您应该将其安装到软件包的 bin 目录中,如下所示:

abinfo "Installing Hugo binary ..."
install -Dvm755 hugo \
    "$PKGDIR"/usr/bin/hugo

请注意,上述例子中的 abinfo() 用于在构建日志中输出状态信息,其工作方式类似于 echo。只需要在脚本中调用 abinfo "Desired build information",这段信息就会被记录到构建日志中。使用 abinfo() 对构建脚本进行注释是一个好习惯,因为这会帮助到对后来可能的维护者。另一个类似的函数是 abwarn(),这个函数用于输出警告。

构建后的调整

有时 Autobuild3 可以很好地处理构建过程,但最终产出的包可能需要一些额外的调整(例如:man 页面的目录不对,需要将 shell 自动补全脚本复制到 $PKGDIR 等)。在这种情况下,我们使用 autobuild/beyond 脚本。与 autobuild/build 类似,这个脚本作为纯 Bash 脚本在构建后执行。

这是一个来自 TREE/extra-web/aria2 的例子。这里我们需要安装 aria2c 的 bash 命令行补全支持文件,所以我们使用如下的 autobuild/beyond 脚本。

abinfo "Installing Bash completions ..."
install -Dvm644 "$PKGDIR"/usr/share/doc/aria2/bash_completion/aria2c \
    "$PKGDIR"/usr/share/bash-completion/completions/aria2c

autobuild/override 目录

有时源代码不包含(或包含不适当的版本)包所需的某些文件。在这种情况下,我们可以将文件放在 autobuild/override 目录中。请注意,文件需要放在与 $PKGDIR 中的文件结构对应的目录下。

例如,如果我们正在构建名为 foo 的包,这个包的源代码树中不包含桌面环境所需的 .desktop 文件,我们可以编写自己的 .desktop 文件,并将其放置在:

autobuild/overrides/usr/share/applications/foo.desktop

高级补丁管理

我们已经在 基础 部分讨论过,我们可以通过简单地将补丁放置在 autobuild/patches 目录中来对源代码打补丁。但有时为了使补丁生效,必须按照特定顺序应用补丁。

为了缓解这个问题,我们引入了 autobuild/patches/series 文件。这个文件包含补丁名称的有序列表(每行一个文件名)。如果存在这个文件,Autobuild3 将按照列表中指定的顺序应用补丁。

在某些情况下,补丁只有在 strip level(需要剥离的目录层级)为 1 时才能应用。下面是一个 strip level 为 1 的补丁的示例标题:

--- a/kernel/init.c
+++ a/kernel/init.c

但有时,源代码可能具有不同的 strip level,例如,这个补丁的 strip level 为 3:

--- dev/working/jelly/kernel/init.c
+++ dev/working/lion/kernel/init.c

在这种情况下,您需要使用 Bash 编写自己的 autobuild/patch 脚本,再手动在脚本中调用 patch 命令。

启用测试

Autobuild3 提供测试功能。

测试功能默认情况下是禁用的,可以在 autobuild/defines 文件中添加 NOTEST=no 来启用。

对于一些 ABTYPE,Autobuild3 提供了预定义的测试模板,并且可以自动匹配并使用。要禁用自动检测,可以使用 ABTEST_AUTO_DETECT=no

如果您的 ABTYPE 没有对应的预定义测试模板,您可以编写自己的 autobuild/check 脚本。例如:

make -C $BLDDIR -k check

处理软件包组

在维护软件包时,有时会遇到需要一堆软件包(例如 KDE 程序)一起更新和 / 或构建的情况。如果我们不得不手动修改版本号和校验和,那将会很令人沮丧。

因此,我们的维护者编写了一些自动化工具来简化这个过程。在这里,我们将尝试将 TREE/extra-gnome 中的所有软件包更新到最新版本。

自动更新版本号

为了监控软件包更新,我们使用 aosc-findupdate 工具(在 AOSC OS 中作为 aosc-findupdate 软件包提供),该工具从各种来源获取软件包更新信息,例如 Fedora 的 Anitya,GitHub、GitLab 或者从使用自定义正则表达式解析的 HTML 文件中提取。

接着,查看 git diff,您应该能够看到各种 VERREL 行上的一系列更改。

自动更新校验和

然而,仅仅修改了 VER 是不够的。尽管 VER 已经被修改,但是 CHKSUM= 后面的校验和仍然是旧 tarball 的校验和,由于与新 tarball 的校验和不匹配,ACBS 将拒绝处理新 tarball。

还有一些自动化这个过程的方法,但目前还没有标准脚本。但是至少有一名维护者使用以下方法:

cd TREE/
# 首先,生成一个临时组。
git --no-pager diff --name-only | grep spec | sed 's/\/spec//' > groups/gnome-changes
# 进入 Ciel 环境。
ciel shell
# 使用 ACBS 更新校验和。
acbs-build -gw groups/gnome-changes

完成这些步骤后,校验和就会是最新的了。

自动构建更新

然后,我们可以简单地尝试构建新的软件包:

# 将 $INSTANCE 替换为您的实例名称。
ciel build -i $INSTANCE groups/gnome-changes

自动提交更改

如果所有包都成功构建,我们就可以提交更改了。我们的 commit-o-matic 将实现这一点。只需下载脚本,将其放入您的 PATH,然后调用脚本就行了。

请注意,您必须在 git 日志中记录任何额外的修改。也就是说,在调用 commit-o-matic 之前,您应该首先从临时组中删除修改后的包,然后手动提交。

commit-o-matic groups/gnome-changes update

如果您想使用和通用的 update to ... 不同的 commit message,例如,当某些包被上游弃用而需要被删除时,您可以按照以下方式进行操作。

commit-o-matic groups/gnome-changes bump-rel 'drop, orphaned'

自动推送更改

最后,我们可以将构建的包推送到主存储库。

pushpkg LDAP_IDENTITY BRANCH

请注意,LDAP_IDENTITYBRANCH 被定义为我们的 社区仓库 上的用户和存储库。贡献者在由我们的基础设施工作组审核之后,会获得 LDAP 身份——我们将通过您对我们 ABBS 树的第一个 PR 与您联系。

Ciel 的高级技术

在使用 Ciel 时,有一些技巧可以让您的生活更轻松。

自动指定实例名称

您应该注意到了,您每次都必须在每个 ciel build 命令后附加 -i $INSTANCE 参数。为了节约时间,您可以这么做:首先,在 Ciel 工作区根目录中创建名为 .env 的文件,然后在该文件中输入以下内容。

# Replace $INSTANCE name with your own.
CIEL_INST=$INSTANCE

保存文件,您现在可以在没有 -i 参数的情况下构建包。

ciel build gnome-shell

在任何目录下使用 Ciel

当您的 Ciel 版本 >= 3.0.6 时,您可以像使用 Git 一样使用 Ciel——Ciel 会尝试在目录树上向上查找并找到工作区的根目录。所以,无需切换到根目录就可以运行任何 Ciel 命令,比如说,您不必离开 TREE/ 目录,这是很方便的。