rpm包製作(一)


rpm介紹

rpm的全稱是RedhatPackage Manager,常見的使用rpm軟件包的系統主要有FedoraCentOSopenSUSESUSE企業版、PCLinuxOS等。使用deb軟件包後綴的類Debian系統最常見的有DebianUbuntuFinnix等。

   從軟件運行的結構來說,一個軟件主要可以分爲三個部分:可執行程序、配置文件和動態庫。當然還有可能會有相關文檔、手冊、供二次開發用的頭文件以及一些示例程序等等。可執行文件是必須的,其他部分都是可選的。

   製作rpm軟件包的方法,使用最多的是rpmbuild這個命令行工具。如果你的rpm的版本<=4.4.x,那麼rpmbuid工具其默認的工作路徑是/usr/src/redhat,由於權限使得普通用戶不能製作rpm包,在製作rpm軟件包時必須切換到root身份纔可以。所以,rpm4.5.x版本開始,將rpmbuid的默認工作路徑移動到用戶家目錄下的rpmbuild目錄裏,即$HOME/rpmbuild。安全起見,建議用戶在製作rpm軟件包時儘量不要以root身份進行操作。

   關於rpmbuild默認工作路徑由%_topdir的宏變量來定義,這個變量在/usr/lib/rpm/macros裏的定義。也可使用rpmbuild命令查看。

$ rpmbuild --showrc |grep _topdir
……
-14: _topdir    %{getenv:HOME}/rpmbuild


如果用戶想更改這個目錄,官方不推薦直接更改這個文件,而是在用戶家目錄下建立一個名爲.rpmmacros的隱藏文件,然後在裏面重新定義%_topdir,指向一個新的目錄名。

 

定製rpm包工作目錄結構

定製rpm包需要在%_topdir下建立以下5個目錄

目錄名     說明                    macros中的宏名

BUILD     編譯rpm包的臨時目錄           %_builddir

RPMS       最終生成的rpm包的所在目錄      %_rpmdir

SOURCES    所有源代碼和補丁文件的存放目錄   %_sourcedir

SPECS     存放SPEC文件的目錄(重要)        %_specdir

SRPMS     源碼格式rpm包存放路徑          %_srcrpmdir


以上目錄無需手動創建,執行rpmdev-setuptree命令即可在用戶家目錄下自動創建目錄樹

$ yum install rpmdevtools   #安裝rpmdevtools這個工具,該工具包含rpmbuild,rpmdev-newspec,rpmdev-setuptree等工具
$rpmdev -setuptree
$ tree
.
└── rpmbuild
    ├── BUILD
    ├── RPMS
    ├── SOURCES
    ├── SPECS
    └── SRPMS

 

rpmbuild命令常用選項

基本格式:rpmbuild  [options]  [spec文檔|tarball包|源碼包]
1、從spec文檔建立rpm包有以下選項:
-bp        #只執行spec的%pre 段(解開源碼包並打補丁,屬於準備階段)
-bc        #執行spec的%pre和%build 段(完成準備階段並編譯)
-bi        #執行spec中%pre,%build與%install(準備,編譯並安裝)
-bl        #檢查spec中的%file段(查看文件是否包含完全)
-ba        #二進制的rpm包和源碼的rpm包都建立(常用)
-bb        #只建立二進制的rpm包(常用)
-bs        #只建立源碼的rpm包

2.  從tarball包建立rpm包有以下選項:
-tp         #對應sepc方式的-bp
-tc         #對應sepc方式的-bc
-ti         #對應sepc方式的-bi
-ta         #對應sepc方式的-ba
-tb         #對應sepc方式的-bb
-ts         #對應sepc方式的-bs

3.  從源碼包建立rpm包有以下選項:
--rebuild    #建立二進制包,同sepc方式的-bb
--recompile   #同sepc方式的-bi

4.  其他選項:
--buildroot=DIRECTORY  #確定以root目錄建立包
--clean         #完成打包後清除BUILD下的文件目錄
--nobuild        #不進行%build的階段
--nodeps         #不檢查建立包時的關聯文件
--nodirtokens          #generate packageheader(s) compatible with (legacy) rpm[23] packaging
--rmsource       #完成打包後清除SOURCES
--rmspec        #完成打包後清除SPEC
--short-cricuit     #skip straight tospecified stage (only for c,i)
--target=CPU-VENDOR-OS #確定包的最終使用平臺


 

製作rpm包的幾個關鍵階段

%prep階段

    這個階段主要完成對源代碼包的解壓和打補丁,系統把源碼包從SOURCES解壓縮到BUILD目錄,並切換到BUILD下的壓縮包解壓生成的目錄(可能是%{name}-%{version} )裏,完成打補丁等準備工作,最後退回到BUILD 目錄下。常用指令如下:

解壓常用指令:

%setup              #不加任何選項,僅將軟件包打開。
%setup -q            #quiet,靜默方式解壓,輸出少量信息。
%setup -n destdir  #destdir爲軟件包解壓後生成的目錄名稱,一般用在tar包名稱和展開後生成的目錄名不一致的情況下。
%setup -c           #解壓縮之前先創建目錄,目錄名稱一般爲%{name}-%{version}。
%setup -a num        #a表示after,在切換到BUILD目錄之後再解壓第num個文件,如果有多個文件,會產生多個目錄。
%setup -b num    #b表示before,在切換到BUILD目錄之前再解壓第num個文件。一般同-c一起使用,如果有多個文件,這樣可以控制多個文件解壓到一個目錄下。
%setup -D          #在解壓之前不刪除原有目錄
%setup -T           #不解壓,直接把文件複製到BUILD目錄即可。
%setup -T -b 0     #將第0個源代碼文件解壓縮。
%setup -c -n destdir   #指定目錄名稱destdir,並在此目錄產生rpm套件。
打補丁常用指令:
%patch            #最簡單的補丁方式,自動指定patch level。
%patch 0           #使用第0個補丁文件,相當於%patch?p 0。
%patch -s          #不顯示打補丁時的信息。
%patch -T          #將所有打補丁時產生的輸出文件刪除。


 

%build階段

這個階段開始構建包,就是執行常見的configuremake操作。

%configure是個宏常量,會自動將prefix設置成/usr。另外,這個宏還可以接受額外的參數,如果某些軟件有某些高級特性需要開啓,可以通過給%configure宏傳參數來開啓。如果不用 %configure這個宏的話,就需要完全手動指定configure時的配置參數了。如果不指定,它自動將軟件安裝時的路徑自動設置成如下默認目錄:

可執行程序/usr/bin

依賴的動態庫/usr/lib或者/usr/lib64視操作系統版本而定。

二次開發的頭文件/usr/include

文檔及手冊/usr/share/man

 

configure執行完成之後系統重新進入BUILD下的壓縮包解壓出來的目錄下執行 make命令,如make %{?_smp_mflags}OPTIMIZE="%{optflags}"       

以上這條命令的兩個參數的含意爲:

%{?_smp_mflags}如果系統裏定義了make的並行編譯參數,則使用這個參數。例如: -j2 表示 make並行執行兩個文件的編譯操作。如果你使用多個 CPU 或者非單核 CPU,這個參數可以明顯提高編譯速度,但是這裏指定的數字不宜超過你的 CPU 內核數量+1

OPTIMIZE="%{optflags}" 表示如果系統裏定義了 gcc的優化參數,則在軟件默認優化參數的基礎上追加使用這裏指定的優化參數。例如: -O2 -g -pipe 表示使用 gcc 第二優化級、爲調試工具GDB 提供額外的支持信息、使用管道而不是臨時文件以便加快編譯速度。

這兩個參數在/usr/lib/rpm/mBuild/macros文件中定義。

 

%install階段

   這個階段就是執行make install操作。這個階段會在BUILDROOT目錄裏建好目錄結構,然後將需要打包到rpm軟件包裏的文件從BUILD裏拷貝到BUILDROOT裏對應的目錄裏。這個階段最常見的兩條指令是:

rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT

 

   其中$RPM_BUILD_ROOT也可以換成我們前面定義的BuildRoot變量,不過要寫成%{buildroot}纔可以,必須全部用小寫,不然要報錯。

   如果軟件有配置文件或者腳本之類,需要使用用copy命令或者install命令拷貝到%{buildroot}相應的目錄裏,推薦用install命令。

install命令相關選項如下:
-b:類似 --backup,但不接受任何參數。 
-d,--directory:所有參數都作爲目錄處理,而且會創建指定目錄的所有主目錄。
-D:創建<目的地>前的所有主目錄,然後將<來源>複製至 <目的地>;在第一種使用格式中有用。 
-g,--group=組:自行設定所屬組,而不是進程目前的所屬組。
-m,--mode=模式:自行設定權限模式 (像chmod),而不是rwxr-xr-x。 
-o,--owner=所有者:自行設定所有者 (只適用於超級用戶)。 
-p,--preserve-timestamps:保留文件原有時間戳。 
-S,--suffix=後綴:自行指定備份文件的<後綴>。


 

%clean階段

   執行編譯完成後一些清理工作,主要包括對%{buildroot}目錄的清空(不是必須),通常執行諸如make clean之類的命令。 通常執行以下命令:

%clean
rm -rf $RPM_BUILD_ROOT
rm -rf $RPM_BUILD_DIR/%{name}-%{version}

也可以寫成

%clean
%{__rm}-rf %{buildroot}
%{__rm}-rf %{_builddir}/%{name}-%{version}


%files階段

   這裏是包含製作rpm包文件的階段,它主要用來說明會將%{buildroot}目錄下的哪些文件和目錄最終打包到rpm包裏。

   %files階段的第一條命令的語法是:%defattr(文件權限,用戶名,組名,目錄權限)

   如果不需要改變文件、目錄權限則一般用%defattr(-,root,root,-)這條指令來爲其設置缺省權限。所有需要打包到rpm包的文件和目錄都在這個地方列出。

 %files階段有一個重要特性:

 %{buildroot}裏的所有文件都需要明確指定是否要被打到rpm包裏。如果不打也要用%exclude排除掉。當然,也不能聲明%{buildroot}裏不存在的文件或目錄。

 

其他附加階段

%pre        #在此編寫rpm包安裝前執行的腳本。

%post        #在此編寫rpm包安裝後執行的腳本。

%preun       #在此編寫rpm包卸載前執行的腳本。

%postun      #在此編寫rpm包卸載後執行的腳本。

 

例如:

%postun
if ["$1" = "0" ]; then
    rm -rf $RPM_BUILD_ROOT%{jdk_home}/jdk
fi

這裏的$1可能會有012或以上,這幾個值。

0表示卸載這個包的最新版本

1表示第一次安裝這個包

2或以上表示升級這個軟件包


%changelog階段

這是最後一個階段,記錄每次打包時的變更日誌,日期一定不能寫錯,只能使用英文格式,如:

* WedApr 11 2014 ju.com <[email protected]> - 1.8.0-1

- modifythe spec file and rebuild

 

rpm包標準分組

製作rpm包的spec文件裏定義的Group,建議使用標準分組,軟件包具體分組類別有:

Amusements/Games              娛樂/遊戲
Amusements/Graphics           娛樂/圖形
Applications/Archiving    應用/文檔
Applications/Communications  應用/通訊
Applications/Databases     應用/數據庫
Applications/Editors      應用/編輯器
Applications/Emulators    應用/仿真器
Applications/Engineering    應用/工程
Applications/File       應用/文件
Applications/Internet     應用/因特網
Applications/Multimedia    應用/多媒體
Applications/Productivity   應用/產品
Applications/Publishing    應用/印刷
Applications/System      應用/系統
Applications/Text       應用/文本
Development/Debuggers     開發/調試器
Development/Languages     開發/語言
Development/Libraries     開發/函數庫
Development/System      開發/系統
Development/Tools       開發/工具
Documentation         文檔
SystemEnvironment/Base    系統環境/基礎
SystemEnvironment/Daemons     系統環境/守護
SystemEnvironment/Kernel      系統環境/內核
SystemEnvironment/Libraries  系統環境/函數庫
SystemEnvironment/Shells   系統環境/接口
UserInterface/Desktops    用戶界面/桌面
UserInterface/X        用戶界面/X窗口
UserInterface/X Hardware Support   用戶界面/X硬件支持


 

常見宏定義

在系統的/usr/lib/rpm/macros文件中定義了各種宏變量,這裏列出常見的宏定義:

%_prefix     /usr            #展開後是/usr
%_exec_prefix   %{_prefix}         #展開後是/usr
%_bindir     %{_exec_prefix}/bin       #展開後是/usr/bin
%_sbindir     %{_exec_prefix}/sbin     #展開後是/usr/sbin
%_libexecdir   %{_exec_prefix}/libexec   #展開後是/usr/libexec
%_datadir      %{_prefix}/share      #展開後是/usr/share
%_sysconfdir   %{_prefix}/etc       #展開後是/usr/etc
%_sharedstatedir %{_prefix}/com        #展開後是/usr/com
%_localstatedir  %{_prefix}/var      #展開後是/usr/var
%_libdir     %{_exec_prefix}/lib    #展開後是/usr/lib
%_includedir   %{_prefix}/include      #展開後是/usr/include
%_infodir    %{_prefix}/info         #展開後是/usr/info
%_mandir     %{_prefix}/man       #展開後是/usr/man

 


上面說了一堆製作rpm包涉及的一些概念和既定的東西,然而要真正製作一個rpm包,這些並沒有什麼大的卵用,哈哈,關鍵還要會寫最最重要的SPEC文件,請見下回分解àrpm包製作(二)》。

 

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章