天天看點

精通RPM之--制作篇(上)

制作篇(上)

要想制作一個RPM格式的軟體包,需要編寫軟體包描述檔案。其标準命名格式為:軟體名-版本号-釋出号.spec,這個檔案,較長的描述了有關該軟體包的諸多資訊,如軟體名,版本,類别,說明摘要,建立時要執行什麼指令,安裝時要執行什麼操作,以及軟體包所要包含的檔案等等。有了這個檔案,RPM就可以制作出相應的包裹檔案來。

下面以我制作小趙編輯器LZE的軟體包(lze-6.0-2.i386.rpm)為例,詳細說明一下軟體包描述檔案的書寫。其描述檔案為lze-6.0-2.spec,該檔案内容如下:(用nl -ba指令列出,每行開頭的數字為所在行在檔案中的行号)

1 # 檔案名稱: lze-6.0-2.spec

2 # 檔案功能: lze軟體包描述資訊

3 # 檔案作者: 縱橫軟體制作中心雨亦奇 國防大學研究所學生二隊趙建利

4 # 修改時間: 2001.10.19

5

6 Name: lze

7 Version: 6.0

8 Release: 2

9 Summary: 小趙全螢幕中英文多視窗多功能編輯器(LINUX/UNIX系統适用)

10 Group: Applications/Editors

11 License: Share

12 Vendor: 縱橫軟體制作中心

13 Packager: 雨亦奇([email protected])

14 Source: http://zhsoft.myetang.com/lze-6.0-2.src.tgz

15 Prefix: /usr

16 Requires: /bin/sh

17 Provides: lze-edit

18

19 %description

20 小趙編輯器,是為使用SCO UNIX,LINUX多使用者系統的廣大使用者專門設計的全螢幕多窗

21 口中英文多功能編輯器。

22 它主要有以下十大特點:1.全螢幕菜單操作。2.顯示方式多樣。3.塊操作豐富。4.十

23 字制表功能強大。5.多視窗操作靈活自如。6.檔案操作功能齊全。7.解釋輸出功能獨具特

24 色。8.自帶中文輸入法(增強五筆和增強拼音),實用友善。9.十六進制編輯功能,如虎

25 添翼。10.即時翻譯,按到即譯。

26 總之,小趙編輯器會成為您在UNIX,LINUX系統上編制程式和書寫一般性文稿的好幫手。

27 它将在工作中助您一臂之力,輕松上陣,遊刃有餘!

28

29 %prep

30 echo "預處理腳本程式(prep)開始執行"

31 %setup

32

33 %build

34 echo "編譯連接配接腳本程式(build)開始執行"

35 make

36

37 %install

38 echo "安裝腳本程式(install)開始執行"

39 make install

40

41 %clean

42 echo "建包結束後清理腳本程式(clean)開始執行"

43

44 %pre

45 echo "安裝前執行腳本程式(pre)開始執行"

46

47 %post

48 echo "安裝後執行腳本程式(post)開始執行"

49

50 %preun

51 echo "解除安裝前執行腳本程式(preun)開始執行"

52

53 %postun

54 echo "解除安裝後執行腳本程式(postun)開始執行"

55

56 %veryfiscript

57 echo "軟體包校驗腳本程式(verifyscript)開始執行"

58

59 %triggerin -- xiuwu

60 echo "軟體包安裝時觸發腳本程式(triggerin)開始執行"

61

62 %triggerun -- yuntaishan < 2.0

63 echo "軟體包解除安裝前觸發腳本程式(triggerun)開始執行"

64

65 %triggerpostun -- dapubu

66 echo "軟體包解除安裝後觸發腳本程式(triggerpostun)開始執行"

67

68 %files

69 %defattr (-,root,root)

70 %config /etc/funkey.def

71 %config /etc/inputme.def

72 %doc /usr/doc/lze-6.0/README

73 %doc /usr/doc/lze-6.0/LICENSE

74 /usr/bin/lze

75 /usr/bin/lzeime.py

76 /usr/bin/lzeime.wb

77 /etc/wbzc.dat

78

79 %changelog

80 * Tue Aug 18 1998 雨亦奇

81 - 内置拼音,五筆輸入法

82 * Fri May 01 1998 雨亦奇

83 - 增加多視窗操作

84 * Mon Mar 24 1997 雨亦奇

85 - 增加塊操作指令

86

該描述檔案包括以下幾方面的内容:

一、注釋行

見第1-4行。

它以#号開頭,起注解作用,可幫助使用者了解所寫的内容,但對軟體包的生成不起任何作用。此檔案中,注釋行集中在檔案首部。實際上,它可位于描述檔案的任何位置。

二、檔案頭

見第6-17行。

檔案頭描述軟體包的基本資訊,它包含若幹個域,其中有必選的域,也有可選的域。一個域占用一行,其描述格式為:

域名 : 域值

注意: 域名不分大小寫,并且域值不能為空。

檔案頭必選域有以下六個:

1. Name :

此域定義軟體名。

2. Version :

此域定義版本号。僅當軟體較以前有較大改變時才增加版本号。注: 版本号中不能含減号(-)字元。

3. Release :

此域定義釋出号。若軟體較以前改變較小,則僅增加釋出号,不改變版本号。注: 釋出号中亦不能含減号(-)字元。

RPM利用上述的Name(軟體名),Version(版本号),Release(釋出号)及體系号來命名軟體包,如本例輸出的包裹檔案名為lze-6.0-2.i386.rpm。

4. Summary :

此域定義軟體包簡介,為一句話說明。

5. Group :

此域定義軟體所屬類别,詳見<<精通RPM之五--查詢篇>>,本例的Applications/Editors表示本軟體屬"應用/編輯器"類。

6. License :

此域定義軟體适用的許可證或版權規則。該域也可用Copyright(版權)來定義,二者同意。許可證具體有: GPL(通用公共許可證,自由軟體适用),BSD,MIT,Public Domain(公共域),Distributable(貢獻),Commercial(商業),Share(共享)等。

檔案頭可選的域包括如下幾類:

1. 基本資訊

1.1 Vendor :

此域定義軟體的供應商(銷售商)。

1.2 Distribution :

此域定義軟體所屬的發行版,這是軟體包制作者自己的分類。通常,一個發行版由若幹個軟體包構成。如我想做一個名為“熊貓'95”的發行版,則其中每個軟體包(如竹葉95)的描述檔案都應有這麼一行:

Distribution : 熊貓'95

1.3 Icon :

此域指定軟體包所用的圖示檔案名。此檔案為GIF或XPM格式,必須存放在RPM的%_sourcedir(源碼目錄)宏所訓示目錄下,預設為/usr/src/dist/SOURCES。RPM本身并不使用圖示,但它将圖示檔案内容存貯到包裹檔案中,安裝時亦存貯到RPM資料庫中。此圖示可被圖形界面的RPM包管理工具使用,用以改善界面效果,增加可視性。如下例訓示軟體包使用panda.xpm作為圖示:

Icon : panda.xpm

1.4 Packager :

此域定義打包者,亦即建立此軟體包的人或公司。書寫格式是:

打包者的名字 <電子信箱或相關網頁>

請參考描述檔案第13行。

1.5 Serial :

此域定義軟體序列号,也可使用域名Epoch。軟體序列号為一整數,由打包者指定,它應随着版本号的增加而不斷增加,并且始終保持數值的唯一。軟體序列号可被用來說明軟體包之間的依賴關系。下例指定軟體包序列号為4:

Serial : 4

或用:

Epoch : 4

1.6 URL :

此域定義包含打包軟體有關資訊的網頁位址。如:

URL : http://devplanet.fastethernet.net/gxedit.html

2. 依賴相關

依賴是RPM用來描述軟體包之間關系的。一個軟體包依賴的東西RPM稱作功能,它可以是真實存在的軟體包,也可以是虛拟的軟體包(虛包)。虛包沒有版本号。

依賴相關的域有:

2.1 Provides :

此域定義軟體包提供的功能,可重複多行。其描述格式為:

Provides : 功能1 [,功能2] ...

注: []所括為可選項,多個功能之間以逗号或空格分隔。

軟體包所提供的功能一般是以虛包形式存在的共享庫。當有多個軟體包均提供相同的服務時,常用虛包來表示其服務。如,一個郵件用戶端軟體允許使用者使用不同的看信方式(文本形式,HTML形式等),可以要求任何一個看信程式必須提供mail-reader虛包。這樣,看信程式的描述檔案應有這麼一行:

Provides : mail-reader

如此它才能被郵件用戶端使用。

2.2 Requires :

此域定義軟體包所需的功能,可重複多行。其描述格式為:

Requires : 功能1 [比較符1 [序列号1:]版本号1[-釋出号1]] [,功能2 [比較符2 [序列号2:]版本号2[-釋出号2]]] ...

其中: * []所括為可選項;

* 比較符可使用<(小于),>(大于),=(等于),>=(大于等于)或<=(小于等于);

* 序列号不選時,RPM預設為0;

* 功能之間的逗号可選,也可使用空格進行分隔。

例子:Requires: aaa, bbb >= 3.0, ccc < 2:5.0-1

注: 本例定義生成的包在安裝時需要系統有如下功能:

(1) aaa(系統中已安裝aaa包,或者已安裝軟體包中有軟體包提供aaa虛包);

(2) bbb包已安裝且版本要求大于等于3.0;

(3) ccc包已安裝且版本要求小于序列号為2,版本号為5.0且釋出号為1。

RPM在進行版本比較時,執行比較的順序是; 先版本号,再釋出号,最後比較序列号。通過比較,确定哪個版本較新,哪個版本較老。

2.3 Conflicts :

此域定義有哪些功能與本軟體包相沖突(不能共存)。此域亦可在描述檔案中書寫多次。其描述格式形同Requires域,為:

Conflicts : 功能1 [比較符1 [序列号1:]版本号1[-釋出号1]] [,功能2 [比較符2 [序列号2:]版本号2[-釋出号2]]] ...

其中: * []所括為可選項;

* 比較符可使用<(小于),>(大于),=(等于),>=(大于等于)或<=(小于等于);

* 序列号不選時,RPM預設為0;

* 功能之間的逗号可選,也可使用空格進行分隔。

舉個例子:

Conflicts : xxx=1:2.0 yyy>=3.0

注: 本例闡明生成的包沖突的功能有:

(1) 當系統中xxx包版本等于序列号為1且版本号為2.0時;(2) 當系統中yyy包版本大于等于3.0時。

*** 依賴關系的自動實作 ***

一般情況下,當RPM建立一個軟體包時,它要執行/usr/lib/rpm目錄下的兩個小程式。一個是find-requires,用于查找軟體包所需的共享庫,這些庫将以虛包的形式加入到該軟體包所需的功能(Requires)之中。另一個是find-provides,它用于查找軟體包所提供的共享庫,這些庫将以虛包的形式加入到該軟體包所提供的功能(Provides)之中。這兩個程式都是SHELL程式,代碼量雖小,但确實幫了軟體包制作者一個大忙--不必勞心費神地自己寫這樣的依賴關系了,因為程式均自動完成了。

下面三個域用于訓示RPM是否執行這兩個程式。

2.4 Autoreq :

此域用于訓示RPM是否自動查找軟體所需的共享庫。僅當域值為no或0時,RPM不執行find-requires程式,否則均執行該程式。

2.5 Autoprov :

此域用于訓示RPM是否自動查找軟體提供的共享庫。僅當域值為no或0時,RPM不執行find-provides程式,否則均執行該程式。

2.6 Autoreqprov :

此域用于訓示RPM是否自動查找軟體所需的共享庫與其提供的共享庫。僅當域值為no

或0時,RPM不執行find-requires與find-provides兩個程式。此域相當于同時設定Autoreq

與Autoprov域值為指定之值。

注: 上述三個域在描述檔案中,它們之間因為順序的不同而結果會有所不同,一般以最後一個為準。如:

Autoreq : yes

Autoreqprov : no

Autoprov : yes

注: 本例雖然第一行允許執行find-requires,但第二行又不允許find-requires與find-provides兩個程式運作,而第三行允許find-provides運作,是以依照執行順序,結果為不允許執行find-requires,而允許執行find-provides。

又如:

Autoreq : no

Autoreqprov : yes

Autoprov : no

注: 本例的結果為允許執行find-requires,而不允許執行find-provides。

3. 系統相關

RPM制作軟體包時,可以為其指定适用的CPU體系或作業系統,也可為其指定不适用的CPU體系或作業系統,這樣,當RPM發現目前的CPU體系或作業系統與軟體包要求的不相容時,将中止軟體包的制作。RPM預設的目前CPU體系由宏%_arch定義,一般為i386。RPM預設的目前作業系統由宏%_os定義,一般為linux。讀者可以通過檢視/usr/lib/rpm/macros宏定義檔案得到。

下面四個域說明軟體包的适用範圍:

3.1 Excludearch :

此域定義軟體包不适用的體系。RPM可選的體系名請參見/usr/lib/rpm/rpmrc檔案中的arch_canon項目。

軟體包不适用于某個體系,可能有兩方面的原因。一是該軟體還沒有移植到所定義的體系上;二是該軟體含有特定的機器碼(彙編語言),它與别的體系不相容。

此域描述格式為:

Excludearch : 體系1 [體系2] ...

注: []所括為可選項,各體系之間以空格分隔。

如果目前體系在此域值之中,則RPM制作軟體包時将報錯退出,請看下面的例子。

在lze-6.0-2.spec檔案頭部分加入一行:

Excludearch : i386

再運作建包指令rpm -bb(<<精通RPM之七--制作篇(下)>>将講到):

# rpm -bb lze-6.0-2.spec

Architecture is excluded: i386

#

由上看出,RPM提示了“體系不适用: i386”的錯誤。

3.2 Exclusivearch :

此域定義軟體包适用的體系。其描述格式與Excludearch類似:

Exclusivearch : 體系1 [體系2] ...

注: []所括為可選項,各體系之間以空格分隔。

假如在lze-6.0-2.spec檔案頭加入一行:

Exclusivearch : i386 sparc

再運作建包指令将會怎麼樣:

# rpm -bb lze-6.0-2.spec

Executing: %prep

預處理腳本程式(prep)開始執行

Executing: %build

編譯連接配接腳本程式(build)開始執行

Executing: %install

安裝腳本程式(install)開始執行

Processing files: lze

Finding Provides: (using /usr/lib/rpm/find-provides)...

Finding Requires: (using /usr/lib/rpm/find-requires)...

Provides: lze-edit

PreReq: /bin/sh

Requires: /bin/sh ld-linux.so.2 libc.so.6 libc.so.6(GLIBC_2.0) libc.so.6(GLIBC_2.1)

Wrote: /usr/src/dist/RPMS/i386/lze-6.0-2.i386.rpm

#

看,此次建包(lze-6.0-2.i386.rpm)成功了,因為目前的體系(i386)正好适用。

3.3 Excludeos :

此域定義軟體包不适用的作業系統。RPM可選的作業系統請參考檔案/usr/lib/rpm/rpmrc中的os_canon項目。

其描述格式為:

Excludeos : 作業系統1 [作業系統2] ...

注: []為可選項,作業系統之間以空格分隔。例如:

Excludeos : irix aix solaris

注: 如将此行加入到lze的描述檔案中,則它會訓示RPM不在irix,aix,solaris這三個作業系統上建立lze軟體包。如果目前作業系統是三者之一,則RPM會報錯并中止軟體包的制作。

如:

# rpm -bb lze-6.0-2.spec

OS is excluded: Solaris

#

3.4 Exclusiveos :

此域定義軟體包适用的作業系統。其描述格式為:

Exclusiveos : 作業系統1 [作業系統2] ...

注: []為可選項,作業系統之間以空格分隔。例如:

Exclusiveos : linux solaris

4. 目錄相關

4.1 Prefix :

此域定義可重定位的目錄字首,可在描述檔案中書寫多次。其描述格式為:

Prefix : 目錄字首1 [目錄字首2] ...

注: []為可選項,各目錄字首之間均以空格分隔。例如:

Prefix : /usr /etc

它也可寫作:

Prefix : /usr

Prefix : /etc

RPM利用可重定位的目錄字首,實作了軟體包的重定位安裝,使軟體中的檔案不必固定在某個絕對位置,這種做法很好。LZE軟體包描術檔案lze-6.0-2.spec中就定義了一個可重定位的字首/usr(見第15行),這樣,安裝時就可将該包中在/usr目錄下的檔案重定位到使用者指定的目錄,如:

# rpm -i --prefix /tmp lze-6.0-2.i386.rpm

#

或者:

# rpm -i --relocate /usr=/tmp lze-6.0-2.i386.rpm

#

注: 此指令安裝lze包,将其中含/usr重定位目錄字首的檔案定位到/tmp目錄。如包中

的/usr/bin/lze檔案安裝後,因重定位而成了/tmp/bin/lze。(RPM安裝指令使用方法請參考<<精通RPM之二--安裝篇>>)

4.2 Buildroot :

此域定義的是軟體包所包含的檔案共有的根目錄,此根目錄僅供RPM建立軟體包時使用。即當RPM建立軟體包時,将設定此目錄為根(調用chroot函數),提取所需檔案,生成軟體包。

例如: 當Buildroot設定為/tmp時,對于LZE包描述檔案中所包含的/usr/bin/lze檔案,RPM實際打包的則是/tmp/usr/bin/lze,但對生成的包查詢後可以發現:原檔案名并未改變,還是/usr/bin/lze。

如此說來,這就很有意思了。一般使用者通過設定Buildroot,也可以象超級使用者(root)那樣自由地建立各種各樣的軟體包了,即使包中有那些唯有超級使用者才可以操作的目錄或檔案。安裝這樣的包與安裝由超級使用者建立的包,是沒有什麼分别的。

此域的描述格式很簡單:

Buildroot : 目錄

如,上例可定義為:

Buildroot : /tmp

5. 源碼相關

下列四個域均是為制作源碼包而設計的。源碼包裡有什麼?使用者可以通過查詢包的檔案清單得到,指令是“rpm -qpl 源碼封包件”(請參閱<<精通RPM之五--查詢篇>>有關内容)。一般情況下,源碼包裡有這麼四類檔案: 一是程式源碼(SOURCE),二是源碼更新檔(PATCH),三是軟體包描述檔案,四是圖示檔案(ICON)。通過安裝源碼包,使用者可以輕松地實作現場編譯、連接配接和應用,同時更友善了軟體開發者與軟體包制作者:他們維護程式容易了,并且維護過後可以很快地生成執行代碼包與源碼包。這,也是所有人鐘愛RPM的重要原因之一。

5.1 Source :

此域定義RPM打包時要包含的程式源碼檔案。這些檔案一般先用tar指令打包,然後再用gzip壓縮。一個描述檔案中可包含多個Source域,當有多個這樣的域時,需要進行編号:第1個編為Source0(也可直接用Source),第2個編為Source1,第3個編為Source2等等。此域的描述格式為:

Source[編号] : 源碼檔案

注: []所括為可選項。具體用法如:

Source0 : lze-6.0-2.tar.gz

Source1 : lzeime-wb-6.0-2.tar.gz

Source2 : lzeime-py-6.0-2.tar.gz

Source3 : lze-lib-6.0-2.tar.gz

注: 此域域值可以采用URL(統一資源定位)的形式,如LZE描述檔案第14行。采用這種形式,主要是給其它使用者提供該源碼的位置資訊。在RPM制作源包時,它提取的是最後的檔案名lze-6.0-2.tar.gz,而不是http://zhsoft.myetang.com/lze-6.0-2.tar.gz(URL前面的内容被RPM忽略了)。

5.2 NoSource :

在上例中,假如在打包時不想包含Source1與Source2定義的檔案,那該怎麼辦?

辦法之一是将其所在行删除掉;

辦法之二是将其所在行注釋掉(即所在行前面加#号);

辦法之三就是定義Nosource域,此域可重複。其描述格式為:

NoSource : 源碼域編号

本例可寫作:

NoSource : 1

NoSource : 2

注: 其中的1與2為編号,表示Source1和Source2。

注意: 如果軟體包描述檔案中沒有NoSource域,則RPM生成的源碼包名字格式為"軟體名-版本号-釋出号.src.rpm"。如果使用了NoSource域,則RPM生成的源碼包名字格式為"軟體名-版本号-釋出号.nosrc.rpm"(單從名字就可看出源碼包包含的檔案不完整)。

5.3 Patch :

Patch的本義是更新檔,用在這裡指的是源程式的更新檔,它是用diff指令比較新老源程式所産生的輸出(指令為“diff -Nur 舊檔案 新檔案 >更新檔檔案”),而系統中的patch指令又可利用此輸出将老版本的源程式更新為新版本。

此域定義RPM制作源碼包時所要包含的更新檔檔案,該檔案的命名建議用"軟體名-版本号.更新檔功能.patch"的格式。一個軟體包描述檔案中可有多個Patch域,當有多個這樣的域時,也需要象Source域那樣進行編号(注:第1個域編為Patch0,也可省略0,用Patch)。

此域的描述格式為:

Patch[編号] : 源碼更新檔檔案

注: []所括為可選項。具體用法如:

Patch0 : blather-4.5-bugfix.patch

Patch1 : blather-4.5-config.patch

Patch2 : blather-4.5-somethingelse.patch

注: 此域的域值也可以象Source域一樣,采用URL的形式,RPM僅提取其中的檔案名供其使用。

5.4 NoPatch :

此域的功能類似NoSource,其定義的編号對應的更新檔檔案RPM不作打包處理。此域在描述檔案中可重複出現。如上例,若不想讓源碼包包含Patch0與Patch2域所訓示的更新檔檔案,則可在描述檔案寫上這麼兩行:

NoPatch : 0

NoPatch : 2

注意: 如果軟體包描述檔案中沒有NoPatch域,則RPM生成的源碼包名字格式為"軟體名-版本号-釋出号.src.rpm"。如果使用了NoPatch域,則RPM生成的源碼包名字格式為"軟體名-版本号-釋出号.nosrc.rpm"(單從名字就可看出源碼包包含的檔案不完整)。

三、功能段

見第19-86(即檔案頭以下的部分)。

何謂功能段?可以這麼說,功能段是描述軟體包的重要資料和操作指令的段落,它包括段名與段内容兩部分。沒有功能段,RPM便制作不出任何包裹檔案。功能段的段名都是以百分号(%)開始的,占用一行。功能段的段内容範圍是這樣界定的:它從該功能段段名下一行開始到下一個功能段段名的前一行或到描述檔案結束。如LZE描述檔案,%description段是從第19行到第28行(%prep段從第29行開始),第19行為段名,第20-28行為段内容。而%prep段是從第29行到第32行(第33行%build段開始),其段名在第29行,段内容在第30-32行。另外要注意的是,各個功能段的位置是自由的,可放在檔案頭以下的任何位置,不必拘泥某一固定位置。

必選的功能段

描述檔案中,必選的功能段有:

1. %description

本段是描述段,段的内容是對軟體包進行較為詳細的介紹,不象檔案頭的Summary域僅用一句話說明。介紹的文本形式自由,可任意換行,不受限制。具體請參見LZE描述檔案第20-27行。

本段段名描述格式是:

%description [子包選項]

其中,子包選項的格式為:[-n] 子包名

注: []所括為可選項。

三種形式的描述段段名

:

(1) 段名格式為“%description”時:

本功能段描述的内容是關于父包的。父包也可叫作主軟體包,它用軟體名來指令,其名字格式是:軟體名-版本号-釋出号.體系.rpm。如:lze-6.0-2.i386.rpm。

(2) 段名格式為“%description 子包名”時:

本功能段描述的内容是關于子包的。子包選項中沒有-n選項時,子包是用軟體名加子包名的形式命名,格式為: 軟體名-子包名-版本号-釋出号.體系.rpm。如分成兩個子包的LZE軟體:lze-bin-6.0-2.i386.rpm(執行程式包),lze-config-6.0-2.i386.rpm(配置檔案包)。

(3) 段名格式為“%description -n 子包名”時:

本功能段描述的内容也是關于子包的。當子包選項中有-n選項時,子包直接采用子包名的形式命名。它不包含軟體名,命名格式為: 子包名-版本号-釋出号.體系.rpm。如分成兩個子包的LZE軟體: bin-6.0-2.i386.rpm(執行程式包),config-6.0-2.i386.rpm(配置檔案包)。注意:這種類型的子包内容通常是可被其它軟體包共用的函數庫,如果專用,則盡量不要采用這樣形式來定義子包。

2. %files

本段是檔案段,它定義的是軟體包需要包含哪些檔案。本段通常放在描述檔案尾部,以便于添加檔案名,便于編輯。

本段段名描述格式為:

%files [子包選項] [-f 檔案名]

注: []所括為可選項。

當沒有任何選項時,本段内容定義的是父包要打包的檔案清單;

當有子包選項時,本段内容定義的則是子包要打包的檔案清單;

當選擇-f選項時,RPM除了從檔案段讀取打封包件清單外,還将從指定的檔案中讀取要打包的檔案清單。指定的檔案中,一個檔案名占用一行。此選項友善了軟體包制作者,他們可以通過程式自動産生有關軟體的檔案清單,并将其寫入到一個特定的檔案中,這樣制作軟體包時,隻需引用一下這個檔案,RPM就會自動從這個檔案中讀取檔案名并将其加入包中。如果沒有此選項,軟體包制作者隻能在檔案段裡,将要打包的檔案名一個一個寫進去,有點麻煩。

檔案段的内容格式為:

[修飾符1 [修飾符2] ...] 檔案名

其中:修飾符是可選的,一個檔案可以有多個修飾符,檔案名必須以/開頭(絕對路徑形式)。

修飾符有以下幾類:

(1) 檔案相關

* %doc :

此修飾符設定檔案類型為說明文檔(參見LZE描述檔案第72,73行);

* %config :

此修飾符設定檔案類型為配置檔案(參見LZE描述檔案第70,71行);

* %config(missingok) :

此修飾符設定檔案類型為配置檔案,且此檔案可丢失。即使丢失了,RPM在解除安裝軟體包時并不認為這是個錯誤,并不報錯。

此修飾符通常用于那些軟體包安裝後建立的符号連接配接檔案,如/etc/rc.d/rc2.d/S55named等。此類檔案在軟體包解除安裝後可能需要删除,是以丢失了也不要緊。

* %config(noreplace) :

此修飾符設定檔案類型為配置檔案,且如果安裝時系統中有同名的檔案,則軟體包中的這個檔案将換個名字安裝,其檔案名字尾加個.rpmnew。(如果不用此修飾符,則安裝時RPM若發現有同名檔案,則RPM會将系統中的這個檔案換個名字,其字尾加上.rpmorig,而軟體包中的檔案則還用原來的名字。)在軟體包解除安裝時,系統中的同名檔案被RPM換個名字儲存起來,其字尾加上了.rpmsave。

如描述檔案的檔案段中定義了這麼一行:

%config(noreplace) /etc/hello

則制成的包在安裝時,若系統中已有此檔案/etc/hello,則RPM會提示:

warning: /etc/hello created as /etc/hello.rpmnew

這表明包中的/etc/hello檔案被建立為/etc/hello.rpmnew檔案了。

如果解除安裝這個軟體包,則系統中的/etc/hello将會改名為/etc/hello.rpmsave。

* %ghost :

此修飾符所修飾的檔案,其内容不被包含到軟體包中。這樣的檔案一般是日志檔案(log file)一類的檔案,其檔案屬性(檔案名,屬主,屬組等)很重要,但是檔案内容并不重要。用此修飾符後,RPM僅将其檔案屬性加入包中。

* %attr :

此修飾符設定檔案的屬性資訊,使用格式為:

%attr(權限,屬主,屬組)

注: 權限常用數字形式(八進制),屬主和屬組可以是數字,也可以是字元串。如果檔案的權限,屬主和屬組想使用系統預設值,則可用減号(-)表示它。

如下例采用兩個修飾符,定義/etc/funkey.def檔案的權限為755,屬主預設,屬組為root,類型為配置檔案:

%attr(755,-,root) %config /etc/funkey.def

* %verify :

此修飾符設定檔案需要校驗的那些屬性。這些屬性有:owner(屬主),group(屬組),mode(權限),md5(MD5檢查和),size(大小),maj(主裝置号),min(從裝置号),symlink(符号連接配接),mtime(最後修改時間)。

此修飾符使用格式為:

%verify([not] owner group mode md5 size maj min symlink mtime)

注: not可選。當選用not時,表明需要校驗除標明屬性以外的那些屬性。

如下例訓示RPM校驗/dev/ttyS0檔案時,要校驗其權限,MD5檢查和,大小,主裝置号,從裝置号,符号連接配接和最後修改時間共七項屬性資訊:

%verify(mode md5 size maj min symlink mtime) /dev/ttyS0

這也可以采用not選項來實作,因為除去屬主owner和屬組group兩項屬性,剩下的就是需要校驗的屬性了:

%verify(not owner group) /dev/ttyS0

(2) 目錄相關

* %docdir :

此修飾符定義說明文檔字首,這樣,後面所有含指定檔案名作為字首的檔案,RPM打包時會将其類型統一設定為說明文檔。

例如某描述檔案的檔案段中有這麼三行:

/root/readme

%docdir /root

/root/mydoc.txt

此例指明/root為說明文檔的字首,因為/root/mydoc.txt在%docdir的下一行,是以RPM打包時會設定此檔案的類型為說明文檔。而/root/readme檔案則不做此設定,因為它在%docdir定義之前。

通過此修飾符,使用者可以很友善地設定說明文檔一類的檔案,因為它們通常固定在某個目錄下面,有着共同的字首。

* %dir :

RPM在制作軟體包時,如果要打包的檔案是個目錄,那麼RPM會将該目錄下面的所有檔案包含到軟體包中。(注意:如果要打包的檔案是個符号連接配接,此符号連接配接又指向一個目錄,則RPM并不會将其視作目錄,隻會把它當為普通檔案處理。)如果僅想将這個目錄名包含到軟體包中,制作者用此修飾符修飾一下這個目錄名就行了。

如: /etc是個系統目錄,其下有多個檔案,如果想将其均加入包中,描述檔案的檔案段裡可寫上這麼一行:

/etc

如果僅想包含此目錄,則可用:

%dir /etc

(3) 另類修飾符

此類隻有一個%defattr。說它是另類修飾符,是由于它設定的是預設的檔案屬性,而非特定的某個檔案。它一般放在檔案段内容的第一行。

其使用格式為:

%defattr(權限,屬主,屬組)

其中: 權限,屬主和屬組都可以使用減号(-)。使用減号的屬性将由系統設定。

例如: %defattr(022,zzz,zhsoft) 設定其後的所有檔案權限為022,屬主為zzz,屬組為zhsoft;又如: %defattr(-,zzz,-) 則是設定其後的所有檔案屬主為zzz,權限與屬組由系統設定。

可選的功能段

描述檔案中,可選功能段的内容都是些腳本程式。(LZE描述檔案中多個腳本程式中僅含一個echo指令)

可選的功能段的描述格式為:

功能段名 [子包選項]

注: 子包選項為"[-n] 子包名"。當無子包選項時,段内容描述的是父包的腳本程式。當有子包選項時,段内容則是描述子包的腳本程式。

可選的功能段可分為如下三類:

1. 建包用功能段:

RPM通過源程式來建立一個軟體包時,要執行預處理,編譯,安裝和清理四項操作,分别對應于%prep,%build,%install和%clean四個段。

下面按其執行順序逐段進行說明:

1.1 %prep :

此為預處理段,其内容為預處理腳本程式。該程式完成以下任務:

* 建立軟體編譯用目錄;

* 将源程式解壓縮;

* 通過打更新檔,更新源程式;

* 執行其它一些操作,使源程式随時可進行編譯。

在此腳本程式中,可使用如下兩個宏指令:

1.1.1 %setup

這個宏利用系統中的gzip與tar等指令,來解壓源程式包。RPM會自動探測源程式包是否壓縮,如果壓縮,它會用gzip将其解壓縮,否則直接用tar指令展開包中檔案。其使用格式為:

%setup [-n name] [-c] [-D] [-T] [-b N] [-a N]

注: []所括為可選項。

(1) 當沒有任何選項時:

這個宏用來解壓預設的源程式包(由檔案頭Source或Source0域指定)。注意:源程式包中的檔案應用"軟體名-版本号"作為其上層目錄,這樣%setup宏就可以正常工作。如果不以"軟體名-版本号"作為其上層目錄,則%setup宏工作時有一個指令"cd 軟體名-版本号"(轉目錄)會因為系統中沒有此目錄而出錯退出(除非在此宏上面加上建立此目錄的指令)。如LZE軟體源程式所在的目錄為lze-6.0,我需要用指令"tar cvzf lze-6.0-2.src.tgz lze-6.0"将源程式打包并壓縮,這樣的包就可以被%setup宏正确使用了。

下面是%setup宏指令所執行的一系列指令: (指令前面為行号)

1 cd /usr/src/dist/BUILD

2 echo "預處理腳本程式(prep)開始執行"

3 cd /usr/src/dist/BUILD

4 rm -rf lze-6.0

5 /bin/gzip -dc /usr/src/dist/SOURCES/lze-6.0-2.src.tgz | tar -xvvf -

6 STATUS=$?

7 if [ $STATUS -ne 0 ]; then

8exit $STATUS

9 fi

10 cd lze-6.0

11 [ `/usr/bin/id -u` = '0' ] && /bin/chown -Rhf root .

12 [ `/usr/bin/id -u` = '0' ] && /bin/chgrp -Rhf root .

13 /bin/chmod -Rf a+rX,g-w,o-w .

14 exit 1

看,第10行就有一個轉到lze-6.0目錄的指令,如果沒有這個目錄,程式就會出錯退出了。也許你要問:這些指令你是怎麼知道的?其實這很簡單,隻要在%setup宏下面加上一句"exit 1"指令,讓預處理腳本程式非正常退出即可。這樣RPM所執行的預處理腳本程式作為臨時檔案在其退出時并未删除,隻要看一下這個檔案(在/var/tmp目錄下以rpm-tmp開頭)就知道%setup宏指令做什麼了。

(2) -n name :

上面已經談到,源程式包中的檔案應采用"軟體名-版本号"作為上層目錄。如果用了别的什麼目錄(如name),%setup宏無法正常工作,那該怎麼辦?沒關系,可以用-n選項,引用一下這個目錄(name)就行了。假如我的LZE源程式包中的檔案是以lze為上層目錄,那麼我就可以用"%setup -n lze"宏指令來解壓縮該包。

(3) -c :

此選項的作用是建立上層目錄("軟體名-版本号"目錄)并轉到這個目錄。對于LZE軟體,其效果相當于在上例的第4行與第5行之間加上這麼兩行指令:

mkdir -p lze-6.0

cd lze-6.0

它适用的情況是:有的源程式包是在源程式所在目錄下打的包,是以其中的檔案都沒有上層目錄。這樣的話,要想正确解壓,必須建立上層目錄。

(4) -D :

本選項的作用是在解壓源程式包之前不要删除軟體的上層目錄(軟體名-版本号)。在上例中,其效果是不執行第4行的指令(rm -rf lze-6.0)。

(5) -T :

本選項的作用是不解壓預設的源程式包(由檔案頭的Source或Source0域所定義)。在上例中,其效果是不執行第5-9行的指令:第5行是解壓源程式包(用gzip -dc将包的内容解壓縮到管道中,再由tar -xvvf -從管道中讀取資料并展開),第6-9行是檢查解壓指令的傳回值,非0時執行非正常退出。

(6) -b N :

本選項訓示RPM在轉到上層目錄前解壓第N個源程式包(由檔案頭SourceN域定義)。這适用于含上層目錄的源程式包。注意:如果使用此選項時不同時使用-T選項,則RPM解壓的是兩個源程式包,一個是預設的包(由Source或Source0域定義),一個是-b選項指定的包(由SourceN域定義)。這樣,當N等于0時,預設的源程式包将被解壓兩次。是以,如果想僅解壓指定源程式包,請同時使用-T選項,以禁止解壓預設的源程式包。

下面的宏指令僅解壓第1個源程式包,然後轉到上層目錄:

%setup -b 1 -T

(7) -a N :本選項訓示RPM在轉到上層目錄後再解壓第N個源程式包(由檔案頭SourceN域定義)。這适用于不含上層目錄的源程式包。使用本選項時,一般加上-c選項,以建立上層目錄并轉到此目錄。注意:如果使用此選項時不同時使用-T選項,則RPM解壓的是兩個源程式包,一個是預設的包(由Source或Source0域定義),一個是-a選項指定的包(由SourceN域定義)。這樣,當N等于0時,預設的源程式包将被解壓兩次。是以,如果想僅解壓指定源程式包,請同時使用-T選項,以禁止解壓預設的源程式包。

下面的宏指令讓RPM先轉到上層目錄,再僅解壓第2個源程式包:

%setup -T -a 2

1.1.2 %patch

此宏利用系統中的patch指令,來給指定的源程式包打更新檔,進而将程式更新。其使用格式為:

%patch [-P N] [-p N] [-b name] [-E]

注: []所括為可選項。

為了說明下列選項的作用,我們為LZE軟體包描述檔案中定義三個更新檔檔案:

Patch0 : lze-patch.zero

Patch1 : lze-patch.one

Patch2 : lze-patch.three

(1) 當沒有任何選項時:

沒有任何選項時,該宏使用的是預設的更新檔檔案(第0個更新檔檔案),即由檔案頭Patch或Patch0域所定義的檔案(LZE包使用lze-patch.zero)。

該宏在執行時,擴充為以下指令:

echo "Patch #0:"

patch -p0 -s < /usr/src/dist/SOURCES/lze-patch.zero

注: 第一行指令是利用echo指令向螢幕輸出字元串“Patch #0:”。第二行指令則是利用patch指令讀取更新檔檔案lze-patch.zero更新源程式。

patch指令用了兩個選項:(有關patch指令用法,詳見其使用者手冊)

* -p : 這個選項用于确定patch所要操作的檔案。它針對更新檔檔案頭部的檔案名,删除名字中指定數目個斜杠(/)前面的所有字元,進而得到要操作的檔案名。如更新檔檔案裡有個檔案名/usr/zzz/src/lze.c,則用-p0時patch操作的檔案名不變,用-p1時則變為usr/zzz/src/lze.c,用-p2時則變為zzz/src/lze.c,如用-p4則操作的檔案名變為lze.c。

* -s : 這個選項訓示patch在打更新檔過程中不輸出任何資訊,即使有錯誤發生。

(2) -P N :

使用此選項以訓示RPM使用第N個更新檔檔案(由檔案頭PatchN域定義)。如想讓RPM使用LZE的第2個更新檔檔案Patch2(lze-patch.three)時,可使用"-P 2"來指定。

(3) -p N :

此選項與其參數是由%patch宏直接傳給patch指令的。請參見上面patch指令所用的-p選項的介紹。

(4) -b name :

當有多個patch指令操作同一個檔案時,patch會将原檔案換名儲存(其字尾變作.orig),如lze.c會變作lze.orig。如果想用别的名字作字尾,則可用-b設定一下,這樣原檔案會換名為"原檔案名+字尾",如用-b ZZZ時,lze.c會換名儲存為lze.cZZZ。

此選項在執行時,實際上是給patch指令傳遞了一個選項及參數,即--suffix name。

(5) -E :

此選項直接傳給patch指令,其作用是:如果一個檔案打完更新檔後内容為空(位元組數為0),則删除這個檔案。

1.2 %build :

此為編譯段,其内容為編譯腳本程式。該程式完成源程式的編譯和連接配接。一個最簡單的例子就是程式中僅有一個make指令。這适用于大部分情況,因為多數軟體均有自己的makefile,這樣通過make指令就可實作編譯與連接配接。如果沒有makefile的話,需要軟體包制作者自己在編譯段書寫上一系列的編譯連接配接指令。

1.3 %install :

此為安裝段,其内容是安裝腳本程式。該程式将已編譯連接配接好的執行程式或其它檔案存放到指定目錄下,這些程式或檔案供RPM打包時使用。一個最簡單的例子就是程式中僅用一個make install指令,進而完成安裝。這也需要相應的軟體有makefile維護檔案。沒有的話,軟體包制作者也得自己寫指令。

1.4 %clean :

此為清理段,其内容是清理腳本程式。此程式在RPM制作好軟體包後才執行,它通常是删除那些編譯連接配接時産生的臨時檔案或目錄,完成繕後工作。

2. 管理用功能段:

此類段用于軟體包自身的管理(安裝,解除安裝和校驗),包括%pre,%post,%preun,%postun,和%verifyscript五個功能段。

2.1 %pre :

該段内容為安裝前腳本程式。它在軟體包安裝之前執行,通常是檢測操作環境,建立有關目錄,清理多餘檔案等等,為軟體包的順利安裝做準備。本段很少使用。

其段名格式為: %pre [子包選項]

2.2 %post :

該段内容為安裝後腳本程式。它在軟體包安裝完成之後執行,常用來建立符号連接配接,修改系統配置檔案,運作ldconfig程式等,以利軟體的正常運作。

其段名格式為: %post [子包選項]

2.3 %preun :

該段内容為解除安裝前腳本程式。它在軟體包解除安裝之前執行,主要為解除安裝做準備。具體如,要解除安裝的軟體包中某個程式目前正在運作時,此腳本程式必須殺掉它,否則無法正确解除安裝。

其段名格式為: %preun [子包選項]

2.4 %postun :

該段内容為解除安裝後腳本程式。它在軟體包解除安裝後執行,完成解除安裝的繕後工作,如将系統配置檔案inetd.conf改回原來的樣子,重新運作一下ldconfig指令,将已解除安裝的共享庫從緩沖檔案ld.so.cache中删除等等。

其段名格式為: %postun [子包選項]

2.5 %verifyscript :

該段内容為校驗腳本程式。RPM校驗軟體包時,除了執行标準的校驗外,如果軟體包制作者設定有此校驗腳本程式,還将執行之。

其段名格式為: %verifyscript [子包選項]

下面是XFree86-libs-3.3.6-6.i386.rpm軟體包中的校驗腳本程式,它校驗的是動态連結庫目錄/usr/X11R6/lib。校驗時,在/etc/ld.so.cache檔案中查找/usr/X11R6/lib,如果找不到,則顯示"missing",找到則顯示"found"。

# verifyscript

echo -n "Looking for /usr/X11R6/lib in /etc/ld.so.conf... "

if ! grep "^/usr/X11R6/lib$" /etc/ld.so.conf > /dev/null

then

echo "missing"

echo "/usr/X11R6/lib missing from /etc/ld.so.conf" >&2

else

echo "found"

fi

3. 互動用功能段:

這類功能段有%triggerin,%triggerun,%triggerpostun,它們的内容都是RPM用于軟體包之間互動控制的腳本程式。這些腳本程式都是在系統滿足指定的條件下才觸發執行的:

1) %triggerin : 段内為安裝時觸發腳本程式,當其所在軟體包與指定軟體包僅有一方已安裝時,安裝另一方将觸發此程式執行;

