Arch 软件包指南
在为 Arch Linux 构建软件包时,请遵守下方的软件包准则,尤其是当您打算向 Arch Linux 贡献新软件包时。您还应查阅 PKGBUILD(5) 和 makepkg(8) 手册页。
本页面列出的重要点不会在其他软件包准则页面中重复。这些特定准则旨在作为下方所列标准的补充。
有关 PKGBUILD 示例,请查看 /usr/share/pacman/ 目录中的 .proto 文件。
软件包礼仪
- 软件包绝不应安装到
/usr/local/。
- 不要在
PKGBUILD构建脚本中引入新的变量或函数,除非不这样做就无法构建软件包,因为这些变量或函数可能会与 makepkg 自身使用的变量和函数冲突。
- 如果必须使用新的变量或函数,请在其名称前加上下划线 (
_),例如。_customvariable=
- 避免将
/usr/libexec/用于任何用途。请改用/usr/lib/$pkgname/。
- 软件包构建者可以通过修改
/etc/makepkg.conf文件中的相应选项,或者通过创建~/.makepkg.conf来覆盖该选项,从而自定义软件包元文件中的packager字段。
- 不要使用 makepkg 子程序(如
error,msg,msg2,plain,warning),因为它们随时可能发生变化。要打印数据,请使用printf或echo。
- 所有重要信息都应在安装过程中使用 .install 文件通过 echo 输出。例如,如果软件包需要额外的设置才能正常工作,则应包含相关说明。
- 依赖项是最常见的打包错误。请花时间仔细核对,例如通过对动态可执行文件运行 ldd(1)、
ldd --unused --function-relocs和 readelf(1) § dynamic,检查脚本所需的工具,或查阅软件文档。namcap 工具可以为您提供帮助。该工具可以分析PKGBUILD文件和生成的软件包压缩包,并就权限错误、缺失依赖、多余依赖以及其他常见错误发出警告。
- 任何运行软件包或使其基本功能正常工作所不需要的可选依赖项,不应包含在 depends 数组中;相关信息应添加到 optdepends 数组中。
optdepends=('cups: printing support' 'sane: scanners support' 'libgphoto2: digital cameras support' 'alsa-lib: sound support' 'giflib: GIF images support' 'libjpeg: JPEG images support' 'libpng: PNG images support')- 上面的例子摘自 wine 软件包。optdepends 信息会在安装/升级时自动打印出来,因此不应将此类信息保留在
.install文件中。
- 在为软件包编写软件包描述时,请勿以自指的方式包含软件包名称。例如,“Nedit is a text editor for X11”可以简化为“A text editor for X11”。此外,尽量将描述限制在 80 个字符左右或更少。
- 尽量将
PKGBUILD文件中的行长度保持在 100 个字符以下。
- 在可能的情况下,移除
PKGBUILD中的空行(例如provides,replaces等字段之间)。
- 通常的做法是保持
PKGBUILD字段的顺序与 PKGBUILD 文章中给出的顺序一致。但这并非强制要求,此上下文中唯一的要求是正确的 Bash 语法。
- 引用可能包含空格的变量,例如
"$pkgdir"和"$srcdir"。
- 为确保软件包的完整性,请确保完整性变量包含正确的值。可以使用 updpkgsums(8) 工具更新这些值。
包命名
- 软件包名称只能包含字母数字字符以及
@、.、_、+、-。名称不得以连字符或点开头。所有字母均应为小写。 - 软件包名称不应附加前缀上游主版本号(例如,如果上游称其为 libfoo v2.3.4,我们不需要 libfoo2),前提是该库及其依赖项能够随着每次上游发布而使用最新的库版本。然而,对于某些软件或依赖项,不能做此假设。过去,这种情况对于 GTK 和 Qt 等小部件工具包尤为突出。依赖此类工具包的软件通常无法轻松迁移到新的主版本。因此,在软件无法轻松随其依赖项滚动升级的情况下,软件包名称应带有主版本后缀(例如 gtk2, gtk3, qt4, qt5)。对于大多数依赖项可以随最新版本滚动,但少数不能(例如需要 libpng12 的闭源软件)的情况,该软件包的过时版本可以称为 libfoo1,而当前版本仅称为 libfoo。
软件包版本控制
- 软件包版本 —
pkgver— 应与作者发布的版本一致。 - 如有必要,版本可以包含字母,例如版本可以是
2.54BETA32。 - 版本标签不得包含连字符,并且只能包含字母、数字和点。如果上游版本包含连字符,则必须将其替换为下划线。
- 软件包发布号 —
pkgrel— 是 Arch Linux 软件包所特有的。这允许用户区分较新和较旧的软件包构建。当新软件包版本首次发布时,发布计数从 1 开始。随着修复和优化的进行,软件包将重新发布给 Arch Linux 公众,发布号将递增。 - 当新版本发布时,发布计数重置为 1。
- 软件包发布标签遵循与版本标签相同的命名限制。
软件包依赖
- 在任何 PKGBUILD 依赖项中不要依赖传递依赖,因为如果其中一个依赖项更新,它们可能会损坏。
- 列出所有直接库依赖项。要识别它们,可以使用 find-libdeps(1)(属于 devtools)。
软件包关系
- 不要将
$pkgname添加到 PKGBUILD#provides,因为它总是被软件包隐式提供。 - 不要将
$pkgname添加到 PKGBUILD#conflicts,因为软件包不能与自身冲突。 - 在 PKGBUILD#provides 中列出软件包的所有外部共享库(例如
'libsomething.so')。要识别它们,可以使用 find-libprovides(1)(属于 devtools)。
软件包源
- 尽可能使用 HTTPS 源(tarball 使用
https://,git 源使用git+https://)。 - 尽可能使用 PGP 签名验证源(如果上游对提交和标签进行签名但不签署 tarball,这可能意味着需要从 git 标签构建而不是从源码 tarball 构建)。
- 从 git 标签构建时,使用通过
git rev-parse获取的对象哈希,而不是标签名称。
_tag=1234567890123456789012345678901234567890 # git rev-parse "v$pkgver" source=(git+https://$url.git?signed#tag=$_tag) pkgver() { cd "$pkgname" git describe }- 此方法的示例可以在 gitea 软件包中找到。这样做是为了防止强制推送标签改变其指向的提交,从而改变已构建的软件包。使用标签对象哈希可确保源的完整性,因为强制推送标签会更改其哈希值。使用
pkgver()函数可以防止在不更新_tag的情况下意外提升pkgver。有关 VCS 源格式的更多信息,请参见 VCS 软件包准则#VCS 源。
- 不要削弱软件包的安全性或有效性(例如通过删除校验和检查或删除 PGP 签名验证),仅仅因为上游版本损坏或突然缺少某个功能(例如新版本缺少 PGP 签名)。
- 源文件在
srcdir中必须唯一(这可能需要在下载时重命名它们,例如"${pkgname}-${pkgver}.tar.gz::https://${pkgname}.tld/download/${pkgver}.tar.gz")。 - 避免使用特定的镜像站(例如在 sourceforge 上)进行下载,因为它们可能会变得不可用。
- 由 SSH 密钥签名的 Git 对象(例如标签、提交等)可以使用 git 命令进行验证,并将
gpg.ssh.allowedSignersFile指向指定可能签名密钥的文件。参见 [2] 获取示例。
与上游协作
尽可能与上游密切合作被认为是最佳实践。这包括报告有关构建和测试软件包的问题。
- 立即向项目上游报告问题。
- 尽可能使用上游补丁。
- 在 PKGBUILD 中添加带有相关(上游)缺陷追踪器工单链接的注释(这非常重要,因为它确保其他打包者能够理解变更并协同处理软件包)。
建议使用 nvchecker、nvrsAUR 或 urlwatch 等工具跟踪上游,以便获知新的稳定版本。
目录
- 配置文件应放置在
/etc目录中。如果存在多个配置文件,习惯上使用子目录以保持/etc区域尽可能整洁。使用/etc/pkg,其中pkg是软件包名称(或合适的替代名称,例如 apache 使用/etc/httpd/)。 - 软件包文件应遵循以下通用目录准则
/etc系统必要配置文件 /usr/bin二进制文件 /usr/lib库 /usr/include头文件 /usr/lib/pkg模块、插件等 /usr/share/doc/pkg应用程序文档 /usr/share/infoGNU Info 系统文件 /usr/share/licenses/pkg应用程序许可证 /usr/share/man手册页 /usr/share/pkg应用程序数据 /var/lib/pkg持久应用程序存储 /etc/pkgpkg 的配置文件 /opt/pkg大型自包含软件包
- 软件包不应包含以下任何目录
/bin/sbin/dev/home/srv/media/mnt/proc/root/selinux/sys/tmp/var/tmp/run
Makepkg 的职责
当使用 makepkg 构建软件包时,它会自动执行以下操作
- 检查是否安装了软件包依赖项和 makedepends
- 从服务器下载源文件
- 检查源文件的完整性
- 解压源文件
- 执行任何必要的补丁操作
- 构建软件并将其安装在伪根(fakeroot)目录中
- 从二进制文件中剥离符号
- 从库文件中剥离调试符号
- 压缩手册和/或信息页面
- 生成包含在每个软件包中的软件包元文件
- 将伪根目录压缩为软件包文件
- 将软件包文件存储在配置的目标目录中(即默认的当前工作目录)
架构
如果编译后的软件包是架构相关的,arch 数组应包含 'x86_64'。否则,对于架构无关的软件包,使用 'any'。
许可证
关于 Arch 软件包的许可证有两种类型
PKGBUILD 的许可证字段
PKGBUILD 的 license 字段。它列出了打包软件的上游许可证。它不是软件包源的许可证。该字段中的许可证必须采用 SPDX 许可证格式。更多详细信息,请参见 PKGBUILD#license。
软件包源许可证
软件包源本身的许可证。在 RFC40 中,Arch Linux 规定软件包源应授权为 BSD Zero Clause License (0BSD),并由 RFC52 规定应使用 REUSE 来执行此操作。
归结起来如下:
- 在源根目录下拥有一个
LICENSE文件,内容完全为 此内容。这是 Arch Linux 用于软件包的0BSD许可证。 - 在源根目录下拥有一个
REUSE.toml。您可以使用pkgctl license setup生成合理的配置以开始使用。 - 确保运行
pkgctl license check并且它返回零错误。
如果您有需要授权的额外文件,则需要为它们选择合理的许可证。这通常非常简单:
- 如果相关文件(例如启动脚本
launcher.sh或 systemd 服务文件myunit.service)完全由您或其他 Arch 员工创建,请将其授权为0BSD。注意:如果您编写了补丁并希望将其提交给上游,您仍然可以为 Arch 将其授权为0BSD,并在提交时允许上游应用其许可证。 - 如果文件取自上游(例如图标
tool.png或补丁fix.patch),则应携带上游许可证。
另请参阅介绍 pkgctl-license(1) 的 Arch Linux 开发博客文章。
可复现构建
Arch 正在努力使所有软件包都实现可复现构建。打包者可以使用 devtools 中的 makerepropkg 或 archlinux-repro 中的 repro 来检查软件包是否可复现。
$ makerepropkg $pkgname-1-1-any.pkg.tar.zst
或者:
$ repro -f $pkgname-1-1-any.pkg.tar.zst
如果构建时需要时间戳,请使用环境变量 SOURCE_DATE_EPOCH。其格式在上游文档中有详细说明。