Arch 构建系统
ABS(Arch Build System)指的是Arch的构建系统。这是一种从源代码编译软件的类 ports 系统。在Arch中,pacman 专门管理二进制软件包(包括那些由ABS创建的);而ABS则是一系列工具,负责把源代码编译成可安装的.pkg.tar.xz
软件包。
Ports 是 *BSD 使用的一种系统,可以自动下载源代码、解压缩、打补丁、编译和安装软件。一个“port”仅仅是指用户电脑上的一个目录,该目录根据即将安装的软件来命名,它包含一些能指导源码的下载和编译安装的文件。Ports系统让你只需在port目录下运行make
或 make install clean
就能安装你想要的软件。
ABS 的概念与Ports相似。ABS的一部分是SVN仓库或等价的Git仓库,这个仓库中每个目录与Arch Linux的官方软件包一一对应。每个目录中并不包含二进制包或源代码,而是包含一个PKGBUILD文件(有时也会有其它文件)。在有PKGBUILD
文件的目录里运行makepkg命令,系统就会在目录中下载软件的源代码、编译并打包在build文件夹里。然后就可以通过pacman进行安装或升级了。
ABS概览[编辑 | 编辑源代码]
'ABS'可以作为一个总括性术语来使用,因为它包含并依赖于若干其他部件。因此,尽管从严格意义上来讲并不精确,ABS可指代包含以下工具的完整工具集:
- makepkg
- ABS的 shell 命令工具,读取 PKGBUILD,下载源码,编译并创建
.pkg.tar.gz
或.pkg.tar.xz
包(拓展名由makepkg.conf
中的PKGEXT
指定)。makepkg也可以用来从AUR或第三方代码构建你自己的自定义软件包。参考Creating packages。
- Pacman
- pacman是完全独立的一个系统,但是它在安装或移除软件包、解决依赖关系时都是必需的。它被 makepkg 调用或者被手动执行。
- AUR
- ArchLinux社区的用户维护的软件仓库独立于ABS,包含不受支持的PKGBUILD文件。它们同样可以可以通过ABS的makepkg工具来编译并打包成可安装软件。与只是一个git仓库的 ABS 树不同,AUR 是一个有着精致外观及多种交互功能的网站界面。它包含成千上万的用户贡献的 PKGBUILD,来提供Arch官方仓库中没有的软件。如果需要编译官方 Arch 树之外的软件包,AUR 中已经存在的可能性非常大。
仓库树[编辑 | 编辑源代码]
core, extra和testing 官方软件仓库可从packages 仓库checkout. 而community和multilib在community仓库。
每个包有各自的子目录,其中又有repos
和trunk
目录。repos
又进一步按仓库名(如core)和架构细分。repos
里的PKGBUILD和其它文件用来构建官方包。trunk
里的文件是给开发者用的,并最终复制到repos
中。
例如,acl包的目录结构是这样的:
acl acl/repos acl/repos/core-x86_64 acl/repos/core-x86_64/PKGBUILD acl/trunk acl/trunk/PKGBUILD
源代码并不直接包含在ABS目录中,而是构建时从PKGBUILD
里指定的源代码URL下载。
我为什么要用ABS[编辑 | 编辑源代码]
常见的使用 ABS 的场景包括:
- 需要编译或重新编译软件包
- 从源代码编译Arch官方源里没有的软件(详情请参照创建软件包)
- 定制现有的软件包以满足你的特定需求(比如开启或禁用相关选项、打补丁)
- 用你的编译器的flags重新构建整个系统,“就像FreeBSD那样”
- 干净地编译安装你自己定制的内核。(参照内核编译(简体中文))
- 使内核模块(比如某些显卡驱动)在你定制的内核下正常工作
- 修改 PKGBUILD 中的版本就能方便地编译和安装新的、老的、beta 或者开发版本的 Arch 软件包
使用 Arch Linux 不一定会用到 ABS,但 ABS 确实可以自动化进行许多源码编译工作。
如何使用 ABS[编辑 | 编辑源代码]
要想获取从源代码构建特定软件包所需的PKGBUILD文件,可以使用 Svn 或 Git 方式。
通过 Git 获取 PKGBUILD 源码[编辑 | 编辑源代码]
使用 asp[编辑 | 编辑源代码]
先安装安装软件包 asp包。Asp 是通过Git接口获取Arch Linux的软件包的源代码文件的工具。另外可以参考Arch Linux BBS论坛帖子[1]。
开始使用此工具::
$ asp export pkgname
这个命令会将 pkgname 加入 asp
追踪列表,并将 pkgname 当局的编译源文件下载到工作目录的 pkgname 下,并自动执行
$ asp update pkgname
和
$ asp export pkgname
后续也可以选择手动执行这两个命令。编译源文件是指 PKGBUILD 和其它一些需要的密码文件等 ABS 必须的文件,而不是软件包的 C 或 Python 等源代码.
要克隆 git 仓库并切换到最新版本:
$ asp checkout pkgname
这个命令不光会下载当前编译文件,还会下载整个版本历史,可以通过 git 命令查看之前的版本及变更历史。
要更新 asp
追踪的编译文件,可以执行 asp update
. 在 checkout
出的仓库目录执行 git pull
会更新仓库到最新版本。
更多信息请阅读 asp(1)。
直接使用 git[编辑 | 编辑源代码]
只下载某个分支的文件:
$ git clone --branch branch/package --single-branch https://github.com/archlinux/svntogit-packages.git
要复制 apache 分支的文件:
$ git clone --branch packages/apache --single-branch https://github.com/archlinux/svntogit-packages.git
使用 SVN 获取 PKGBUILD 源码[编辑 | 编辑源代码]
安装subversion包包。
checkout仓库[编辑 | 编辑源代码]
要checkout core, extra,和testing 官方软件仓库:
$ svn checkout --depth=empty svn://svn.archlinux.org/packages
要checkout community和multilib仓库:
$ svn checkout --depth=empty svn://svn.archlinux.org/community
两条命令都只是创建了空目录,但它知道这是SVN checkout目录。
Checkout软件包[编辑 | 编辑源代码]
在刚才checkout的SVN仓库(packages或community)中执行:
$ svn update package-name
这条命令把指定的包同步到你的checkout目录。以后在顶层目录执行svn update时,这个包也会更新。
如果指定的包不存在,svn不会产生警告,只是显示类似"At revision 115847"而不创建文件。出现这种情况时:
- 检查软件包名的拼写
- 检查包是不是被移到了另一个仓库 (例如从community到主仓库)
- 到 https://archlinux.org/packages 检查这个包是不是从另一个基础包构建的 (例如python-tensorflow包是在tensorflow包 PKGBUILD里构建的)
如果想在最新的版本进行编译,定期执行:
$ svn update
构建软件包[编辑 | 编辑源代码]
关于如何配置makepkg来从PKGBUILD构建软件包,请参考makepkg#配置。
把PKGBUILD所在目录复制到新的位置。在新目录按需要进行修改。 并按照makepkg#使用来构建和安装软件包。
技巧[编辑 | 编辑源代码]
保留修改过的软件包[编辑 | 编辑源代码]
Pacman 进行升级时会将修改后的软件包升级到仓库中的最新版本,可以通过下面方式避免这个行为:
在 PKGBUILD 中将软件包加入 modified
组.
PKGBUILD
groups=('modified')
然后将此组加入/etc/pacman.conf
的 IgnoreGroup
:
/etc/pacman.conf
IgnoreGroup = modified
当系统生升级发现官方仓库中有新版本时,pacman会显示软件包因为在IgnoreGroup中而被忽略的提示,这时需要从 ABS 编译更新的软件包以防止部分升级。
Checkout旧版本软件包[编辑 | 编辑源代码]
在checkout的SVN仓库目录 (即"packages"或"community") 中查看日志:
$ svn log package-name
从历史记录中找出要checkout的版本。例如要checkout版本r1729
:
$ svn update -r1729 package-name
已存在的package-name目录会更新成指定版本。
也可以指定一个日期,如果当天没有对应版本,svn会找出之前的最近版本。下面的例子checks out了2009-03-03的版本:
$ svn update -r'{20090303}' package-name
要checkout被移动到另一个仓库之前的包,只需查看日志,找到移动之前的日期或版本即可。