一、說(shuō)明
如果我們是以軟件包的格式來(lái)劃分的,常見的Linux發(fā)行版主要可以分為兩類,類ReadHat系列和類Debian系列,這兩類系統(tǒng)分別提供了自己的軟件包管理系統(tǒng)和相應(yīng)的工具。
類RedHat系統(tǒng)中軟件包的后綴是rpm,類Debian系統(tǒng)中軟件包的后綴是deb。另一方面,類RedHat系統(tǒng)提供了同名的rpm命令來(lái)安裝、卸載、升級(jí)rpm軟件包,類Debian系統(tǒng)同樣提供了dpkg命令來(lái)對(duì)后綴是deb的軟件包進(jìn)行安裝、卸載和升級(jí)等操作。
rpm的全稱是Redhat Package Manager,常見的使用rpm軟件包的系統(tǒng)主要有Fedora、CentOS、openSUSE、SUSE企業(yè)版、PCLinuxOS以及Mandriva Linux、Mageia等,使用deb軟件包后綴的類Debian系統(tǒng)最常見的有Debian、Ubuntu、Finnix等。
RPM這個(gè)軟件管理的機(jī)制是由 Red Hat 這家公司發(fā)開發(fā)出來(lái)的, RPM 是以一種數(shù)據(jù)庫(kù)記錄的方式來(lái)將你所需要的軟件安裝到你的 Linux 系統(tǒng)的一套管理機(jī)制。
它最大的特點(diǎn)就是將你要安裝的軟件先編譯過, 并且打包成為 RPM 機(jī)制的包裝文件,通過包裝好的軟件里默認(rèn)的數(shù)據(jù)庫(kù)記錄, 記錄這個(gè)軟件要安裝的時(shí)候所依賴的軟件,當(dāng)在你的 Linux 主機(jī)進(jìn)行安裝時(shí), RPM 會(huì)先依照軟件里的數(shù)據(jù)查詢 Linux 主機(jī)的依賴軟件是否滿足, 若滿足則予以安裝,若不滿足則不予安裝。那么安裝的時(shí)候就將該軟件的信息整個(gè)寫入 RPM 的數(shù)據(jù)庫(kù)中,以便未來(lái)的查詢、驗(yàn)證與卸載!


