spec 文件詳解


 轉自http://blog.sina.com.cn/s/blog_43b39e250100nnu4.html

rpm軟件包系統的標准分組:/usr/share/doc/rpm-4.3.3/GROUPS

rpmrc配置文件:/usr/lib/rpm/rpmrc  /etc/rpmrc   ~/.rpmrc
各種宏定義: /usr/lib/rpm/macros  /etc/rpm/macros   ~/.rpmmacros
已經安裝的rpm包數據庫: /var/lib/rpm*

臨時文件:/var/tmp/rpm*

可以通過命令rpm --showrc查看實現代碼。另外直接通過rpm --eval "%{macro}"來查看具體對應路徑。

比如我們要查看%{_bindir}的路徑,就可以使用命令rpm --eval "%{_bindir}"來查看。

用以下命令將spec文件取出。
  $rpm -qlp *.src.rpm
  $rpm2cpio *.src.rpm|cpio -ivh *.spec
  首先執行rpm -qlp查詢得知該套件中有幾個.spec文件再執行rpm2cpio將rpm文件轉換成cpio文件格式並將轉換結果輸出給cpio程序把source rpm套件中的sepc文件解壓取出。

SPEC腳本引用定義部分

�fine userpath /var/www/html/demo

Name:

軟件包的名稱,后面可使用%{name}的方式引用
Summary:

軟件包的內容概要
Version:

軟件的實際版本號,例如:1.0.1等,后面可使用%{version}引用
Release:

發布序列號,例如:1linuxing等,標明第幾次打包,后面可使用%{release}引用

Copyright:

軟件包所采用的版權規則。具體有:GPL(自由軟件),BSD,MIT,Public Domain(公共域),Distributable(貢獻),commercial(商業),Share(共享)等,一般的開發都寫GPL。
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 (文檔)
  System Environment/Base(系統環境/基礎)
  System Environment/Daemons (系統環境/守護)
  System Environment/Kernel (系統環境/內核)
  System Environment/Libraries (系統環境/函數庫)
  System Environment/Shells (系統環境/接口)
  User Interface/Desktops(用戶界面/桌面)
  User Interface/X (用戶界面/X窗口)
  User Interface/X Hardware Support (用戶界面/X硬件支持)

License:

軟件授權方式,通常就是GPL
Source:

源代碼包,可以帶多個用Source1、Source2等源,后面也可以用%{source1}、%{source2}引用。

NoSource:0 #第一個源碼不包含在包中


Patch:

補丁源碼,可使用Patch1、Patch2等標識多個補丁,使用%patch0或%{patch0}引用,

補丁 ID 規則
0-9 Makefile、configure 等的補丁
10-39 指定功能或包含他的文件的補丁
40-59 配置文件的補丁
60-79 字體或字符補丁
80-99 通過 xgettexize 得到的目錄情況的補丁
100- 其他補丁
NoPatch:0 #第一個補丁文件不包含在包中
BuildRoot:

這個是安裝或編譯時使用的“虛擬目錄”,考慮到多用戶的環境,一般定義為:%{_tmppath}/%{name}-%{version}-root
%{_tmppath}/%{name}-%{version}-%{release}-root

%{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n}
該參數非常重要,后面可使用$RPM_BUILD_ROOT 方式引用。因為在生成rpm的過程中,執行make install時就會把軟件安裝到上述的路徑中,在打包的時候,同樣依賴“虛擬目錄”為“根目錄”進行操作。

※注意區分$RPM_BUILD_ROOT和$RPM_BUILD_DIR:
$RPM_BUILD_ROOT是指定義的BuildRoot,而$RPM_BUILD_DIR通常就是指/usr/src/asianux/BUILD,其中,前面的才是%file需要的。

URL:

軟件的主頁
Vendor:

軟件開發者名字,發行商或打包組織的信息,例如RedFlag Co,Ltd
Distribution:

發行版標識

例如Red Hat Linux

ExcludeArch: sparc s390  #rpm包不能在該系統結構下創建,如果是這個環境,將報錯。

ExclusiveArch: i386 ia64 #rpm包只能在給定的系統結構下創建

ExcludeOS:windows        #rpm包不能在該操作系統下創建

ExclusiveOS: linux       #rpm包只能在給定的操作系統下創建

(

%ifarch sparc s390  判斷處理器的結構

%ifnoarch i386 alpha 與上邊相反

%ifos  linux        測試操作系統

%ifnos  linux       與上邊相反

)

Icon:

file.xpm or file.gif #存儲在rpm包中的icon文件


Prefix:

