1.RPM目錄結(jié)構(gòu)
- rpmbuild
- SOURCES 源碼荣月、圖標(biāo)等文件
- SPECS 用于管理rpm制作進(jìn)程的spec文件
- BUILD 解壓后的文件
- RPMS 由rpmbuild制作好的二進(jìn)制包
- SRPMS 由rpmbuild制作好的源碼包
2.spec文件綜述
- spec文件有什么用?
- spec文件有兩個(gè)用途:構(gòu)建和打包者娱。構(gòu)建即將源碼轉(zhuǎn)換為構(gòu)建工件(java構(gòu)建工具一般為Ant, Maven, Gradle; C語言構(gòu)建工具為makefile)涌韩。打包即確定需要安裝在目標(biāo)機(jī)器上的構(gòu)建產(chǎn)物肮帐。
注意:#
字符表示注釋,但需要避免注釋宏(以 %
開頭)哼丈,因?yàn)樗鼈儠?huì)首先被替換展開启妹。使用 %%
注釋宏。另外醉旦,還要避免在腳本命令的相同行中使用行內(nèi)注釋饶米。
%{name}
,%{version}
和 %{release}
代表 Name, Version 和 Release 這三個(gè)標(biāo)簽髓抑。只要更改標(biāo)簽咙崎,宏就會(huì)使用新值。
spec文件主要標(biāo)簽:
Name: 軟件包名吨拍,應(yīng)與 SPEC 文件名一致褪猛。
Version: 版本號(hào)。
-
Release: 發(fā)行編號(hào)羹饰,初始值為 1%{?dist} 伊滋,每次制作新包時(shí),遞增該數(shù)字队秩。
- 什么是 1%{?dist} : 如果%{dist}未定義返回1笑旺,否則返回1%{dist},
- 用法:
- if判斷:
如果if 0%{?flag}; then foo fi
%{flag}
被定義了馍资,條件語句為:0%{flag}
筒主,執(zhí)行if block; 反之,條件語句為:0, 不執(zhí)行if block。
注意:%{?flag}
前必須加0乌妙,否則如果%{?flag}
未定義使兔,if語句停止執(zhí)行并退出。 -
%{?flag: ...}
:如果%{flag}
被定義藤韵,則展開"..."部分虐沥;
- if判斷:
Patch0: 用于源碼的補(bǔ)丁名稱。如果需要在源碼包解壓后對(duì)一些代碼做修改泽艘,應(yīng)該修改代碼并使用
diff
命令生成 patch 文件欲险,然后放在~/rpmbuild/SOURCES
目錄下。一個(gè) Patch 應(yīng)該只做一種修改匹涮,所以可能會(huì)包含多個(gè) patch 文件天试。BuildRoot: 在
%install
階段(%build
階段后)文件需要安裝至此位置。默認(rèn)情況下焕盟,根目錄為%{_topdir}/BUILDROOT/
秋秤。%description: 程序的詳細(xì)/多行描述宏粤。每行必須小于等于 80 個(gè)字符脚翘。
%prep: 打包準(zhǔn)備階段執(zhí)行一些命令(如,解壓源碼包绍哎,打補(bǔ)丁等)来农,以便開始編譯。
%build: 包含構(gòu)建階段執(zhí)行的命令崇堰,構(gòu)建完成后便開始后續(xù)安裝沃于。
-
%install: 包含安裝階段執(zhí)行的命令。命令將文件從
%{_builddir}
目錄安裝至%{buildroot}
目錄海诲》庇ǎ可以使用$RPM_BUILD_ROOT
代替%{buildroot}
,兩者都可以使用特幔。術(shù)語:
-
%{_builddir}
(即"build目錄")咨演,與%{buildroot}
(即"build root目錄")是不同的目錄。在%{_builddir}
中進(jìn)行編譯蚯斯,并將需要打包的文件從%{_builddir}
中復(fù)制到%{buildroot}
中薄风。 -
%install
階段的命令不會(huì)在用戶安裝RPM包時(shí)執(zhí)行,此階段只在打包時(shí)執(zhí)行拍嵌。
一般在%install
階段執(zhí)行make install
之類的命令遭赂。%make_install
命令等同于DESTDIR=%{buildroot}
,該命令會(huì)將文件安裝到%{buildroot}
目錄中。如果程序不支持DESTDIR
,可手動(dòng)執(zhí)行安裝:需要在%{buildroot}
下創(chuàng)建必要的目錄横辆,并從%{_builddir
}復(fù)制文件至%{buildroot}
目錄撇他。
-
%clean: 清理安裝目錄。一般只包含:
rm -rf %{buildroot}
-
%files:
%files
指令列出需要安裝的文件和目錄。-
%defattr
用于設(shè)置默認(rèn)文件權(quán)限困肩,一般在%files
開頭設(shè)置募疮。格式為:%defattr(<文件權(quán)限>, <用戶>, <用戶組>, <目錄權(quán)限>)
常規(guī)用法為:
%defattr(-, user, group, -)
必須在
%files
部分列出該軟件所擁有的所有文件,注意不要使用如 /usr/bin/ 的硬編碼僻弹,盡量使用宏代替目錄名阿浓。如果路徑以"/"開頭(或從宏擴(kuò)展),則認(rèn)為文件在%{buildroot}目錄中蹋绽。否則芭毙,默認(rèn)文件在當(dāng)前目錄中。
【問題:如果軟件包僅安裝一個(gè)文件卸耘,那么該文件會(huì)安裝在哪里退敦?】
【答:必須有一個(gè)路徑】若要軟件包不受上游改動(dòng)影響,可使用通配符匹配所有文件蚣抗。
【問題:不受上游改動(dòng)影響是什么意思侈百?】
注意:%{somedir}/*
不會(huì)聲明軟件包擁有%{somedir}
目錄,而只包含其中的文件翰铡。如果列出一個(gè)目錄钝域,則該軟件包擁有整個(gè)目錄,以及該目錄內(nèi)所有的文件和子目錄锭魔,因此要小心處理可能和其他軟件共享的目錄例证。-
如果存在以下情況,可能引發(fā)錯(cuò)誤:
- 通配符未匹配任何文件或目錄
- 文件或目錄被多次列出
- %{buildroot}中有文件未列出(空文件目錄不會(huì)報(bào)錯(cuò))
- 使用通配符來列出全部文件時(shí)迷捧,可使用 %exclude 來排除文件织咧。注意如果未匹配到任何文件也會(huì)造成失敗。
-
3. %files指令
%files列表包括多種指令漠秋,主要用于:
- 識(shí)別文檔和配置文件
- 確定文件有正確的權(quán)限和擁有組
- 設(shè)置哪些文件需要在打包驗(yàn)證時(shí)進(jìn)行校驗(yàn)
- 精簡語法
兩個(gè)%files指令可同時(shí)作用于同一個(gè)文件笙蒙,例如:%foo %bar baz
I 文件相關(guān)指令
RPM需要根據(jù)文件類型分別處理不同類型的文件,然而庆锦,rpm并沒有自動(dòng)識(shí)別文件類型的功能捅位。因此,需要由打包者適當(dāng)?shù)膶?duì)不同類型的文件進(jìn)行標(biāo)識(shí)肥荔。
注意:并非所有文件都需要被標(biāo)識(shí)绿渣,在大多數(shù)包中,大多數(shù)文件都不需要被標(biāo)識(shí)燕耿。
-
%doc
指令:
rpm會(huì)跟蹤其數(shù)據(jù)庫中的文檔文件中符,以便用戶查找已安裝包信息。
此外誉帅,rpm可在安裝期間創(chuàng)建包的文檔目錄淀散,并將文檔復(fù)制其中右莱。添加該步驟方法如下:
build期間,README 文件位于頂級(jí)目錄档插;軟件包install完成后慢蜓,rpm將在軟件包同名的文檔目錄(即<software>-<version>-<release>)創(chuàng)建目錄,并將 README 文件拷貝其中郭膛。新創(chuàng)建的目錄和 README 文件將在rpm數(shù)據(jù)庫被作為文檔進(jìn)行標(biāo)識(shí)晨抡。默認(rèn)的文檔目錄是%doc README %doc /usr/local/foo/README
/usr/doc
,可在rpmrc文件中更改则剃。 -
%config
指令:用于標(biāo)識(shí)文件作為配置文件耘柱。(只能一個(gè)配置文件) -
%attr
指令:用于設(shè)置文件權(quán)限。例:%attr(<file_mode>, <user>, <group>) filename
-
%defattr
指令: 用于設(shè)置文件默認(rèn)權(quán)限棍现,一般寫在%files
頭部调煎。例:%defattr(<file_mode>, <user>, <group>, <dir_mode>)
-
%ghost
to be continue... -
%verify
to be continue...
II 目錄相關(guān)指令
-
%docdir
指令:向文檔目錄列表添加目錄。rpm的%docdir
列表默的認(rèn)目錄有:/usr/doc
,/usr/info
,/usr/main
己肮。例:%docfir /usr/test ,
任何
/usr/test
目錄下的文件都會(huì)自動(dòng)被標(biāo)識(shí)為文檔文件士袄。 %dir
指令:之前提到,如果在%files
下列出文件夾谎僻,則該文件夾下的所有文件或子文件夾都會(huì)被打包到軟件包中娄柳。%dir
指令可設(shè)置rpm只打包自身,而忽略其中的文件或子文件夾戈稿。-f <file>
:從<file>中讀取%files
列表西土。
Tips
- shell腳本錯(cuò)誤
Syntax error near unexpected token `fi`
:缺少then
- spec文件內(nèi)的標(biāo)簽必須有值讶舰,標(biāo)簽前不能有空格鞍盗;
- spec文件必須要有
%description
- spec文件的當(dāng)前目錄為
/BUILD
-
%{buildroot}
是%install
階段,/BUILDROOT
下自動(dòng)創(chuàng)建的子目錄/name-version-release
-
%{buildroot}
內(nèi)的所有文件都必須在%files
中列出跳昼,空目錄可不必列出 -
/BUILDROOT
目錄會(huì)在%install
階段自動(dòng)創(chuàng)建
代碼參考
package.sh:
CUR_DIR=$(cd `dirname $0`; pwd)
if [ -d ${CUR_DIR}/rpmbuild ]; then
rm -rf ${CUR_DIR}/rpmbuild
fi
mkdir -p ${CUR_DIR}/rpmbuild
mkdir -p ${CUR_DIR}/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
cp ${CUR_DIR}/*.spec ${CUR_DIR}/rpmbuild/SPECS/
rpmbuild --define "_topdir ${CUR_DIR}/rpmbuild" -bb ${CUR_DIR}/rpmbuild/SPECS/web.spec
web.spec:
Name: web
Version: 1.0.0
Release: 1%{?dist}
Summary: test
License: GPL
URL: http://gitlabsec.huawei.com/h00416865/web
%description
%define PROJECT_ROOT %{_builddir}/../../..
%prep
%build
echo "begin to mvn install..."
cd %{PROJECT_ROOT}/web_console
mvn clean install
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}/opt/weiee
mkdir -p %{_builddir}/webapp
cp -r %{PROJECT_ROOT}/web_console/target/*.war %{_builddir}
unzip -oq %{_builddir}/*.war -d %{_builddir}/webapp
cp -r %{_builddir}/webapp %{buildroot}/opt/weiee
%files
%defattr(-,root,root,-)
/opt/weiee/
%post
%clean
rm -rf %{buildroot}
%changelog
參考文章
http://ftp.rpm.org/max-rpm/index.html
How to create an RPM package/zh-cn