PKGBUILD (简体中文)
相关文章
PKGBUILD是一种 Arch Linux 在 创建软件包时使用的包构建描述文件。其本质是一个shell脚本。
在 Arch Linux 中,创建包时要用到 makepkg 和放在 PKGBUILD 文件里的描述信息。当 makepkg 运行时,它会在当前目录寻找 PKGBUILD
文件,并依照其中的指令去获取依赖文件,之后编译出 pkgname.pkg.tar.xz
文件。生成的包内有二进制文件和安装指令,可以使用 pacman 指令安装它了。
本页面讨论PKGUILD中使用的变量。若要获取PKGBUILD中函数的信息,请参考Creating packages#PKGBUILD_Functions.
Contents
-
1 变量
- 1.1 pkgname
- 1.2 pkgver
- 1.3 pkgrel
- 1.4 pkgdir
- 1.5 epoch
- 1.6 pkgbase
- 1.7 pkgdesc
- 1.8 arch
- 1.9 url
- 1.10 license
- 1.11 groups
- 1.12 depends
- 1.13 optdepends
- 1.14 makedepends
- 1.15 checkdepends
- 1.16 provides
- 1.17 conflicts
- 1.18 replaces
- 1.19 backup
- 1.20 options
- 1.21 install
- 1.22 changelog
- 1.23 source
- 1.24 noextract
- 1.25 md5sums
- 1.26 sha1sums
- 1.27 sha256sums, sha384sums, sha512sums
- 2 更多信息
变量
下面是一些在 PKGBUILD 文件里使用的变量。pkgname
,pkgver
,pkgrel
和arch
是必须出现的。license
在构建包时并不强制要求,但若您想要将PKGBUILD文件和他人分享,推荐您加上该变量。若该变量未设置,makepkg
会警告您。
一般来说,这些变量按下面的顺序出现在 PKGBUILD 文件中,但这并不是强制性的,只要使用正确的 Bash 语法就行了。
pkgname
软件包的名称,名称由小写字母、数字和任意以下字符组成:@ . _ + - (at 符号, 点, 下划线, 加号, 连字符)。字母均为小写且不能以连字符开头。为了保证一致性,pkgname
应该匹配源文件 tar 包的名称,比如:源文件包名为 foobar-2.5.tar.gz
,那么 pkgname
的值应该是 foobar。除此之处,PKGBUILD
文件所在工作目录也应该与 pkgname
想匹配。
pkgver
软件包的版本号,应该与软件原作者发布的版本号一致。它由字母、数字和'.'组成,但不能包含连字符'-',如果原作者在他的版本号中使用了连字符'-',那么用下划线'_'来替代。举个例子:原版本号“0.99-10”,改写成“0.99_10”。在之后的 PKGBUILD 指令中 pkgver
中的下划线可以用下面这个方法替代为连接符:
source=("$pkgname-${pkgver//_/-}.tar.gz")
pkgrel
软件包对 Arch Linux 的释出号。这个值可以用来区分同一版本软件的多次构建。当软件包第一次发布时,释出号为1,随着 PKGBUILD
的调整与优化,软件包再次发布,释出号递增 1。而当这个软件包发布一个新版本时,释出号重置为 1。
pkgdir
该变量展示(设置)包中文件的根目录。它经常在make DESTDIR="$pkgdir" install
中使用。PKGBUILD (prepare()
, build()
, check()
, etc.) 的任何方法都不应该修改此值。
epoch
这是一个针对 Arch Linux 的特别的整型值,用于比较软件的生命周期和版本号。这个值允许使用一般性的版本区分规则重写那些因降级,改变版本编号方式等因素而前后不一致的版本编号。默认情况下,软件包会假定这个值为 0。除非你明白自己在做什么,否则不要使用此变量。
用来强制使软件包被视为更新版本。该值越小,软件包版本就会被视为越新——即使软件版本号并不表现为更新。该值必须为一个正整数(若留空,则设置为0)。当一个软件的版本编号方式改变,打破正常的版本比较逻辑时,该变量尤其有用。参见pacman(8)来获取关于版本号比较的更多信息。
pkgbase
当构建分开的包时可以使用一个可选的全局参考值。pkgbase用来指向软件包组,它们在makepkg的输出及纯源代码的包名中。若该变量未被设置,则用pkgname数组的第一个元素充当。PKGBUILD中的本全局变量是分包的所有选项和参考值的默认值。然而,一些参数可以在每个包的打包函数中被覆盖,它们是:pkgver,pkgrel,epoch,pkgdesc,arch,url,license,groups,depends,optdepends,provides,conflicts,replaces,backup,options,install以及changelog。此变量不允许以下划线开头。
pkgdesc
软件包描述,最多80个字符并且不能包含软件包自身的名称。比如:"Nedit is a text editor for X11"应该写成"A text editor for X11"。
arch
主机架构数组。当前,它应该包含 i686
、x86_64
两者或其中之一,arch=('i686' 'x86_64')
。值 any
用于不依赖架构的软件包。
在构建过程中,甚至是定义其它变量时都可以使用变量 $CARCH
来取得当前主机架构。另请参考FS#16352。例:
depends=('foobar') if test "$CARCH" == x86_64; then depends+=('lib32-glibc') fi
url
软件官方站点的网址
license
软件发布许可证。软件包仓库 [core]
中的 licenses 包存放了通用的许可证协议,安装后能在 /usr/share/licenses/common
中找到这些许可证协议,比如 /usr/share/licenses/common/GPL
。如果软件包是发布在这些许可证中的任何一个,这个值应该被设定成许可证的目录名,比如:license=('GPL')
。如果官方 licenses 包中没有适用的许可证,可以按下的方法做:
- 许可证文件应当放到
/usr/share/licenses/pkgname/
目录下,例如:/usr/share/licenses/foobar/LICENSE
。 - 如果源文件中没有包含证书的内容,而是保存在其它地方,比如说一个网站上,那么你需要把许可证内容拷贝到一个文件并在软件包中包含它。
- 把
custom
添加到license
列表。或者你可以用custom:name of license
替代custom
。一旦某个许可证被官方仓库用于两个以上软件包(包括[community]
),它将成为 licenses 的一个组成部分。
-
BSD、MIT、zlib/png 和 Python 是几个例外的情况,它们不能加入 licenses 包。在
license
列表中还是把它们当成通用协议来对待(license=('BSD')
,license=('MIT')
,license=('ZLIB')
andlicense=('Python')
),但是实际上它们都是私有协议,因为它们都包括了各自的版权条款。任何发布于这四个许可协议的软件包都应该在/usr/share/licenses/pkgname
存放它们独有的许可证文件。一些软件包可能不止一个许可证,这种情况下,在license
列表中置入多个值,像license=('GPL' 'custom:name of license')
。 - 另外,(L)GPL 拥有多个版本。对那个 (L)GPL 软件,约定如下:
- (L)GPL - 指代 (L)GPLv2 或之后的任意版本
- (L)GPL2 - 仅 (L)GPL2
- (L)GPL3 - 指代 (L)GPL3 或之后的任意版本
- 如果最终无法决定使用哪种许可证,
PKGBUILD.proto
建议使用unknown
。这种情况下应该联系上游的软件发布者。
groups
软件包所在的组。例如:当你安装 kdebase,它会安装属于 kde 组里的所有包。
depends
软件的运行时依赖列表。可以使用比较运算符来描述版本限制,如:depends=('foobar>=1.8.0')
。如有多重限制,你可以重复设置它们[1],像这样:depends=('foobar>=1.8.0' 'foobar<2.0.0')
你并不一定要限制依赖包的版本。且并不需要列出你的软件包的二次依赖——你的软件及它所依赖的软件共同依赖的软件包。比如说:gtk2依赖{{pkg|glib2}和glibc;然而glib2本就依赖于glibc,那么在gtk2中就不需要把glibc加入 depends 列表。
optdepends
一组不影响软件正常工作,但能提供额外特性的软件包。应该简要说明每个包所能提供的额外特性。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' )
makedepends
软件编译时需要,但运行时并不依赖的包序列。可以像depends
序列里提到的一样指定最小版本依赖。
checkdepends
运行测试组件时需要,而运行时不需要的包列表。该列表中的包遵循和depends
相同的格式。这些依赖只在check()函数存在且被makepkg运行时被考虑。
provides
这个变量说明当前包能替代的其它软件包(或者像 cron、sh 这样的虚拟包)。
如果你使用这个变量,应当加上所替代软件的版本号(pkgver
,可能的话还有pkgrel
)。举例来说,如果你提供一个修改过的 qt 包其版本号为 3.3.8,命名为 qt-foobar,那么 provides
应该写成 provides=('qt=3.3.8')
。只写成 provides=('qt')
会使对 qt 有版本依赖的包编译失败。不要把 pkgname
加入 provides 序列,它会自动完成的。
conflicts
与当前软件包发生冲突的包列表。可以像 depends 那样指定冲突包的版本号。
replaces
会因安装当前包而取代的包列表,比如:wireshark-gtk中的replaces=('wireshark')
。pacman -Sy
同步软件数据库后,会立刻用软件库中的另一个包替换掉 replaces
中已安装的包。如果你只是提供已存在包的一个替代品,使用conflicts
变量——该变量仅在安装冲突包时被检查。
backup
当包被升级或卸载时,应当备份的文件(的名字)。这些文件一般是用户会更改的文件,如(主要是)放置在/etc
中的配置文件。
在升级时,新版本会被命名为file.pacnew
以避免覆盖旧有且被用户修改过的文件。类似地,当卸载包时,用户修改过的文件会以file.pacsave
为名而保留下来——除非用pacman -Rn
命令卸载。
列表中的文件应该使用相对路径(如 etc/pacman.conf
),而不是绝对路径(如 /etc/pacman.conf
)。参见Pacnew and Pacsave files获取更多信息。
options
这个变量允许你重置makepkg
的部分默认(定义在/etc/makepkg.conf
中的)行为。要设置一个选项必须指定选项名。要反转一个默认行为,在选项前加上!
。
参见man PKGBUILD
以获取所有可用选项。
install
.install
脚本的名称。pacman 可以在安装、卸载或升级一个软件包时存储及执行一些特定的脚本。在不同的情况下,脚本会执行下面几个函数。
- pre_install - 安装前运行的脚本,可以传递版本号为参数。
- post_install - 安装后运行的脚本,可以传递版本号为参数。
- pre_upgrade - 升级前运行的脚本,可以按
新版本号
,旧版本号
的顺序传递参数。 - post_upgrade - 升级后运行的脚本,可以按
新版本号
,旧版本号
的顺序传递参数。 - pre_remove - 卸载前运行的脚本,可以传递版本号为参数。
- post_remove - 卸载后运行的脚本,可以传递版本号为参数。
每一个函数都是在 pacman 安装目录下通过 chroot 运行。参见这个帖子.
changelog
软件包 changelog 的名称,要查看安装软件的 changelog:
pacman -Qc pkgname
source
构建软件包时需要的文件列表。它必须包含软件源的位置信息,大多数情况下是一个完整的 HTTP 或 FTP 地址。可以在软件源信息中很好的调用前面提到的变量 pkgname
和 pkgver
(如 source=("https://example.com/$pkgname-$pkgver.tar.gz")
)。
noextract
一些列举于 source
中,但不需要在运行makepkg
时解包的文件。这种情况常发生在不能被/usr/bin/bsdtar
处理的文件上——libarchive以流方式来处理所有文件,而不像unzip一样随机访问。在这些情况下,额外的解包工具(如unzip
、p7zip
等)应该加入 makedepends
序列,并且用prepare()函数手动解包。例如:
unzip [source].zip
注意当 source
是一些 URL 时,noextract
仅仅取文件名部分。举例说明:可能像下面这样(截取自 grub2's PKGBUILD):
source=("https://ftp.archlinux.org/other/grub2/grub2_extras_lua_r20.tar.xz") noextract=('grub2_extras_lua_r20.tar.xz')
不提取任何东西时,可以像这样(截取自firefox-i18n):
noextract=("${source[@]%%::*}")
md5sums
source
列表中文的 MD5 校验和。一旦 source
序列中的所有文件都存在了,每个文件的 MD5 哈希值会自动的计算出来,并与对应 source
列表位置的 MD5 值相比较。源文件本身的顺序并不重要,重要的是要能与这个列表相匹配,因为 makepkg
并不能猜出哪个较验和虽于哪个源文件。你可以在包含 PKGBUILD
文件的目录下,使用指令 updpkgsums
简单而快速生成 MD5 序列。
sha1sums
SHA-1 160位校验和序列。它是上面所说的 md5sums 之外的一个选择。为了启用sha-1,请在 /etc/makepkg.conf
设置 INTEGRITY_CHECK
选项。参见 man makepkg.conf
。
sha256sums, sha384sums, sha512sums
SHA-2 校验和列表,有256,384 和 512位。它们都可以替代上述的 md5sums
和 sha1sums
,并且有更少的已知弱点。为了启用这些算法,在 /etc/makepkg.conf
开启 INTEGRITY_CHECK
选项。详情请看 man makepkg.conf
。