Arch 软件包准则
32 位 – CLR – CMake – 交叉编译 – DKMS – Eclipse – Electron – 字体 – Free Pascal – GNOME – Go – Haskell – Java – KDE – 内核模块 – Lisp – Meson – MinGW – Node.js – 非自由软件 – OCaml – Perl – PHP – Python – R – Ruby – Rust - 安全 – Shell – VCS – Web – Wine
当为 Arch Linux 构建软件包时,请遵守以下软件包准则,特别是当您打算向 Arch Linux 贡献新软件包时。您还应该查看 PKGBUILD(5) 和 makepkg(8) man 手册页。
本页列出的要点不会在其他软件包准则页面上重复。这些特定准则旨在作为对以下列出的标准的补充。
提交到 Arch 用户仓库 的软件包还必须遵守 AUR 提交准则。
请参阅 /usr/share/pacman/
目录 中的 .proto 文件,作为 PKGBUILD
的示例。
软件包礼仪
- 软件包绝不应该安装到
/usr/local/
。
- 不要在
PKGBUILD
构建脚本中引入新的变量或函数,除非不这样做就无法构建软件包,因为这些变量和函数可能会与 makepkg 本身使用的变量和函数冲突。
- 如果绝对需要新的变量或新的函数,请在其名称前加上下划线 (
_
),例如:_customvariable=
- 避免对任何事物使用
/usr/libexec/
。请改用/usr/lib/$pkgname/
。
- 软件包构建者可以通过修改
/etc/makepkg.conf
文件中的相应选项来自定义软件包元文件中的packager
字段,或者通过创建~/.makepkg.conf
来覆盖它。
- 不要使用 makepkg 子例程(例如
error
、msg
、msg2
、plain
、warning
),因为它们可能随时更改。要打印数据,请使用printf
或echo
。
- 所有重要消息都应在使用 .install 文件安装期间回显。例如,如果软件包需要额外的设置才能工作,则应包含说明。
- 依赖是最常见的软件包错误。请花时间仔细验证它们,例如通过在动态可执行文件上运行
ldd
,检查脚本所需的工具或查看软件的文档。namcap 实用程序可以帮助您解决此问题。此工具可以分析 PKGBUILD 和生成的软件包 tarball,并会警告您关于错误的权限、缺失的依赖项、冗余的依赖项和其他常见错误。
- 任何可选依赖,如果不是运行软件包或使其正常运行所必需的,则不应包含在 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,因为它始终由软件包隐式提供。 - 在 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()
函数可以防止意外地增加pkgver
而不更新_tag
。有关 VCS 来源格式的更多信息,请参阅 VCS 软件包准则#VCS 来源。
- 不要降低软件包的安全性或有效性(例如,通过删除校验和检查或删除 PGP 签名验证),因为上游版本已损坏或突然缺少某些功能(例如,新版本缺少 PGP 签名)
- 来源在
srcdir
中必须是唯一的(这可能需要在下载时重命名它们,例如"${pkgname}-${pkgver}.tar.gz::https://${pkgname}.tld/download/${pkgver}.tar.gz"
) - 避免使用特定的镜像(例如,sourceforge 上的镜像)进行下载,因为它们可能变得不可用
与上游合作
与上游尽可能紧密合作被认为是最佳实践。这包括报告有关构建和测试软件包的问题。
- 立即向上游报告问题。
- 尽可能向上游提交补丁。
- 在 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/info
GNU Info 系统文件 /usr/share/licenses/pkg
应用程序许可证 /usr/share/man
Manpages /usr/share/pkg
应用程序数据 /var/lib/pkg
持久性应用程序存储 /etc/pkg
pkg 的配置文件 /opt/pkg
大型自包含软件包
- 软件包不应包含以下任何目录
/bin
/sbin
/dev
/home
/srv
/media
/mnt
/proc
/root
/selinux
/sys
/tmp
/var/tmp
/run
Makepkg 职责
当使用 makepkg 构建软件包时,它会自动执行以下操作
- 检查软件包依赖项和 makedepends 是否已安装
- 从服务器下载源代码文件
- 检查源代码文件的完整性
- 解包源代码文件
- 执行任何必要的补丁
- 构建软件并将其安装在虚拟根目录中
- 剥离二进制文件中的符号
- 剥离库文件中的调试符号
- 压缩手册页和/或 info 页面
- 生成软件包元文件,该文件包含在每个软件包中
- 将虚拟根目录压缩到软件包文件中
- 将软件包文件存储在配置的目标目录中(即,默认情况下为当前工作目录)
架构
如果编译后的软件包是特定于架构的,则 arch
数组应包含 'x86_64'
。否则,对于与架构无关的软件包,请使用 'any'
。
许可证
请参阅 PKGBUILD#license。
可重现构建
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
。格式在 上游文档 中进行了说明。