ABS PKGBUILD 详解 (简体中文)
From ArchWiki
i18n |
---|
English |
Dansk |
简体中文 |
正體中文 |
Arch 用戶可以使用ABS轻易将源代码编译为一个 .pkg.tar.gz 软件包.
Contents |
什么是软件包文件?
记住,ABS自动为你要编译的那个软件包下载源代码。然后解压、编译,再将编译好的文件压缩到一个软件包中,通常,所得到的这个软件包文件就是一个以 .pkg.tar.gz 结尾的文件,例如:foo.pkg.tar.gz.
事实上,它不仅仅是一个 gzip 压缩过的 tar 档案文件('tarball'),它含有:
- 要安装的文件
- .PKGINFO: 包含 pacman 要处理的软件包,依赖性文件等所有的元数据。
- .FILELIST: 该文件记录了档案中所有文件的列表。它被用于反安装软件包,或检查冲突文件。
- .INSTALL: 该文件用在安装/升级/刪除的阶段之后执行命令(仅当 PKGBUILD 中指定时,该文件才会存在)
因为 pacman 能管理 tar.gz 软件包, 所以用 ABS 创建的 ***.pkg.tar.gz 就能轻易被安装或刪除了。
什么是 PKGBUILD 文件,其內容是什么?
前面解释过了 PKGBUILD 文件,它记录了一个软件包的元数据。它是一个文本文件。这里是一个例子:
# $Id: PKGBUILD,v 1.12 2003/11/06 08:26:13 dorphell Exp $ # Maintainer: judd <jvinet@zeroflux.org> # Contributor: Judd Vinet <jvinet@zeroflux.org> pkgname=foo pkgver=0.99 # note: if the pkgver had been '0.99-10' then use an underscore, i.e. '0.99_10' pkgrel=1 pkgdesc="short description of foo" arch=(i686 x86_64) url="http://www.foo.org" license=('GPL') groups= provides= depends=('qt' 'python') makedepends=('guile') conflicts=('yafoo') replaces=('mffoo') backup=('etc/foo/foo.conf') install=('foo.install') source=(http://www.foo.org/download/$pkgname-$pkgver.tar.gz) md5sums=('2c0cca3ef6330a187c6ef4fe41ecaa4d35175bee593a7cc7d6205584a94d8625') build() { cd $startdir/src/$pkgname-$pkgver ./configure --prefix=/usr make || return 1 make prefix=$startdir/pkg/usr install }
现在让我们来逐条解释一下:
- # abc ... : 这是注释文字
- # $Id: PKGBUILD,v ...: 该软件包的 cvs 标签 (从 archlinux-cvs 系统创建)
- # Maintainer: 在官方软件包库中负责此软件包的维护人
- # Contributor: 第一个写出此软件包的PKGBUILD 文件的人
- pkgname: 软件包名称
- pkgver: 软件包的版本号
- pkgrel: 此 Arch 软件包的释出号。它不同于版本号。当PKGBUILD 文件有改动时,释出号就改变了。这种情況有多各原因,例如你为某事开启了编译时支援。
- pkgdesc: 软件包的简明描述。这也是你浏览package database时会见到的。
- arch: 表明它在哪种架构下构建和工作的,软件包移植的细节可参閱Arch64_FAQ。
- url: 软件包的主页 (当你在软件包数据库中点击包的时候,就能出现了)
- license: 基于哪种软件包发布许可
- groups: 这一条用于为软件包分组;例如当你要安装 KDE 时,它就会安装属于 KDE 软件包组的所有软件包。
- provides: 如果一个软件包也提供了其它包的安装,那就使用它。例如,kernel-scsi 也提供了 kernel 的软件包。
- depends: 它列出了软件包运行时的依赖软件包 (必须有这些软件包才能正常工作)
- makedepends: 在构建软件包时需要的依赖性软件包,不过一旦已经构建好的,就不再需要了。
- conflicts: 这些包不能被同时安装。这里 foo 跟 yafoo (另外一个 foo) 有冲突。它们不能共存。
- replaces: 新软件包代替了旧的。这里, mffoo (第一个 foo) 不再受到支持了,被 foo 所代替。
- backup: 当刪除软件包时,用哪个文件作为备份文件(如 file.pacsave) 。
- install: 指定一个特別安装脚本,它将被包含在软件包中(必须跟 PKGBUILD 在同一个目录下)
- source: 它指定了从何处下载该软件包的源代码包。它可以在本地电脑上,也可以是从 "http" 或 "ftp" 上取得的。它用 pkgver 来命名,以免每次源码包变动时,源码的名称也要跟着变化。
- md5sums: 计算源代码包的 md5 值,以检查完整性。
现在来解释一下函数:
- build: 构建一个软件包时所需的所有动作(稍候本文将作更详细的说明)
正如所见,PKGBUILD 文件含有包管理器可能需要的所有信息,它是 pacman 和 abs 的核心。
还会有些安装文件。这个 PKGBUILD 指定了 'foo.install' 作为软件包的安装文件。这是例子:
post_install() { /bin/true } post_upgrade() { /bin/true } pre_remove() { /bin/true } op=$1 shift $op "$@"
其中的函数说明如下:
- post_install: 文件装完后运行此脚本。它可接受一个变量:
- 软件包版本
- post_upgrade: 文件升级完后运行此脚本。它可接受两个变量:
- 新软件包版本
- 旧软件包版本
- pre_remove: 此脚本运行于刪除文件前(例如停止了一个守护进程)。它可接受一个变量:
- 软件包版本
最后那三行是每一个安装文件都必需的,以便安装文件正常运行。
构建函数的解释
那么来看看上面例子中用到的 ABS 的构建函数。注意 build 一节:
build() { cd $startdir/src/$pkgname-$pkgver ./configure --prefix=/usr make || return 1 make prefix=$startdir/pkg/usr install }
发生了什么:
- 进入源代码包的解压目录:
cd $startdir/src/$pkgname-$pkgver
- 配置软件包,并告诉它安装到
/usr
这个目录下:
./configure --prefix=/usr
- 编译
make || return 1
- 软件包先被安装到
$startdir/pkg/usr
而不是/usr
下,以便 pacman 能控制这些文件。
make prefix=$startdir/pkg/usr install
我们想要做的是构建这个软件包,而不是去安装它。所以我们告诉 make
将所有的文件放到指定目录下面 $startdir/pkg/usr
,而不是安装到标准的位置 /usr
。
这样一来, makepkg 就能查看到这个软件包要安装哪些个文件了,并将其压缩成 Arch 软件包。
注意: 有时候,Makefile
中并未使用 prefix
;经常是用了 DESTDIR
。如果此软件包是用 autoconf/automake 来构建的,就用 DESTDIR
。这是在手冊中 详细说明了的。检查一下生成的 filelist
是否比平常小很多,如果是这样的话,尝试用 make DESTDIR=$startdir/pkg install
来构建。如果不能正常工作,那就要深入研究一下安装命令了,它们位于 "make <...> install=
" 中。