這樣一來(lái)的優(yōu)點(diǎn)是:
1.?由于已經(jīng)編譯完成并且打包完畢,所以軟件傳輸與安裝上很方便 (不需要再重新編譯)
2.? 由于軟件的信息都已經(jīng)記錄在 Linux 主機(jī)的數(shù)據(jù)庫(kù)上,很方便查詢、升級(jí)與卸載
但是這也造成些許的困擾,由于 RPM 文件是已經(jīng)包裝好的數(shù)據(jù),也就是說(shuō), 里面的數(shù)據(jù)已經(jīng)都『編譯完成』了!所以,該軟件文件幾乎只能安裝在原本默認(rèn)的硬件與操作系統(tǒng)版本中。?也就是說(shuō),你的主機(jī)系統(tǒng)環(huán)境必須要與當(dāng)初創(chuàng)建這個(gè)軟件文件的主機(jī)環(huán)境相同才行!?
舉例來(lái)說(shuō),rp-pppoe 這個(gè) ADSL 撥接軟件,它必須要在 ppp 這個(gè)軟件存在的環(huán)境下才能進(jìn)行安裝!如果你的主機(jī)并沒有 ppp 這個(gè)軟件,那么很抱歉,除非你先安裝 ppp 否則 rp-pppoe 就是不讓你安裝的 (當(dāng)然你可以強(qiáng)制安裝,但是通常都會(huì)有點(diǎn)問題發(fā)生就是了!)。
所以,通常不同的 distribution (發(fā)行版)所釋出的 RPM 文件,并不能用在其他的 distributions 上。舉例來(lái)說(shuō),Red Hat 釋出的 RPM 文件,通常無(wú)法直接在 SuSE 上面進(jìn)行安裝的。更有甚者,相同 distribution 的不同版本之間也無(wú)法互通,例如 CentOS 6.x 的 RPM 文件就無(wú)法直接套用在 CentOS 7.x 。
因此,這樣可以發(fā)現(xiàn)這些軟件管理機(jī)制的問題是:
1.? 軟件文件安裝的環(huán)境必須與打包時(shí)的環(huán)境需求一致或相當(dāng)
2.? 需要滿足軟件的相依屬性需求
3.? 卸載時(shí)需要特別小心,最底層的軟件不可先移除,否則可能造成整個(gè)系統(tǒng)的問題
那怎么辦?如果我真的想要安裝其他 distributions 提供的好用的 RPM 軟件文件時(shí)? 呵呵!還好,還有 SRPM 這個(gè)東西!SRPM 是什么呢?顧名思義,他是 Source RPM 的意思,也就是這個(gè) RPM 文件里面含有源碼。特別注意的是,這個(gè)SRPM 所提供的軟件內(nèi)容『并沒有經(jīng)過編譯』, 它提供的是源碼!
通常?SRPM 的擴(kuò)展名是以 ***.src.rpm 這種格式來(lái)命名的。不過,既然 SRPM 提供的是原始碼,那么為什么我們不使用 Tarball 直接來(lái)安裝就好了?這是因?yàn)?SRPM 雖然內(nèi)容是原始碼, 但是他仍然含有該軟件所需要依賴說(shuō)明、以及所有 RPM 文件所提供的數(shù)據(jù)。同時(shí),他與 RPM 不同的是,它也提供了參數(shù)配置文檔 (就是 configure 與 makefile),所以如果我們下載的是 SRPM ,那么要安裝該軟件時(shí),你就必須要:
1.? 先將該軟件以 RPM 管理的方式編譯,此時(shí) SRPM 會(huì)被編譯成為 RPM 文件
2.? 然后將編譯完成的 RPM 文件安裝到 Linux 系統(tǒng)當(dāng)中
怪了,怎么 SRPM 這么麻煩呢!還要重新編譯一次,那么我們直接使用 RPM 來(lái)安裝不就好了?通常一個(gè)軟件在發(fā)布的時(shí)候,都會(huì)同時(shí)發(fā)布該軟件的 RPM 與 SRPM 。我們現(xiàn)在知道 RPM 文件必須要在相同的 Linux 環(huán)境下才能夠安裝,而 SRPM 既然是原始碼的格式,自然我們就可以通過修改 SRPM 內(nèi)的參數(shù)配置檔,然后重新編譯生成能適合我們 Linux 環(huán)境的 RPM 文件,如此一來(lái),不就可以將該軟件安裝到我們的系統(tǒng)當(dāng)中,而不必與原作者打包的 Linux 環(huán)境相同了?這就是 SRPM 的用處了!

