應用程式打包技術之三(rpm 篇)
應用程式打包技術之三(rpm 篇)
資料來源: http://yangwenbo.com/articles/packaging-3-rpm.html
rpm 是 RedHat 系 Linux 使用的套裝軟體格式。流行的 Linux 發行版本:Fedora, RHEL, OpenSUSE, Oracle 包括國產的紅旗 Linux,都採用 rpm 來管理套裝軟體。
我不是很喜歡 rpm 套裝軟體格式,原因主要有兩個,一個是它的依賴關係很難處理,另一個是控制檔比較複雜。但是 rpm 包有著非常廣泛的應用,也是一個提高生產力的重要工具。
像前一篇文章提到的一樣,checkinstall 也可以用來打 rpm 包,但我不是很熟悉這個軟體。這裡我僅僅介紹如何使用原始的
rpm(rpmbuild) 工具來打 rpm 套裝軟體。
和前面 deb 包使用
fakeroot 一樣,rpmbuild 也是利用沙箱的方式來構建套裝軟體,除了控制檔比較繁瑣,過程可能還更自動一些。構建 rpm 包的工作目錄預設是 /usr/src/redhat,如果您在 Debian 下安裝了 rpm 這個套裝軟體,它可能是 /usr/src/rpm。您可以使用 rpm –eval %_topdir 查看自己的 rpm 工作目錄。
$ tree `rpm –eval %_topdir`
/usr/src/redhat
|– BUILD
|– RPMS
| |– athlon
| |– i386
| |– i486
| |– i586
| |– i686
| `— noarch
|– SOURCES
|– SPECS
`— SRPMS
我們可以看到,/usr/src/redhat/ 下有幾個子目錄:SOURCES 用來存放原始程式碼包,SPECS 用來存放 spec 控制檔,BUILD 用來解壓原始程式碼包和構建軟體,RPMS 裡存放的是打好的二進位應用程式 RPM 包,SRPMS 裡存放的是打好的原始程式碼 RPM 包。但是,我們應該知道 _topdir 是可以在 spec 檔中修改的,否則我們只能用 root 才能在預設的工作目錄 /usr/src/redhat 下創建檔和執行命令。我們可以先把工作目錄樹拷貝到使用者自己的目錄中:
$ cp -r /usr/src/redhat ~/rpm
這樣,我們就可以在使用者目錄 ~/rpm 下打 rpm 包了。打 rpm 包之前的準備工作只有兩件:1. 準備好原始程式碼包並放置在 SOURCES 目錄下;2. 準備好 spec 控制檔並放在
SPECS 目錄下。如何打原始程式碼包我們已經在 《原始程式碼篇》中介紹過,下面我們主要來介紹 spec 檔的格式。下面是一個實例 spec 檔。
$ more ~/rpm/SPECS/casnet.spec
%define _topdir /home/solrex/rpm
Name: casnet
Version: 1.3
Release: 1
License: GPL
Packager: Solrex Yang
Summary: CASNET Client
Group: Network
Source: %{name}-%{version}.tar.gz
Prefix: /usr
%description
CASNET is a gui client for ip gateway of GUCAS(Graduate University of Chinese
Academy of Sciences), which is written in Python and PyGtk.
%prep
%setup -q
%build
%install
make -e PREFIX=%{prefix} install
%files
%{prefix}/bin/casnetconf
%{prefix}/bin/casnet
%{prefix}/bin/casnet-gui
%{prefix}/share/casnet/casnetconf.py
%{prefix}/share/casnet/casnet.py
%{prefix}/share/casnet/casnet-gui.py
%{prefix}/share/casnet/pics/*.png
%{prefix}/share/applications/casnet.desktop
%{prefix}/share/icons/casnet.png
我們可以看到,spec 檔與 deb 包的 control 檔有很多相似之處:Name, Version, Release,
License, Packager, URL
是軟體的名稱、版本、小版本、使用的協定、維護者和網址;Summary
和 %description 是軟體的資訊;Group 是軟體所歸類別。剩下的就有些不同了:Source 是指軟體的原始程式碼包名稱,rpm 會到 SOURCES 目錄下找這個包;Prefix 是軟體的預設安裝位置;%prep、%build、%install
下分別是軟體的預處理、編譯和安裝命令;%files 是所有需要被打包進去的檔。
因此,作者需要將 spec 檔中的各個域填寫正確。%prep 下的 %setup 宏一般是用來將原始程式碼 tar 包釋放到 BUILD 目錄下;%build
下可以添加 %configure 宏和 make 命令,如果您的軟體需要編譯的話;%install 下是您的安裝命令;%files 下是您程式運行所需要的全部檔,其路徑即為您安裝完軟體後它應該在的位置。%{name} 可以用來指代 Name: 域的內容,%{version } 指代 Version: 域的內容,以此類推。
需要注意的是,rpmbuild 使用
BUILD/%{name}-%{version} 作為您的原始程式碼包釋放後的目錄,進入其進行編譯。因此當您使用 tar 打原始程式碼包時,tar 包的頂層目錄名應該為 %{name}-%{version} 而不是僅僅是 %{name},比如:
$ tar czvf casnet-1.3.tar.gz casnet-1.3
$ mv casnet-1.3.tar.gz ~/rpm/SOURCES
現在我們在 ~/rpm/SOURCES 下有了 casnet-1.3.tar.gz,在 ~/rpm/SPECS 目錄下有了 casnet.spec,那麼我們就可以使用下面的命令生成 rpm 包了。如果您的安裝位置 Prefix 選擇的是一個系統目錄,比如 /usr, /usr/local 之類,您也許需要使用 root 許可權來運行 rpmbuild 命令。
$ rpmbuild -ba ~/rpm/SPECS/casnet.spec
這樣我們就能在 ~/rpm/RPMS/i386 目錄下獲得我們生成的 rpm 套裝軟體了。rpmbuild 命令的執行過程是這樣的:首先根據 spec 檔定位原始程式碼包,然後將原始程式碼包釋放到 BUILD 目錄下,使用 spec 檔中給出的命令編譯和安裝,然後將 spec 中列的檔提取出來,按照包資訊打出來 rpm 包。
我們可以使用 rpm -qpi 命令來查看 rpm 包的資訊,rpm -qpl 命令來查看 rpm 包所包含的文件列表:
$ rpm -qpi
~/rpm/RPMS/i386/casnet-1.3-1.i386.rpm
Name :
casnet
Relocations: /usr
Version :
1.3
Vendor: (none)
Release :
1
Build Date: Thu 26 Feb 2009 08:03:50 PM CST
Install Date: (not
installed)
Build Host: laptop
Group :
Network
Source RPM: casnet-1.3-1.src.rpm
Size :
40883
License: GPL
Signature : (none)
Packager : Solrex Yang
URL :
http://share.solrex.org/casnet/
Summary : CASNET Client
Description :
CASNET is a gui client for ip
gateway of GUCAS(Graduate University of Chinese
Academy of Sciences), which is written in Python and PyGtk.
$ rpm -qpl ~/rpm/RPMS/i386/casnet-1.3-1.i386.rpm
/usr/bin/casnet
/usr/bin/casnet-gui
/usr/bin/casnetconf
/usr/share/applications/casnet.desktop
/usr/share/casnet/casnet-gui.py
/usr/share/casnet/casnet.py
/usr/share/casnet/casnetconf.py
/usr/share/casnet/pics/casnet.png
/usr/share/casnet/pics/offline.png
/usr/share/casnet/pics/online.png
/usr/share/icons/casnet.png
如果您想瞭解更詳細的內容,您可以進一步參考 Jake’s RPM Build Tutorial 這篇文章。