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被移動到另一個倉庫之前的包,只需查看日誌,找到移動之前的日期或版本即可。