%{_prefix} 這個主要是為了解決今后安裝rpm包時,並不一定把軟件安裝到rpm中打包的目錄的情況。這樣,必須在這里定義該標識,並在編寫%install腳本的時候引用,才能實現rpm安裝時重新指定位置的功能
%{_sysconfdir} 這個原因和上面的一樣,但由於%{_prefix}指/usr,而對於其他的文件,例如/etc下的配置文件,則需要用%{_sysconfdir}標識

Prefix: /usr #定義一個relocatable的包,當安裝或更新包時, #所有在/usr目錄下的包都可以映射到其他目錄,當定義Prefix時,所有%files標志的文件都要在Prefix 定 義的目錄下


BuildArch:

指編譯的目標處理器架構,noarch標識不指定,但通常都是以/usr/lib/rpm/marcros中的內容為默認值

Obsoletes:

過時的,廢棄的。

Obsoletes:anaconda-images <= 10

Provides:

指明本軟件提供一些特定的功能,以便其他rpm識別

例如:

Provides: mail-reader
Requires:

該rpm包所依賴的軟件包名稱,可以用>=或<=表示大於或小於某一特定版本,

※“>=”號兩邊需用空格隔開,而不同軟件名稱也用空格分開

例如:該包需要 libpng-devel版本至少為 1.0.20,以及zlib
Requires: libpng-devel >= 1.0.20 zlib

Requires: bzip2 = %{version}, bzip2-libs = %{version}

Requires: perl(Carp)>=3.2 需要perl模塊Carp
PreReq、Requires(pre)、Requires(post)、Requires(preun)、Requires(postun)、BuildRequires等都是針對不同階段的依賴指定
PreReq: capability >=version      #capability包必須先安裝

Conflicts:bash>=2.0              #該包和所有不小於2.0的bash包有沖突

以上三者是在安裝RPM包時要滿足.

BuildRequires:

BuildRequires: zlib-devel

BuildPreReq:

 

BuildConflicts:

這三個選項的依賴性關系在構建RPM包時就要滿足

Autoreq:

rpm_build時會為包里的二進制文件找出對應的共享庫(.so)依賴,打成RPM包后可能在安裝時提示缺少依賴並退出,要避免執行find-requires找共享庫依賴,可以加上禁用自動依賴Autoreq:no   或者設為0

Autoprov:

rpm_build時會為包里的二進制文件找出對應的共享庫(.so)依賴,打成RPM包后可能在安裝時提示缺少依賴並退出,要避免執行find-provides找共享庫依賴,可以加上禁用自動依賴Autoprov:no   或者設為0

AutoReqProv:no

rpm_build時會為包里的二進制文件找出對應的共享庫(.so)依賴,打成RPM包后可能在安裝時提示缺少依賴並退出,要避免執行find-provides與find-requires找共享庫依賴,可以加上禁用自動依賴

Autoprov:no   或者設為0 或者為flase 相當於同時設定上邊兩個的值Autoreq:和Autoprov:

上邊3個會因為順序的不同而導致結果會有所不同,一般以最后一個為准。

%triggerin -- package < version

執行腳本或者命令

#當package包安裝或更新時,或本包安裝更新且 package已經安裝時,運行script

當其所在軟件包與指定軟件包僅有一方安裝時,安裝另一方將觸發此程序執行。

%triggerun -- package

執行腳本或者命令

#當package包刪除時,或本包刪除且package已經安裝時,運行script

當其所在軟件包與指定軟件包都已安裝時,卸載任一方將觸發此程序執行。

例如:

%triggerun -- anaconda < 8.0-1

./script

%triggerpostun -- package

#當package刪除時運行script,本包刪除時不運行

指定軟件包卸載后才觸發此程序執行。

%triggerpostun -p /usr/bin/perl -- vixie-cron <3.0.1-56

-p /usr/sh package < version

-n subpackage_name –vixie-cron <3.0.1-56

...script...

-p  解釋程序

--  觸發條件

-n  子包的觸發條件等

Packager:

打包者的信息,姓名以及郵箱等,處於同一行。
�scription

軟件的詳細說明

上邊是關於RPM包信息的一些描述。

spec腳本主體

%package

#定義一個子包

%package -n sub_package_name #定義一個子包,名字為sub_package_name

當定義一個子包時,必須至少包含Summary:,Group:,�scription選項,任何沒有指定的選項將用父包的選項,如版本等,如:

%package server

Requires: xinetd

Group: System Environment/Daemons

Summary:The server program for the telnet remote login protocol

�scription server

Telnet is a popular protocol for logging into remote systems

如果在%package時用-n選項,那么在�scription時也要用,如:

�scription -n my-telnet-server

 

如果在%package時用-n選項,那么在%files時也要用,如:

%files -n my-telnet-server,也可以定義安裝或卸載腳本,像定義%files和�scription 一樣

%package devel

Summary: Header files and libraries for developing apps which will use bzip2.

Group: Development/Libraries

Requires: bzip2 = %{version}, bzip2-libs = %{version}

�scription devel

Header files and a static library of bzip2 functions, for developing apps

which will use the library.

 

%package libs

Summary: Libraries for applications using bzip2

Group: System Environment/Libraries

�scription libs

Libraries for applications using the bzip2 compression format.

 


%prep

預處理腳本,這個段是預處理段,通常用來執行一些解開源程序包的命令,為下一步的編譯安裝作准備。%prep和下面的%build,%install段一樣,除了可以執行RPM所定義的宏命令(以%開頭)以外,還可以執行SHELL命令,命令可以有很多行,如我們常寫的tar解包命令。
%preun

rpm卸載前執行的腳本
%setup

把源碼包解壓並放好
通常是從/usr/src/asianux/SOURCES里的包解壓到/usr/src/asianux/BUILD/%{name}-%{version}中。

%setup -q %{name}-%{version}
一般用%setup -q就可以了,但有兩種情況:一就是同時編譯多個源碼包,二就是源碼的tar包的名稱與解壓出來的目錄不一致,此時,就需要使用-n參數指定一下了。

%setup 不加任何選項,僅將軟件包打開。

%setup -q 在安靜模式下且最少輸出

%setup -D #在解壓之前禁止刪除目錄

%setup -a number #在改變目錄后,僅解壓給定數字的源碼,如-a 0 for source0
%setup -n newdir 將軟件包解壓到newdir目錄。
%setup -c 解壓縮之前先產生目錄。
%setup -b num 包含多個源文件時,將第num個source文件解壓縮。
%setup -T 不使用default的解壓縮操作。
%setup -T -b 0 將第0個源代碼文件SOURCE0解壓縮。
%setup -c -n newdir 指定目錄名稱newdir,並在此目錄產生rpm套件。

%patch
通常補丁都會一起在源碼tar.gz包中,或放到SOURCES目錄下。

一般參數為:
%patch -p1 使用前面定義的Patch補丁進行,-p1是忽略patch的第一層目錄
%Patch2 -p1 -b xxx.patch 打上指定的補丁,-b是指生成備份文件
%patch 最簡單的補丁方式,自動指定patch level。
%patch 0 使用第0個補丁文件,相當於%patch ?p 0。
%patch -s 不顯示打補丁時的信息。
%patch -T 將所有打補丁時產生的輸出文件刪除。

%patch #打補丁0

%patch1 #打補丁1

%patch2 #打補丁2

%patch -P 2 #打補丁2

在%build之前,%prep部分將准備好編譯工作,解開源碼包,並將相應的補丁打進去。
%build

開始編譯源碼構建包,相當於configure以及make部分

所要執行的命令為生成軟件包服務,如

%configure 這個不是關鍵字,而是rpm定義的標准宏命令。意思是執行源代碼的configure配置,可以用rpm –eval '%configure'命令查看該宏
在/usr/src/asianux/BUILD/%{name}-%{version}目錄中進行操作 ,使用標准寫法,會引用/usr/lib/rpm/marcros中定義的參數。
另一種不標准的寫法是,可參考源碼中的參數自定義,例如:

引用

CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}

make 命令
在/usr/src/asianux/BUILD/%{name}-%{version}目錄中進行make的工作 ,常見寫法:

make %{?_smp_mflags} OPTIMIZE="%{optflags}"
都是一些優化參數,定義在/usr/lib/rpm/marcros中

%check
%install

開始把軟件安裝到虛擬的根目錄中,本段是安裝段,其中的命令在安裝軟件包時將執行,如make install命令、cp、mv、install、ln。
在/usr/src/asianux/BUILD/%{name}-%{version}目錄中進行make install的操作。這個很重要,因為如果這里的路徑不對的話,則下面%file中尋找文件的時候就會失敗。 常見內容有:
%makeinstall 這不是關鍵字,而是rpm定義的標准宏命令,相當於執行make install命令那一步。

也可以使用非標准寫法:

make DESTDIR=$RPM_BUILD_ROOT install

make prefix=$RPM_BUILD_ROOT install

make INSTROOT=$RPM_BUILD_ROOT install
需要說明的是,這里的%install主要就是為了后面的%file服務的。所以,還可以使用常規的系統命令:

rm -rf ${RPM_BUILD_ROOT}

mkdir -p $RPM_BUILD_ROOT/{%{_bindir},%{_mandir}/man1,%{_libdir},%{_includedir}}

