軟件開發的最終目標就是要給用戶用,而在把軟件發佈給用戶前,我們一般會先製做一個安裝包,這樣用戶在使用我們的軟件前就能輕鬆的把軟件安裝到系統上,這篇文章我就介紹在Linux下製做RPM安裝包和在Solaris下製做PKG安裝包的方法。
RPM安裝包的製做方法
RPM(RPM Package Manager)是一個開放的包管理器,它使用戶可以從源碼構建一個二進制的軟件發行包和利用補丁包給軟件打補丁。RPM包非常靈活易用,因此被作爲很多linux發行版的默認軟件安裝包。
創建一個RPM安裝包是件很容易的事,特別是當你可以獲得軟件的源代碼包的時候。下面介紹怎麼製做一個RPM軟件安裝包,在繼續之前,我們假設你已經知道怎麼從源代碼安裝一個軟件包。
製做一個RPM軟件安裝包有以下幾個步驟:
(1)獲得軟件的源代碼包
(2)如果你自己修改了軟件,那麼給它做一個補丁
(3)編寫一個包含軟件包信息的spec文件
(4)確保軟件被正確的安裝到適當的位置
(5)創建RPM安裝包
從上面的幾步我們可以看到,製做一個RPM包最主要的就是第三步編寫一個spec文件,下面介紹怎麼編寫這個spec文件。一個spec文件分成下面幾個小節
一、前言(preamble)
當用戶查詢軟件包信息的時候,RPM程序會打印出前言包含的信息。這一小節包含的信息有軟件包的名稱、功能描述、版本號、發行號和類型等信息。
二、準備(preparation)
從prep節開始是創建一個軟件包要做的實際工作。故名思意,這一小節所做的都是一些必須的準備工作,它的內容就像一個普通的shell腳,爲了使工作更容易,這一小節提供了兩個可以使用的宏,一個是解壓tar文件,並把當前工作目錄設置爲源代碼目錄,另一個是給源碼打補丁。
三、創建(build)
就像prep小節一樣,build的內容也是一個普通腳本,這一小節包含的是怎麼編譯源代碼,它可以是一個簡單的make命令或者一些更復雜的編譯命令。因爲現在的大多數軟件都使用make編譯,所以這一小節沒有提供宏。
四、安裝(install)
install小節同樣也是一個腳本,它提供一些安裝軟件包的命令,如果源代碼的makefile文件提供有make install命令,這一節你可以簡單的包含一個make install命令,否則你就得提供一些像cp, mv或者install之類的命令集。
五、驗證(verify script)
這一小節包含一個驗證軟件包的腳本,驗證軟件包不屬於RPM的能力範圍。
六、清除(clean)
這一小節包含一個編譯好以後用於清除無用信息的腳本。這一腳本很少會用到,因爲在大多數環境下,RPM會做好這些工作。
七、文件列表(file list)
這一小節包含一份文件列表,它們是組成RPM包的所有文件,當你用rpm -qpl 命令查看軟件包的時候就會得到這一份文件列表。在這一小節也有幾個宏可以用,它們指出哪些文件是文檔,哪些是配置文件,哪裏是目錄等。
八、維護日誌(changelog)
這一小節記錄了軟件包的維護日誌。
spec文件有一個命名規則,其文件名由以下幾部份組成:
軟件包名-版本號-發行號.spec
下面我們舉一個簡單的spec文件,然後再來說明各部分的意思。文件如下:
Summary: GNU readline library
Name: readline
Version: 5.1
Release: 1
Copyright: GPL
Group: Library
Source: ftp://172.16.100.81/soft/readline-5.1.tar.gz
URL: http://www.gnu.org/index.html
Distribution: GNU Project
Vendor: GNU
Packager: Yan Dingcheng <[email protected]>
%description
The GNU readline library gets a line from user with editing.
%prep
%setup
%build
./configure --prefix=/opt/%{name}
make
%install
make install
%files
/opt/%{name}/lib/libhistory.a
/opt/%{name}/lib/libhistory.so
/opt/%{name}/lib/libhistory.so.5
/opt/%{name}/lib/libhistory.so.5.1
/opt/%{name}/lib/libreadline.a
/opt/%{name}/lib/libreadline.so
/opt/%{name}/lib/libreadline.so.5
/opt/%{name}/lib/libreadline.so.5.1
/opt/%{name}/include/readline/chardefs.h
/opt/%{name}/include/readline/history.h
/opt/%{name}/include/readline/keymaps.h
/opt/%{name}/include/readline/readline.h
/opt/%{name}/include/readline/rlconf.h
/opt/%{name}/include/readline/rlstdc.h
/opt/%{name}/include/readline/rltypedefs.h
/opt/%{name}/include/readline/tilde.h
/opt/%{name}/info/dir
/opt/%{name}/info/history.info
/opt/%{name}/info/readline.info
/opt/%{name}/info/rluserman.info
/opt/%{name}/man/man3/history.3
/opt/%{name}/man/man3/readline.3
%changelog
* Wed Jan 31 2007 <[email protected]>
+ create package
前言
Summary:這一行文字對軟件包進行簡短描述
Name:軟件包的名字
Version:軟件包的版本號,這裏必須是你計劃要使用的RPM文件版本號
Release:軟件包的發行號,這裏必須是你計劃要使用的RPM文件發行號
Copyright:軟件包的版權
Group:軟件包的分組,這裏定義怎麼打包軟件包
Source:軟件包的來源,當你想再次獲取該軟件包或者查看它是不是有更新的版本的時候,這一行就很有用了。
URL:URL與Source不一樣的地方就是,Source提供的是源代碼的文件名,URL提供的是指向軟件包文檔的鏈接。
Distribution:指明軟件包是屬於哪個產品的一部份。
Vendor:軟件包的生產廠商。
Packager:打包的組織或者個人。
discription:軟件包功能的一個詳細描述。
準備(prep)
%setup宏:解壓源代碼包並把當前工作目錄設置到源代碼目錄。%setup宏做的主要工作類似於下面兩條命令:
tar zxvf 源代碼包文件名
cd RPM包名-版本號
所以如果你的源代碼包解壓以後的目錄組成不是“RPM包名-版本號”的話,在這裏使用%setup宏就會出問題。
創建(build)
這裏使用了一個configure和make命令組合
安裝(install)
這裏使用了make install命令,因爲makefile裏有install標籤了,所以就用它,簡便。
文件列表(files)
這裏是一個文件列表,列出的文件就是創建以後的RPM包將要包含的文件,文件路徑要求是一個絕對路徑,利用RPM命令安裝這個軟件包以後,這些文件將會按照這裏指定的路徑安裝到系統中。在創建RPM包之前必須保證這裏指定的文件在系統中都能找到,不然創建RPM包將會出錯。所以如果是爲了學習怎麼編寫一個spec文件的話,就像我上面那樣,把軟件安裝到一個乾淨目錄下(比如/opt),這樣不會影響系統的正常工作。
這個文件列表目前還沒有什麼好的工具能夠自動生成,因爲RPM沒法知道執行make install的時候到底安裝了哪些文件。有的人建議用一個find命令來查找到底安裝了哪些文件,但是我覺得這未必會有用。我一般是在configure的時候使用configure --prefix=/opt/package_name指定一個乾淨目錄,先把軟件安裝到該目錄下,然後查看軟件包安裝後都有哪些文件,通過這些文件生成一個文件列表,然後再使用configure命令重新安裝一次軟件包,這次把軟件包安裝到系統中,比如是/usr或者/usr/local目錄下,然後把文件列表中的目錄前輟改成相應的目錄前輟(比如/usr或者/usr/local)就可以了。
維護日誌(changelog)
維護日誌是一些對軟件包維護的日誌記錄,其中包含有一個時間信息,它有指定的格式:Wed Jan 31 2007。按順序是 星期 月 日 年。
編寫好spec文件以後在redhat linux下把軟件源碼包放到/usr/src/redhat/SOURCE目錄下(如果是suse linux把軟件源碼包放到/usr/src/packages/SOURCE目錄下),然後把spec文件放到/usr/src/redhat/SPECS目錄下(如果是suse linux放到/usr/src/packages/SPECS目錄下),最後轉到/usr/src/redhat/SPECS目錄下執行如下命令:
rpmbuild -ba spec文件名
執行成功以後會生成三個RPM文件並打印信息如下:
Wrote: /usr/src/redhat/SRPMS/readline-5.1-1.src.rpm
Wrote: /usr/src/redhat/RPMS/i386/readline-5.1-1.i386.rpm
Wrote: /usr/src/redhat/RPMS/i386/readline-debuginfo-5.1-1.i386.rpm
我們可以看到在RedHat系統下生成的RPM文件被放到/usr/src/redhat/RPMS/i386和/usr/src/redhat/SRPMS目錄下,如果打包的RPM包是爲了i586架構打的,那麼RPM包會被放到i586目錄下。其中readline-5.1-1.src.rpm是源碼包,可以通過命令
rpmbuild --rebuild readline-5.1-1.src.rpm
重新生成二進制的RPM包。
Solaris系統下製做軟件安裝包的步驟
1、下載軟件源碼包
2、編譯、安裝軟件,在configure的時候通過—prefix選項把軟件安裝到一個乾淨目錄(空目錄,比如/opt/mysoft)下,下面的步驟假設已經把軟件安裝到/opt/mysoft目錄下。
3、#cd /opt/mysoft
4、#find . -print | pkgproto > prototype
這個命令會在你的當前目錄下建立一個prototype文件,在這個文件里加入下面一行
i pkginfo=./pkginfo
並將文件裏的用戶名和組名(比如root)改成bin,不然在用pkgadd安裝時將無法正常安裝軟件包。下面是一個完成的prototype文件例子。
i pkginfo=./pkginfo
d none include 0755 bin bin
d none include/libnet 0755 bin bin
f none include/libnet/libnet-asn1.h 0644 bin bin
f none include/libnet/libnet-functions.h 0644 bin bin
f none include/libnet/libnet-headers.h 0644 bin bin
f none include/libnet/libnet-macros.h 0644 bin bin
f none include/libnet/libnet-structures.h 0644 bin bin
f none include/libnet/libnet-types.h 0644 bin bin
f none include/libnet.h 0644 bin bin
d none lib 0755 bin bin
f none lib/libnet.a 0644 bin bin
5、在/opt/mysoft下建立pkginfo文件,格式如下
PKG="libnet"
NAME="libnet"
ARCH="i386"
VERSION="1.00"
CATEGORY="library"
VENDOR="Guangdong linux technology center"
EMAIL="[email protected]"
PSTAMP="gdlc"
BASEDIR="/usr/local"
CLASSES="none"
這個文件的各項含義如下:
PKG=你所選擇 package 目錄的名稱 (軟件包的名稱)
NAME=程序名稱
ARCH=作業系統的版本(如sparc, i386等)
VERSION=軟件的版本編號
CATEGORY= 這個軟件的類型(如library,application)
VENDOR=開發這個軟件的公司
EMAIL=e-mail 地址
PSTAMP=是誰作這個軟體
BASEDIR=軟件要安裝到的目錄(如/usr/local)
CLASSES=只要寫 none 就好了
6、執行下面的命令
#pkgmk -r `pwd`
執行這個命令之後,會在/var/spool/pkg目錄下建立一個package的目錄(按上面的例子會建立一個libnet目錄),可以把這個用tar和gzip打包壓縮起來,安裝時只要解壓成libnet目錄,到libnet目錄執行命令
#pkgadd -d .
就可以了。這樣一個軟件安裝包的製做就完成了。
7、也可以把軟件安裝包轉換成datastream格式。步驟如下
(1)#cd /var/spool/pkg
(2)#pkgtrans -s `pwd` /tmp/libnet-1.00
執行上面的命令後會在/tmp目錄下產生libnet-1.00這個datastream格式的軟件安裝包,可以用下面的命令來安裝datastream格式的安裝包:
#pkgadd -d libnet-1.00
下面是對pkgtrams的補充說明
所謂的file system格式,就是一般的檔案格式,如果同時有好幾個package在該目錄下,使用”pkgadd -d .”就會列出所有的 package。而datastream的格式,則是將整個file system做成一個檔案,有點類似tar的作用。使用datastream格式的package來安裝時必須指定文件名,不能用“.”來指定,而且每次只能安裝一個package,但好處是只需要一個文件而己。要把file system的格式轉換成datastream的格式可以用下面的命令:
#pkgtrans -s `pwd` dest
要把datastream格式轉換成file system格式可以用下面的命令:
#pkgtrans source dest