2) %triggerun : 段内為解除安裝時觸發腳本程式,當其所在軟體包與指定軟體包都已安裝時,解除安裝二者中的任一個将觸發此程式執行;

3) %triggerpostun : 段内為解除安裝後觸發腳本程式,隻有指定軟體包解除安裝後才觸發此程式執行。

3.1 段名格式

它們的段名描述格式均為:

互動段名 [子包選項] [-p 解釋程式] -- 觸發條件1 [,觸發條件2] ...

注: []所括為可選項。子包選項見前面介紹,不贅述。

3.1.1 -p選項:

此選項用于指定一個解釋程式,來解釋執行互動功能段的腳本程式。預設情況下,RPM使

用/bin/sh來執行腳本(此類腳本用SHELL語言編寫,也叫SHELL程式)。有的RPM包則是使用/usr/bin/perl

來執行腳本(此類腳本是用PERL這種解釋性語言寫的),這就需要用-p選項來指定解釋程式為

/usr/bin/perl,如:

%triggerin -- sendmail

ln -sf /usr/bin/sendmail /etc/mymailer/mailer

%triggerin -- vmail

ln -sf /usr/bin/vmail /etc/mymailer/mailer

注: 此例中定義package子軟體包安裝時觸發腳本程式:當觸發條件(fileutils>3.0,perl<1.2)滿足時,用/usr/bin/perl執行腳本,即用print指令輸出字元串"I'm in my trigger!"。

3.1.2 觸發條件:

互動功能段的觸發條件格式是:

功能名 [比較符 版本号]

其中:比較符與版本号可選。僅有一個功能名時,表明該功能存在時觸發程式執行。比較符可用大于(>),等于(=),小于(<),大于等于(>=)和小于等于(<=)。

如觸發條件bash,又如觸發條件fileutils>3.0,這種使用均合法。

互動功能段最少有一個觸發條件。當有多個觸發條件時,這些條件間均以逗号(,)分隔,它們之間是"或"的關系,即隻要其中有一個條件系統滿足,RPM就将執行觸發腳本程式。如上面介紹-p選項時舉的例子:例子中有兩個觸發條件fileutils>3.0和perl<1.2,在安裝軟體包時,隻要有一個條件滿足,RPM就會執行觸發腳本,即輸出"I'm in my trigger!"。

3.2 互動用功能段的使用

為什麼要使用互動用功能段?下面的例子很能說明問題。

假定mymailer軟體包需要/etc/mymailer/mailer這個符号連接配接檔案指向目前使用的郵件發送代理程式。如果sendmail包安裝了,那麼這個符号連接配接檔案應指向/usr/bin/sendmail程式。如果vmail包安裝了,那麼它應當指向/usr/bin/vmail程式。如果這兩個軟體包都安裝了(實際上,sendmail與vmail彼此是沖突的),那麼我們也無需考慮符号連接配接指向哪個檔案了。當然,如果這兩個包都未安裝,那麼/etc/mymailer/mailer符号連接配接檔案也沒有理由存在了。