install -m 755 bzlib.h $RPM_BUILD_ROOT/%{_includedir}

install -m 644 bzip2.1 bzdiff.1 bzgrep.1 bzmore.1  $RPM_BUILD_ROOT/%{_mandir}/man1/

install -d $RPM_BUILD_ROOT/
cp -a * $RPM_BUILD_ROOT/

ln -s file/magic  ${RPM_BUILD_ROOT}%{_datadir}/magic

%find_lang  %{name}

%files -f  %{name}.lang

第一句生成一個名為%{name}.lang的文件,內容是所有的%{name}.mo,第二句意思是一個一個列舉.mo文件很麻煩,-f參數是將其后邊接的文件合並到%files的文件列表。

%clean

清除編譯和安裝時生成的臨時文件
通常內容為:

[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
rm -rf $RPM_BUILD_DIR/%{name}-%{version}
%post

rpm安裝后執行的腳本
%post libs -p /sbin/ldconfig

libs包時執行這部分動作
%postun

rpm卸載后執行的腳本
%postun libs  -p /sbin/ldconfig

 

rpm還提供了一種信號機制:不同的操作會返回不同的信息,並放到默認變量$1中。

引用

0代表卸載、1代表安裝、2代表升級


可這樣使用:

引用

%postun
if [ "$1" = "0" ]; then
/sbin/ldconfig
fi

%verifyscript #軟件包校驗腳本程序開始執行

%files

�fattr (-,root,root)

本段是文件段,用於定義構成軟件包的文件列表,那些文件或目錄會放入rpm中,分為三類-說明文檔(doc),配置文件(config)及執行程序,還可定義文件存取權限,擁有者及組別。

這里會在虛擬根目錄下進行,千萬不要寫絕對路徑,而應用宏或變量表示相對路徑。

※特別需要注意的是:%install部分使用的是絕對路徑,而%file部分使用則是相對路徑,雖然其描述的是同一個地方。千萬不要寫錯。
%files  -f %{name}.lang tui

file1 #文件中也可以包含通配符,如*

file2

directory #所有文件都放在directory目錄下

%dir /etc/xtoolwait #僅是一個空目錄/etc/xtoolwait打進包里

%doc  表示這是文檔文件,因此如安裝時使用--excludedocs將不安裝該文件,

%doc /usr/X11R6/man/man1/xtoolwait.* #安裝該文檔

%doc README NEWS #安裝這些文檔到/usr/share/doc/%{name}-%{version} 或者 /usr/doc或者

%docdir #定義說明文檔的目錄,例如/root,在這一語句后,所有以/root開頭的行都被定義為說明文件。

%config /etc/yp.conf #標志該文件是一個配置文件,升級過程中,RPM會有如下動作。

%config(missisgok) /etc/yp.conf 此配置文件可以丟失,即使丟失了,RPM在卸載軟件包時也不認為這是一個錯誤,並不報錯。一般用於那些軟件包安裝后建立的符號鏈接文件,如

/etc/rc.d/rc5.d/S55named文件,此類文件在軟件包卸載后可能需要刪除,所以丟失了也不要緊。

%config(noreplace) /etc/yp.conf

#該配置文件不會覆蓋已存在文件(RPM包中文件會以.rpmnew存在於系統,卸載時系統中的該配置文件會以.rpmsave保存下來,如果沒有這個選項,安裝時RPM包中文件會以.rpmorig存在於系統 )

覆蓋已存在文件(沒被修改),創建新的文件加上擴展后綴.rpmnew(被修改)

%{_bindir}/*

%config  /etc/aa.conf

%ghost /etc/yp.conf #該文件不應該包含在包中,一般是日志文件,其文件屬性很重要,但是文件內容不重要,用了這個選項后,僅將其文件屬性加入包中。

%attr(mode, user, group) filename #控制文件的權限如%attr(0644,root,root) /etc/yp.conf

如果你不想指定值,可以用-

%config %attr(-,root,root) filename #設定文件類型和權限

�fattr(-,root,root) #設置文件的默認權限,-表示默認值,對文本文件是0644,可執行文件是0755

%lang(en) %{_datadir}/locale/en/LC_MESSAGES/tcsh* #用特定的語言標志文件

%verify(owner group size) filename #只測試owner,group,size,默認測試所有

%verify(not owner) filename #不測試owner,測試其他的屬性

所有的認證如下:

group:  認證文件的組

maj:    認證文件的主設備號

md5:    認證文件的MD5

min:    認證文件的輔設備號

mode:   認證文件的權限

mtime:  認證文件最后修改時間

owner:  認證文件的所有者

size:   認證文件的大小

symlink:認證符號連接

 

如果描述為目錄,表示目錄中出%exclude外的所有文件。

%files
�fattr(-,root,root)

%doc
%{_bindir}/*
%{_libdir}/liba*
%{_datadir}/file

%{_infodir}/*

%{_mandir}/man[15]/*

%{_includedir}
%exclude %{_libdir}/debug

(%exclude 列出不想打包到rpm中的文件。※小心,如果%exclude指定的文件不存在,也會出錯的。)
如果把

%files
�fattr(-,root,root)
%{_bindir}
寫成

%files
�fattr(-,root,root)
/usr/bin
則打包的會是根目錄下的/usr/bin中所有的文件。

%files libs

�fattr(-,root,root)

%{_libdir}/*so.*

%files devel

�fattr(-,root,root)

%{_includedir}/*

 

由於必須在%file中包括所有套件中的文件,所以,我們需要清楚編譯完的套件到底包括那些文件,常見的做法是,人工模擬一次編譯的過程:

./configrue --prefix=/usr/local/xxx
make
make DESTDIR=/usr/local/xxx install

make prefix=/usr/local/xxx install
這樣,整個套件的內容就會被放到/usr/local/xxx中,可根據情況編寫%file和%exclude段
※當然,這個只能對源碼按GNU方式編寫,並使用GNU autotool創建的包有效,若自定義Makefile則不能一概而論。
%changelog

變更日志,本段是修改日志段。你可以將軟件的每次修改記錄到這里,保存到發布的軟件包中,以便查詢之用。每一個修改日志都有這樣一種格式:

第一行是:* 星期月日 年 修改人電子信箱。

其中:星期、月份均用英文形式的前3個字母,用中文會報錯。接下來的行寫的是修改了什么地方,可寫多行。一般以減號開始,便於后續的查 閱。

* Mon Mar 31 1997 Erik Troan <ewt@redhat.com>

 

- Fixed problems caused by 64 bit time_t.



 

 

技巧:

如果要避免生成debuginfo包:這個是默認會生成的rpm包。則可以使用下面的命令:

echo '�bug_package %{nil}' >> ~/.rpmmacros
如果rpm包已經做好,但在安裝的時候想修改默認路徑,則可以:

rpm -ivh --prefix=/opt/usr xxx.rpm
又或者同時修改多個路徑:

rpm xxx.rpm --relocate=/usr=/opt/usr --relocate=/etc=/usr/etc

所有的宏都可以在/usr/lib/rpm/macros里找到。

下面是宏對應路徑一覽表:

Macros mimicking autoconf variables

%{_sysconfdir}        /etc

 

%{_prefix}            /usr

 

%{_exec_prefix}      %{_prefix}

 

%{_bindir}           %{_exec_prefix}/bin

 

%{_lib}               lib (lib64 on 64bit systems)

 

%{_libdir}           %{_exec_prefix}/%{_lib}

 

%{_libexecdir}       %{_exec_prefix}/libexec

 

%{_sbindir}          %{_exec_prefix}/sbin

 

%{_sharedstatedir}    /var/lib

 

%{_datadir}          %{_prefix}/share

 

%{_includedir}       %{_prefix}/include

 

%{_oldincludedir}     /usr/include

 

%{_infodir}           /usr/share/info

 

%{_mandir}            /usr/share/man

 

%{_localstatedir}     /var

 

%{_initddir}         %{_sysconfdir}/rc.d/init.d

 

Note: On releases older than Fedora 10 (and EPEL),%{_initddir}does not exist. Instead, you should use the deprecated%{_initrddir}macro.

RPM directory macros

%{_topdir}           %{getenv:HOME}/rpmbuild

 

%{_builddir}         %{_topdir}/BUILD

 

%{_rpmdir}           %{_topdir}/RPMS

 

%{_sourcedir}        %{_topdir}/SOURCES

 

%{_specdir}          %{_topdir}/SPECS

 

%{_srcrpmdir}        %{_topdir}/SRPMS

 

%{_buildrootdir}     %{_topdir}/BUILDROOT

 

Note: On releases older than Fedora 10 (and EPEL),%{_buildrootdir}does not exist.

Build flags macros

%{_global_cflags}     -O2 -g -pipe

 

%{_optflags}         %{__global_cflags} -m32 -march=i386 -mtune=pentium4 # if redhat-rpm-config is installed

 

Other macros

%{_var}               /var

 

%{_tmppath}          %{_var}/tmp

 

%{_usr}               /usr

 

%{_usrsrc}           %{_usr}/src

 

%{_docdir}           %{_datadir}/doc


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM