APKBUILD 参考

来自 Alpine Linux

APKBUILD 是为了使用 abuild 工具构建 Alpine 软件包而创建的脚本。

有关 Alpine 官方 ports 仓库的详细信息,请参阅 aports

本页面旨在作为创建 APKBUILD 的参考;如果这是您第一次为 Alpine Linux 创建软件包,请参阅 创建 Alpine 软件包

图例

以下注释将帮助您理解本文档。

在描述文本中

  • 如果变量没有以 $ 为前缀,它将以斜体表示(即,srcdir )。
  • 函数也将以斜体表示,但也会以一对括号结尾(即,build() )。
  • Shell 命令将以 像这样 表示。


变量

注意: 包含路径的变量(例如 $srcdir$pkgdir)应始终使用双引号括起来(即,"$srcdir")。这样做是为了防止当用户在包含空格的目录路径中拥有 APKBUILD 时发生错误。
注意: 所有任意变量和函数名称都应以下划线字符 ( _ ) 为前缀,以避免与 abuild 的内部结构发生名称冲突(例如,_luaversions)。

这些变量都在 man 5 APKBUILD 中有详细文档(man page 源代码)。

用户定义的变量

以下变量应由用户定义

maintainer

软件包维护者的姓名和电子邮件地址。
一个格式良好的示例是 maintainer="John Snow <john_snow@thewall.net>"

arch

要构建的软件包架构。可以是以下架构之一或以空格分隔的多个架构:x86, x86_64, armv7, armhf, aarch64, ppc64le, s390x, riscv64, all, 或 noarch,其中 all 表示所有架构,noarch 表示它是架构独立的(例如,纯 Python 软件包)。可以使用 ! 字符否定架构,以将其从支持的架构列表中排除。例如,arch="all !ppc64le" 表示允许在除 ppc64le 架构之外的所有架构上构建软件包。
提示: 要确定您的 APKBUILD 是否可以使用 noarch:首先指定 all,然后通过执行 abuild -r 构建软件包。在输出的末尾注意警告,说明可以使用 noarch。如果主软件包和所有子软件包(如果您有任何子软件包)都给出警告,说明可以使用 noarch,那么您可以使用 noarch

depends

运行时依赖软件包,这些软件包不是共享对象依赖项。共享对象依赖项是自动检测的,不应在此处指定。要指定冲突的软件包,请在软件包名称前添加 '!'。

depends_dev

$pkgname-dev 子软件包的运行时依赖软件包。
注意: 来自 IRC 上的 ncopa:要了解是否需要将软件包添加到 depends_dev,请查看 usr/lib/pkgconfig/*.pc 中的 *requires*。使用 libtool 会更复杂,但我们应该删除 .la 文件。还要检查是否有任何 /usr/bin/*-configure #!/bin/bash #!/usr/bin/perl 或 Python。有时脚本或类似内容是在构建时生成的(即 autoconf automake),那么通常不需要将这些添加到 depends_dev。您也可以只将所有 -dev makedepends 添加到 depends_dev,但这会稍微减慢构建过程(更多的构建依赖项)。

depends_doc

$pkgname-doc 子软件包的运行时依赖软件包。

depends_openrc

$pkgname-openrc 子软件包的运行时依赖软件包。

depends_libs

$pkgname-libs 子软件包的运行时依赖软件包。

depends_static

$pkgname-static 子软件包的运行时依赖软件包。

checkdepends

仅在检查阶段需要的依赖项,只有在启用 check 选项时才会安装它们

giturl

abuild checkout 从中检出的 Git 仓库。您可以通过添加 -b $branch 在 git 中检出特定分支。

install

有 6 种不同类型的安装脚本。安装脚本命名为 $pkgname.action,其中 action 可以是:pre-install、post-install、pre-upgrade、post-upgrade、pre-deinstallpost-deinstall。例如,如果 pkgname 设置为 mypackage,而 install 设置为 $pkgname.post-install,那么名为 mypackage.post-install 的脚本必须与 APKBUILD 并排存在。
注意: 始终对安装脚本的 shebang 行上的命令行解释器使用 /bin/sh

以下是各种类型的安装脚本的详细信息

$pkgname.pre-install
此脚本在安装软件包之前执行。典型用途是在软件包需要创建组和用户时。例如
#!/bin/sh

addgroup -S clamav 2>/dev/null
adduser -S -D -H -h /var/lib/clamav -s /sbin/nologin -G clamav -g clamav clamav 2>/dev/null

exit 0
注意: 如果脚本退出时失败(例如,如果用户已存在),则软件包将不会被安装,并且 apk 将以失败退出,因此末尾有 exit 0
$pkgname.post-install
此脚本在安装软件包之后执行。
$pkgname.pre-upgrade
此脚本在升级/降级/重新安装软件包之前执行。请注意,退出时失败不会导致 apk 以失败退出,但会将软件包标记为损坏。
$pkgname.post-upgrade
此脚本在升级/降级/重新安装软件包之后执行。
$pkgname.pre-deinstall
此脚本在卸载软件包之前执行。
注意: 如果脚本退出时失败,apk 将不会卸载软件包。
$pkgname.post-deinstall
此脚本在卸载软件包之后执行。

install_if

当某些软件包已安装或在依赖树中时,可以使用 install_if 来安装软件包。它的工作方式与 recommends 功能相反,而其他软件包管理器提供 recommends 功能。
通常,这用于子软件包中,该子软件包应提供对另一个软件包有意义的文件。例如
...
subpackages="$pkgname-bash-completion:bashcomp:noarch"
...
bashcomp() {
	pkgdesc="Bash completions for $pkgname"
	install_if="$pkgname=$pkgver-r$pkgrel bash-completion"

	install -Dm644 "$builddir"/doc/bash_completion/aria2c \
		"$subpkgdir"/usr/share/bash-completion/completions/_aria2c
}

来自 aria2c APKBUILD。请注意,自定义 bashcomp() 函数是必需的,因为这些文件不在 /usr/share/bash-completion 中。

通常,install_if 应该只与至少一个版本约束一起使用。否则,通过 install_if 隐式安装的软件包,然后从二进制仓库中删除,将不会通过 apk upgrade 清除。[1]

license

软件包的许可证,例如 GPL-3.0-or-laterBSD-2-ClauseMIT (详情)

makedepends

构建时依赖软件包。对于交叉编译支持,将其拆分为 makedepends_build(本机系统)和 makedepends_host(外部系统)。

sha256sums/sha512sums

source 中列出的文件/URL 的校验和。校验和通常通过执行 abuild checksum 生成和更新,并且应该是 APKBUILD 中的最后一个项目。

新软件包应仅使用 sha512sums。对 md5sums 和 sha1sums 的支持已删除。

options

软件包的构建时选项。
选项 描述
!archcheck 不要尝试验证二进制文件的架构是否与 abuild 应该构建的架构相同。设置此选项的一个合理示例是包含固件文件的软件包,这些固件文件在另一个 CPU(例如 WiFi 固件)上执行。
!check 不要尝试运行 check() 函数。请始终在 !check 之后添加简短注释,说明禁用它的原因。[2] 创建一个非常简单的 check 函数,它调用 program --version 比完全禁用测试更糟糕,因为它给人一种错误的印象,即软件包已通过上游的测试套件进行了彻底测试。[3]
checkroot 指定软件包的测试套件将在 fakeroot 中运行。对于某些以非 root 身份运行时会失败的测试套件,这是必要的。
net 允许在 rootbld 中运行时进行网络访问。
!strip 避免从二进制文件中剥离符号。
suid 允许 setuid 二进制文件。
!tracedeps 不要自动查找依赖项(例如,通过使用 ldd 查找生成的二进制文件链接到的动态库)。
chmod-clean 使 src/ 目录中的所有文件都可写。对于在构建软件包(go 模块)过程中使文件变为只读的软件包很有用。
toolchain 当 g++ 在 makedepends 中时不发出警告
!dbg 不创建调试子软件包
ldpath-recursive 在创建 .so providers 时递归扫描目录
!spdx 不检查 license= 字段是否具有符合 SPDX 的许可证
textrels 当找到文本重定位时不报错
charset.alias 如果找到 /usr/lib/charset.alias 则不报错
libtool 不删除 libtool .la 文件
!fhs 不对遵循 FHS 的路径强制执行检查

pkgdesc

对软件包功能的简短单行描述。
这是来自 OpenSSH 客户端软件包的示例
pkgdesc="Port of OpenBSD's free SSH release - client"

pkggroups

在构建时要创建的系统组。系统组也应在 $pkgname.pre-install 脚本中创建,以便系统组也在软件包安装之前创建以供运行时使用。

pkgname

软件包的名称。所有字母都应为小写。
注意: 在为另一个软件包创建模块或库的 APKBUILD 时,我们使用一些常见的软件包前缀,例如:lua-perl-php-py3-。在 aports 中搜索其他常见前缀。

pkgrel

Alpine 软件包发布号。从 0(零)开始。在更新 aport 时始终递增 pkgrel;当递增 pkgver 时,将 pkgrel 重置为 0(零)。

pkgusers

在构建时要创建的系统用户。系统用户也应在 $pkgname.pre-install 脚本中创建,以便系统用户也在软件包安装之前创建以供运行时使用。

pkgver

要打包的软件的版本。有效版本的格式:{digit}{.digit}...{letter}{_suf{#}}...{-r#} [4]
上述格式中的后缀 suf 可以是以下之一,以指示发布版本没有后缀的版本alphabetaprerc [5]
这些用于指示较新的发布版本:cvssvngithgp [6]
所有其他后缀均无效。要打包特定的 git 提交,提交日期将附加到最新版本,例如 1.0.0_git20180204

provides

此软件包提供的软件包名称列表(以及可选的版本信息)。
如果提供了带有版本的软件包 (provides='foo=1.2'),则 apk 会将其视为备用名称,并且会自动考虑通过备用名称安装该软件包,并与具有相同名称或 provides 的其他软件包冲突。
如果未提供版本 (provides='foo'),则 apk 会将其视为虚拟软件包名称。可以同时安装多个具有相同非版本化 provides 的软件包。但是,当通过虚拟名称请求时,默认情况下不会安装它们中的任何一个 - 而是给出错误消息,并要求用户选择应安装哪个提供虚拟名称的软件包。

provider_priority

一个数值,apk-tools 在选择虚拟软件包以满足依赖项时使用它来打破僵局。值越高,优先级越高。主要用例是指定满足虚拟(provider)的主软件包。

replaces

允许在与列出的软件包同时安装此软件包,即使它们具有冲突的文件也是如此。来自此软件包的文件将覆盖(“接管”)冲突的文件。
这可以用于使用“策略软件包”覆盖配置文件 [7]
另一个用例是重命名软件包(或将文件从一个软件包移动到另一个软件包):“replaces”将避免 apk 在卸载旧软件包之前碰巧安装新软件包时报告的文件冲突错误 [8]
一个常见的误解是,“replaces”用于替换软件包(如在 PKGBUILD 中)。情况并非如此,它仅用于解决文件冲突。要让 apk 考虑安装一个软件包而不是另一个软件包,请参阅 provides(带有版本)。

replaces_priority

replaces 的优先级。如果多个软件包相互替换文件,则 replaces_priority 最高的软件包将获胜。

source

source 变量不仅用于列出要获取的远程源文件,还用于列出 abuild 构建 apk 所需的本地文件。此类本地文件的示例包括:init.d 文件、conf.d 文件、安装文件(参见 install 变量)、补丁以及所有其他必要的文件。
以下是一些需要注意的事项
  • 当您完成向 source 添加本地和/或远程文件时,您可以执行以下命令以将其校验和添加到 APKBUILD 文件

abuild checksum

注意: 稍后更新 source 的内容或更新 source 中列出的文件时,您还必须使用相同的命令再次更新其校验和。
  • 当远程文件托管在 SourceForge 时,最好指定 SourceForge 使用的特殊镜像链接
http://downloads.sourceforge.net/software/software-$pkgver.tar.gz
(或类似的,取决于软件包)。
  • 您可以通过在 URI 前面加上 filename:: 来设置目标文件名(例如“另存为...”)。当远程文件名未在 URI 中指定时(即,不以“/software-1.0.tar.gz”结尾),这很有用,例如
http://oss.example.org/?get=software&ver=1.0
或者当文件名很糟糕时,例如 github 的下载标签
https://github.com/software/software/archive/v$pkgver.tar.gz
以上两个示例都需要目标文件名前缀
$pkgname-$pkgver.tar.gz::http://oss.example.org/?get=software&ver=$pkgver
$pkgname-$pkgver.tar.gz::https://github.com/software/software/archive/v$pkgver.tar.gz
  • abuild 当前支持以下用于远程文件检索的协议
    • http
    • https
    • ftp
  • abuild 当前支持以下存档类型/存档文件扩展名
    • .tar(仅在 Alpine >= 2.5 中)
    • .tar.gz / .tgz
    • .tar.bz2
    • .tar.lz(仅在 Alpine >=3.7 中)
    • .tar.lzma
    • .tar.xz
    • .zip
  • source 应仅包含经常更改的变量,例如 pkgver 或提交 ID。如果您在 source 中包含 pkgname,CI 会警告您。其他变量,例如 _pkgname_pyname 也不属于 source。

subpackages

从此 APKBUILD 构建的子软件包。 abuild 将解析此变量并尝试查找子软件包拆分函数。拆分函数必须将不属于主软件包的文件从 $pkgdir 移动$subpkgdir。文件和目录也可以从 $startdir$srcdir 复制$subpkgdir
拆分函数可以通过 3 种不同的方法指定
  1. subpkgname:splitfunc
  2. $pkgname-splitfunc
  3. splitfunc
注意: 拆分函数名称不能使用连字符;如果子软件包名称包含连字符 (-) 字符,请使用上面的第一种方法,如下所示:subpkg-name:subpkg_name,其中 subpkg-name子软件包的名称,subpkg_name子软件包的拆分函数的名称。
提示: 有关更多信息,请参阅 子软件包示例

triggers

Apk-tools 可以“监视”目录,并且如果任何软件包在被监视的目录中安装/卸载了任何文件,则执行触发器。触发器始终在 apk 操作(安装、卸载、升级)之后执行。
触发器以格式指定:scriptname=pathlist,其中 scriptname 是(子)软件包名称 + .trigger 后缀,而 pathlist 是 : 分隔的要监视的目录列表。
triggers 变量必须包含子软件包的触发器(如果它们有任何触发器)。
可以在目录列表中使用通配符 (*)。

url

软件包的主页。这旨在帮助用户查找上游文档和有关软件包的其他信息。

langdir

-lang 子软件包的语言文件所在路径,默认为 /usr/share/locale

pcprefix

使用此变量中的值作为前缀,为所有从解析 pkg-config Requires: 派生的 provides 添加前缀,例如:'pcprefix="foo:" 将生成 pc:foo:bar

sonameprefix

使用此变量中的值作为前缀,为所有从解析共享对象派生的 provides 添加前缀,例如:sonameprefix="foo:" 将生成 so:foo:bar.so.X

函数

注意: 所有不是 prepare()build()check()package() 的函数都应将当前工作目录视为未定义,因此应利用 abuild 定义的目录变量
sanitycheck() -> clean()-> fetch() -> verify() -> unpack() -> prepare() -> mkusers() -> build() -> check() -> package() -> subpackages() -> language packs -> apk -> cleanup()

abuild 定义的函数

以下函数由 abuild 提供,可以被覆盖,但在代码审查中强烈不建议覆盖某些函数

fetch()

source 中列出的远程源下载到 SRCDESTSRCDEST/etc/abuild.conf 中配置),并在 $srcdir 中创建符号链接。

unpack()

unpack() 将调用 default_unpack()。
default_unpack() 解压缩来自与 $SRCDEST(或 distfiles 文件夹)关联的 $srcdir 中的符号链接的 .tar、.tgz、.tar.gz、.tar.lz(仅在 Alpine >=3.7 中可用)、.tar.bz2、.tar.lzma、.tar.xz 和 .zip 存档,从而在 $srcdir 中生成解压缩的文件夹。

dev()

$pkgname-dev 软件包的子软件包函数用于收集开发人员文件和文件夹,以供其他软件包在编译过程中使用,仅此而已。如果不指定自定义 dev() 函数,abuild 将调用其内部 dev() 函数,该函数又会调用 default_dev()。
default_dev() 将递归地将 "$pkgdir"/{lib,usr} 中的任何 include 文件夹和包含 *.[acho](静态存档、c 源代码、c 头文件、目标文件)、*.prl 文件扩展名模式的文件夹移动到 "$subpkgdir"/{lib,usr};并将 "$pkgdir"/{lib,usr/lib} 中的 *.so 文件移动到 "$subpkgdir"/{lib,usr/lib}。它还将扫描并移动 $pkgdir 中的 usr/{include,lib/{pkgconfig,cmake,qt*/mkspecs},share/{aclocal,gettext,vala/vapi,gir-[0-9]*,qt*/mkspecs},bin/*-config}} 仅开发人员文件夹,并将它们传输到 $subpkgdir
通常,default_dev() 将支持共享 pkg-config、C 编程语言 API、共享库和静态库、Autotools、gettext、Vala 编程语言绑定、Python GObject introspection、提供的自定义 pkg-config 样命令 (*-config)、Qt 和 CMake 的软件包。如果您有 C++、其他语言、其他构建系统等的软件包;则只有当这些开发人员文件要在其他软件包中使用时,才需要手动移动它们。
重要提示:要像 no dev() 那样调用 default_dev(),您需要显式添加 subpackages="$pkgname-dev"。

doc()

$pkgname-doc 软件包的子软件包函数,其工作仅是从 $pkgdir 收集文档文件夹,仅此而已。如果不指定自定义 doc() 函数,abuild 将调用其内部 doc() 函数,该函数又会调用 default_doc()。
default_doc()"$pkgdir"/usr/share/{doc,man,info,html,sgml,licenses,gtk-doc,ri,help} 移动到 $subpkgdir
强烈建议不要覆盖此函数。打包文档应在 package() 函数中完成,同时让 abuild 自动收集文档文件夹。
重要提示:要像 no doc() 那样调用 default_doc(),您需要显式添加 subpackages="$pkgname-doc"。

openrc()

$pkgname-openrc 软件包的子软件包函数,其工作是收集位于 /etc/init.d 和 /etc/conf.d 中的 OpenRC 服务文件。
default_openrc()"$pkgdir"/etc/{conf,init}.d 移动到 $subpkgdir
强烈建议不要覆盖此函数。打包 OpenRC 服务定义应在 package() 函数中完成,同时让 abuild 自动收集 openrc 文件夹。
重要提示:要像 no openrc() 那样调用 default_openrc(),您需要显式添加 subpackages="$pkgname-openrc"。

static()

$pkgname-static 软件包的子软件包函数,其工作是收集存储在 /lib 和 /usr/lib 中的静态库。
default_static() 将所有静态库(以 .a 结尾的文件)从 "$pkgdir"/lib"$pkgdir"/usr/lib 移动到 $subpkgdir 中的等效位置。
强烈建议不要覆盖此函数。打包静态库应在 package() 函数中完成,同时让 abuild 自动收集静态库。
重要提示:要像 no static() 那样调用 default_static(),您需要显式添加 subpackages="$pkgname-static"。

snapshot()

可选。对于 live APKBUILD 或版本号中带有 _cvs、_svn、_git、_hg 的 APKBUILD,只有当没有指向提交/哈希/标签的存档文件(.zip、.tar.gz 等)的下载链接时,才应创建快照函数。快照函数的目的是创建源代码的存档,以便软件包源代码是确定性的,并且它不会浪费时间来获取源代码,而是在快照后绕过下载步骤。那些从 git 仓库下载源代码的人将遵循 head 或源代码的最新更改。最好将源代码存档为 zip / tar.gz / tar.bz2,直到您尝试构建软件包的提交或标签。如果对于每个依赖项和主项目,代码不是确定性的或并非所有部分都及时冻结,那么补丁将失败,或者当您几个月或几年后重新访问软件包以反向移植补丁时,软件包可能无法编译。
默认 snapshot() 函数具有与之关联的变量
  • $disturl - 自动上传快照的位置的基本 URL
  • $svnurl - Subversion 仓库
  • $giturl - Git 仓库
默认 snapshot() 只能支持一个仓库。如果您的软件包中涉及多个仓库,则最好覆盖它。CVS、Mercurial (hg) 和其他备用版本控制系统必须覆盖默认 snapshot()。
请参阅 APKBUILD 示例:Git checkout,了解如何在 git 中使用它。它通常需要 2-3 个步骤。克隆仓库;在特定的修订版/提交或标签处检出它;然后您使用 archiver 将其转储到 $SRCDEST 变量中,该变量指向 distfiles 文件夹和您要创建的存档的完整路径的基本路径。您为软件包拉取的每个内部依赖项都执行此操作。
创建快照函数后,您可以使用 abuild snapshot 来运行它。
快照生成的存档将保存在 /var/cache/distfiles 或您为 $SRCDEST 设置的任何位置。如果存档未保存到 Alpine 服务器,您可能需要创建指向该存档的符号链接。
在快照后,您需要使用 abuild checksum 生成校验和,以便在 APKBUILD 创建过程中使用它。
此功能自 Alpine >=2.6 起可用。

default_prepare()

在构建准备之前,它处理 $srcdir 内的一组补丁,并打印失败的补丁。

用户定义的函数

以下函数应由用户定义

prepare()

注意: 请调整旧的 APKBUILD,当您无论如何都要编辑它们时,它们仍然具有与 default_prepare() 执行相同操作的 prepare() 函数。
可选 用于构建准备:补丁等应在此处应用。当您不指定自定义 prepare() 时,将使用来自 abuild 的内置 default_prepare()。它已经应用了补丁(始终以 -p1 格式准备它们),因此通常根本没有必要创建自定义 prepare() 函数! 如果您确实创建了一个,请在其中调用 default_prepare()
在调用 default_prepare 之前,您可以定义 patch_args 以在全局范围内为 patch 命令提供参数,然后丢弃 prepare(),这样就不需要使用旧的模板代码来打补丁了。patch_args 和自动打补丁仅在 Alpine >=3.4 中可用。请参阅 Creating_an_Alpine_package#Patches 以修复使用不同补丁级别 (-pX) 的补丁。
prepare() {
    default_prepare
    # your custom code here
}

build()

必需。 这是编译阶段。此函数将以当前用户身份调用(除非缺少 package() 函数 - 出于兼容性原因)。如果不需要编译,则应删除该函数。
要启用或禁用每个架构的 CFLAGS、CXXFLAGS、带有选项的 CMake 或配置选项,请使用 CARCH 变量
local cmakeoptions=
case "$CARCH" in
        aarch64*|arm*|ppc64le|x86|s390x) cmakeoptions="$cmakeoptions -DWITH_OPENMP=OFF" ;;
        x86_64)                          cmakeoptions="$cmakeoptions -DWITH_OPENMP=ON" ;;
        *)                               msg "Unable to determine architecture from (CARCH=$CARCH)" ; return 1 ;;
esac
该代码块可以用于 APKBUILD 的其他部分,甚至在全局范围内。

check()

如果功能存在则为必需。 此函数在构建阶段之后立即调用。它应该检查打包的内容是否实际工作,通常通过运行(集成)测试(如果上游提供)。如果没有(简单)方法来测试软件包,您可以声明它不想使用 check(),方法是在 options 变量中添加 "!check" (options="!check")。
default_check() 不执行任何操作。您需要手动显式调用单元测试或测试套件。当您运行测试时,程序应返回退出代码 0,表示测试成功。单元测试或测试套件将执行功能测试、每个函数的正确性检查、模糊测试、基准测试。
软件包也可能需要作为外部依赖项的其他测试框架软件包。您应该将它们添加到 Alpine >=3.6 中的 checkdepends= 或旧版本回溯移植中的 makedepends= 中。如果测试框架不可用,您需要为其创建一个软件包。如果它需要特定版本的测试框架,请考虑将其作为内部依赖项或创建一个新的软件包,其软件包名称包含主要版本号和次要版本号,例如 python 软件包。
一般来说,您应该为库、大型程序(如 Web 浏览器或编译器和解释器)、加密/安全/匿名相关内容、关键任务内容、PCI 合规性/金钱/会计软件、具有大量利益相关者或消费者的服务器软件定义 check 函数。很快,新的策略变更将要求几乎所有具有测试功能的软件包都必须具有可工作且已定义的 check() 函数
有时单元测试不起作用,仅仅是因为测试本身已损坏、新功能未实现、未考虑外部因素、解捆绑路径差异、ccache 引起的损坏、缺少测试依赖项或版本不匹配依赖项(如 python2 与 python3)、测试脚本仅适用于特定的语言实现(如仅支持 python2 但不支持 python3,使用了 2to3 转换脚本)。如果已知单元测试不起作用,您可能需要修补它以省略该测试或修复它;但是,某些重要的测试不应禁用。您可能需要更改对未编译的内部依赖项的引用,以使其与外部依赖项一起工作。对于 ccache,您可以禁用它或在运行测试之前将其从 PATH 环境变量中删除。
注意: 图形应用程序和工具包的测试可能在 X11 用户设置上工作,但在服务器上会失败,除非使用 xvfb-run 运行。
如果您不添加 check()options=,您将看到以下内容
 >>> WARNING: py-webtest*: APKBUILD does not run any tests!
   Alpine policy will soon require that packages have any relevant testsuites run during the build process.
   To fix, either define a check() function, or declare !check in $options to indicate the package does not have a testsuite.
如果您不执行检查或禁用它,您必须在 options="!check" 的代码审查员注释形式 (#) 中说明没有测试套件。
要使用 autotools 运行测试套件,请执行
 make check
要使用 python setuptools 运行测试套件
 python2 setup.py test
 python3 setup.py test
对于 python,应该是 test 而不是 check。Check for python setuptools 将检查包装元数据字段[9],但不会运行单元测试。也应该有详细的输出。测试的依赖项在 setup.py 中的 test_require 中找到。
如果它显示 Ran 0 tests in 0.000s,这是不可接受的。check() 会说它是好的,但实际上是不正确的。如果看到 tox.ini 文件,则需要使用替代方法(如 tox -e py27,py36)运行测试套件。
您希望为每个实现都这样做,以确保每个实现的 API 调用都是正确的,但 ncopa 说 python3 就可以了。
如果 checkdepends= 存在循环依赖关系,您需要禁用检查并将原因放在 options="!check" 旁边,说明存在循环依赖关系。您应该为最不重要或安全风险最低的软件包禁用它。另一种解决方案是将冲突的依赖项设为内部依赖项,但要确保它在检查时不被拉取。这样,它们都可以正确地执行测试。

package()

必需。 这是打包阶段。在此阶段,应将构建的应用程序和支持文件安装到 $pkgdir 中。如果这是一个元软件包,则此函数可以包含一行代码:mkdir -p "$pkgdir"
注意: 在 fakeroot 中构建会显着降低并行构建的性能。因此,我们将构建和打包过程分为两个独立的函数。

特殊运算符

$pkgname~$pkgver

指定 apk 满足 $pkgname 要求所需的 $pkgver~ 忽略软件包版本的修订版。例如,$depends 中的 superd~0.6 将确保安装软件包版本为 0.6 的 superd 作为软件包的运行时依赖项。

$pkgname>=$pkgver

指定已安装的软件包版本必须大于或等于 $pkgverapk 才能满足 $pkgname 要求。


示例

APKBUILD 示例页面将帮助您了解如何创建 APKBUILD。

版本

本文档假定 abuild 用于 Alpine Edge。对于旧版本的 abuild,如果您使用的是旧版本,则某些功能可能不可用。研究人员和回溯移植者可以链接到实现。

有关更多信息,请参见APKBUILD_versions