為何說(shuō) CentOS 是『社群維護(hù)的企業(yè)版』呢?
?Red Hat 公司的 RHEL 發(fā)布后,連帶會(huì)將 SRPM 發(fā)布出來(lái)。 社群的朋友就將這些 SRPM 收集起來(lái)并重新編譯成為所需要的軟件,再重復(fù)發(fā)布,成為 CentOS,所以才能號(hào)稱與 Red Hat 的 RHEL 企業(yè)版同步??!真要感謝 SRPM 哩!如果你想要理解 CentOS 是如何編譯一支程序的, 也能夠通過學(xué)習(xí) SRPM 內(nèi)含的編譯參數(shù),來(lái)學(xué)習(xí)的??!
本文主要描述如何通過軟件包的源代碼src.rpm構(gòu)建自己的rpm軟件安裝包。
?從軟件運(yùn)行的結(jié)構(gòu)來(lái)說(shuō),一個(gè)軟件主要可以分為三個(gè)部分:可執(zhí)行程序、配置文件和動(dòng)態(tài)庫(kù)。當(dāng)然還有可能會(huì)有相關(guān)文檔、手冊(cè)、供二次開發(fā)用的頭文件以及一些示例程序等等,其他部分都是可選的,只有可執(zhí)行文件是必須的。
?關(guān)于如何制作rpm軟件包的方法,網(wǎng)上教程也一大堆,談及最多的當(dāng)屬rpmbuild這個(gè)命令行工具。
rpm的打包流程相比deb的要稍微麻煩一些,因?yàn)樗鼘?duì)打包目錄有一些嚴(yán)格的層次上的要求。如果你的rpm的版本<=4.4.x,那么rpmbuid工具其默認(rèn)的工作路徑是/usr/src/redhat,這就使得普通用戶不能制作rpm包,因?yàn)闄?quán)限的問題,在制作rpm軟件包時(shí)必須切換到root身份才可以。
從rpm從4.5.x版本開始,將rpmbuid的默認(rèn)工作路徑移動(dòng)到用戶家目錄下的rpmbuild目錄里,即$HOME/rpmbuild,并且推薦用戶在制作rpm軟件包時(shí)盡量不要以root身份進(jìn)行操作,因?yàn)樵谥谱鱎PM包的過程中,將會(huì)把軟件編譯和安裝到系統(tǒng)中,這樣可能會(huì)破壞系統(tǒng)。


二、實(shí)驗(yàn)環(huán)境
操作系統(tǒng): CentOS7.x Minimal
編譯安裝軟件:nginx-1.15.0-1.el7_4.ngx.src.rpm
虛擬機(jī): xx.xx.xx.xx (能聯(lián)網(wǎng))
三、 安裝編譯環(huán)境
nginx源碼都是用C/C++寫的,所以需要在編譯用的CentOS 7服務(wù)器上安裝gcc和gcc-c++等相關(guān)軟件包
安裝常用工具
# yum -y install vim? wget
安裝編譯工具
# yum -y install rpm-build? gcc? make??redhat-lsb-core? ?libuuid-devel
安裝nginx依賴包
#? yum -y install openssl openssl-devel libxml2-devel libxslt-devel perl-devel perl-ExtUtils-Embed libtool zlib zlib-devel pcre pcre-devel patch
添加用于編譯src.rpm的用戶
# useradd builder
四、用src.rpm編譯生成nginx安裝包
# wget? http://120.52.51.13/nginx.org/packages/mainline/centos/7/SRPMS/nginx-1.15.0-1.el7_4.ngx.src.rpm

# rpm -qpi? ?nginx-1.15.0-1.el7_4.ngx.src.rpm


#? cp??nginx-1.15.0-1.el7_4.ngx.src.rpm? /home/builder
#? su - builder

編譯方式一:直接生成安裝用的rpm安裝包
?$ rpmbuild --rebuild --clean nginx-1.15.0-1.el7_4.ngx.src.rpm


$ ll? -R


可以看到,程序根據(jù)操作系統(tǒng)的架構(gòu),在 /home/builder/rpmbuild/RPMS/x86_64/ 目錄下編譯生成用于安裝的rpm包。

編譯方式二:生成源碼包
$ rpm -ivh nginx-1.15.0-1.el7_4.ngx.src.rpm
$ ll -R

用root用戶,對(duì)生成的?nginx-1.15.0.tar.gz 包做編譯安裝,這沒什么好說(shuō)的。

編譯方式三:通過spec 文件,生成用于安裝的rpm包
$ rpm -ivh nginx-1.15.0-1.el7_4.ngx.src.rpm
$ ll? -R
$ cd /home/builder/rpmbuild/SPECS/
$ rpmbuild -bb nginx.spec


$?/home/builder
$? ll? -R