上述要求,我們通過為mymailer軟體包編寫觸發腳本程式來實作,這些腳本程式在下列事件發生時,将改變/etc/mymailer/mailer符号連接配接的内容:

1) sendmail已安裝;

2) vmail已安裝;

3) sendmail解除安裝時;

4) vmail解除安裝時。

前兩個事件觸發的腳本程式可以這樣寫:

%triggerin -- sendmail

ln -sf /usr/bin/sendmail /etc/mymailer/mailer

%triggerin -- vmail

ln -sf /usr/bin/vmail /etc/mymailer/mailer

這是兩個安裝時被sendmail或vmail所觸發腳本程式。它們将在下列情況下執行:

1) 在mymailer包已安裝的情況下,安裝或更新sendmail包;

2) 在mymailer包已安裝的情況下,安裝或更新vmail包;

3) 在sendmail包已安裝的情況下,安裝或更新mymailer包;

4) 在vmail包已安裝的情況下,安裝或更新mymailer包。

後兩個事件觸發的腳本程式可以這麼寫:

%triggerun -- sendmail

[ $2 = 0 ] || exit 0

if [ -f /usr/bin/vmail ]

then

ln -sf /usr/bin/vmail /etc/mymailer/mailer

else

rm -f /etc/mymailer/mailer

