rpm介紹
rpm的全稱是RedhatPackage Manager,常見的使用rpm軟件包的系統主要有Fedora、CentOS、openSUSE、SUSE企業版、PCLinuxOS等。使用deb軟件包後綴的類Debian系統最常見的有Debian、Ubuntu、Finnix等。
從軟件運行的結構來說,一個軟件主要可以分爲三個部分:可執行程序、配置文件和動態庫。當然還有可能會有相關文檔、手冊、供二次開發用的頭文件以及一些示例程序等等。可執行文件是必須的,其他部分都是可選的。
製作rpm軟件包的方法,使用最多的是rpmbuild這個命令行工具。如果你的rpm的版本<=4.4.x,那麼rpmbuid工具其默認的工作路徑是/usr/src/redhat,由於權限使得普通用戶不能製作rpm包,在製作rpm軟件包時必須切換到root身份纔可以。所以,rpm從4.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階段
這個階段開始構建包,就是執行常見的configure和make操作。
%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可能會有0,1,2或以上,這幾個值。
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包製作(二)》。