細(xì)心的你可能會(huì)發(fā)現(xiàn),咦,怎么和方式一生成安裝用的rpm包方式一樣?
其實(shí)不一樣,相比方式一,在?rpmbuild -bb nginx.spec 之前,我們是可以編輯修改nginx.spec 之前,自定一些東西的,只是我們這里用的默認(rèn)的nginx.spec文件而已,關(guān)于nginx.spec文件,不是本文的關(guān)注點(diǎn),感興趣可以查看相關(guān)文檔。
總結(jié)一下:
src.rpm包的好處是,一定程度上跨平臺(tái),在類RedHat系列,如RedHat、Fedora、CentOS、openSUSE、SUSE企業(yè)版、PCLinuxOS以及Mandriva Linux、Mageia等操作系統(tǒng)上,不管哪個(gè)版本,下載某個(gè)軟件的src.rpm包,編譯成用于安裝rpm包,那么就適配這個(gè)操作系統(tǒng)了。
如你將nginx-1.15.0-1.el7_4.ngx.src.rpm在 CentOS6.5上編譯成安裝用的rpm包,那么就可以在CentOS6.5上安裝,如你將nginx-1.15.0-1.el7_4.ngx.src.rpm在 CentOS7.5上編譯成安裝用的rpm包,那么就可以在CentOS7.5上安裝。
如果你將nginx-1.15.0-1.el7_4.ngx.src.rpm在CentOS6.5上編譯成安裝用的rpm包,在CentOS7.5上安裝,基本不行!
五、安裝nginx
$? su? -root??
# rpm -ivh /home/builder/rpmbuild/RPMS/x86_64/nginx-1.15.0-1.el7_4.ngx.x86_64.rpm

# nginx -V 2>&1 | sed 's/ --/\n--/g' | egrep --color '.*path.*|$'

#???rpm -qa --scripts nginx

# rpm -qi? nginx
你在哪臺(tái)服務(wù)器上做的編譯,包中獲取了你的主機(jī)名。

# systemctl start nginx
# systemctl enable nginx
# systemctl status nginx


六、參考
軟件安裝:?RPM, SRPM?與?YUM?功能
http://cn.linux.vbird.org/linux_basic/0520rpm_and_srpm.php#intro_whatisrpm
rpmbuild命令
http://man.linuxde.net/rpmbuild
rpmbuild制作rpm 包
https://blog.csdn.net/u012373815/article/details/73257754
一堂課玩轉(zhuǎn)rpm包的制作
http://blog.chinaunix.net/uid-23069658-id-3944462.html
How to compile and install nginx1.15.3 on CentOS7
http://www.itdecent.cn/p/1a83110786b1
玩轉(zhuǎn)rpm包的制作
https://blog.csdn.net/weixin_37871174/article/details/79258383
Linux 安裝.src.rpm源碼包的方法
https://www.cnblogs.com/einyboy/archive/2012/09/13/2683015.html
CentOS 7內(nèi)核源碼包(kernel.src.rpm)的修改和打補(bǔ)丁編譯
https://www.sulabs.net/?p=773
鳥哥的 Linux 私房菜:基礎(chǔ)學(xué)習(xí)篇 第四版
https://wizardforcel.gitbooks.io/vbird-linux-basic-4e/content
修改、重新生成和安裝src.rpm源碼包
http://abcdxyzk.github.io/blog/2014/10/30/tools-src-rpm
https://haohetao.iteye.com/blog/684589
在 CentOS 下設(shè)置一個(gè)創(chuàng)建 RPM 的環(huán)境
https://wiki.centos.org/zh/HowTos/SetupRpmBuildEnvironment
Rebuild a Source RPM
https://wiki.centos.org/HowTos/RebuildSRPM
https://wiki.centos.org/zh/HowTos/RebuildSRPM
Redhat RPM Source Packages
https://aplawrence.com/BGarlock/rpm-bg.html
Linux : How to install source rpm on RHEL/CentOS
https://www.itechlounge.net/2012/12/linux-how-to-install-source-rpm-on-rhelcentos/