fi

%triggerun -- vmail

[ $2 = 0 ] || exit 0

if [ -f /usr/bin/sendmail ]

then

ln -sf /usr/bin/sendmail /etc/mymailer/mailer

else

rm -f /etc/mymailer/mailer

fi

這兩個腳本程式在下列情況下觸發執行:

1) 在sendmail包已安裝的情況下,解除安裝mymailer包;

2) 在vmail包已安裝的情況下,解除安裝mymailer包;

3) 在mymailer包已安裝的情況下,解除安裝sendmail包;

4) 在mymailer包已安裝的情況下,解除安裝vmail包。

為了確定在mymailer包解除安裝後符号連接配接檔案/etc/mymailer/mailer也被删除,可以在

mymailer軟體包描述檔案的%postun功能段内,加上删除該檔案的指令:

%postun

[ $1 = 0 ] && rm -f /etc/mymailer/mailer

注: %postun段内為解除安裝後執行腳本程式,在mymailer包解除安裝後執行。

由上看出,當一個軟體包與另一個軟體包存在密切關系時,我們可以通過互動用功能段實作某些檔案的管理,這不僅擴充了RPM軟體包管理的功能,又有助于軟體包的正常運作。

4. 其它功能段

其它功能段隻有一個,即%changelog。這個段的内容是軟體維護記錄,它記錄每次軟體維護的時間,維護人及其EMAIL,維護的項目等。

%changelog段内容格式為:

* 星期 月份 日子 年份 維護内容

注: 每個維護記錄均以*開頭,星期,月份均須為英文縮寫。維護内容多時可分行編寫,

每行開頭最好以減号(-)開頭。可以采用類似LZE方式的維護記錄寫作格式:(見LZE描述檔案第80-85行)

摘自賽迪網

繼續閱讀