本文出自:MacBlog2

 


 

一、準備工作
1.要打包套件,必須先安裝 rpm-build 套件

sudo yum install rpm-build

2.建立打包套件的環境
在 FC5 後,並不建議用 root 來打包套件,所以請改用一般的使用者身份來打包套件
首先要安裝 fedora-rpmdevtools 這個套件

sudo yum install fedora-rpmdevtools

接著執行 fedora-buildrpmtree 來建立打包的環境

fedora-buildrpmtree

執行完後,在 Home 目錄底下就產生 rpmbuild 的目錄
在 rpmbuild 目錄底下又有 BUILD RPMS SOURCES SPECS SRPMS 五個子目錄

BUILD    編譯時所用的暫存目錄
RPMS 放置打包好的套件
SOURCES 放置套件的原始碼及修補檔等等
SPECS 放置 .spec 檔
SRPMS 放置 Source RPMS (.src.rpm)

3.建立 ~/.rpmmacros 檔案
編輯 ~/.rpmmacros,主要是設定 %packager 及 %vendor 等等:

%_topdir %(echo $HOME)/rpmbuild
%_smp_mflags -j3
%__arch_install_post /usr/lib/rpm/check-rpaths /usr/lib/rpm/check-buildroot
%packager Chung-Yen Chang <candyz0416@gmail.com>
%vendor Chinese Linux Extensions

如果有 GPG Key 可以加上類似底下幾行,到時候要 GPG Sign 時會用到:

%_signature gpg
%_gpg_path ~/.gnupg
%_gpg_name Chung-Yen Chang (candyz) <candyz0416@gmail.com>
%_gpgbin /usr/bin/gpg

二、建立 spec 檔案
我以打包 pcmanfm-0.3.0-beta3.tar.gz 為例
假設這個套件沒有人打包過,因此必須自行建立 pcmanfm.spec 檔案
先進到 ~/rpmbuild/SPECS 目錄底下:

cd ~/rpmbuild/SPECS

1.利用 fedora-newrpmspec 工具程式來產生一個 spec 檔的樣本,然後再慢慢來修改

fedora-newrpmspec pcmanfm

執行完後,就會產生 pcmanfm.spec
spec 檔的命名規則為 %{name}.spec
spec 檔的 Encoding 必須為 UTF-8

2.編輯 pcmanfm.spec
2.1.Version、Release 及 Summary

Version:        0.3.0
Release: 0.1.beta3%{?dist}
Summary: PCMan File Manager

Version Tag 及 Release Tag 的命名規則,請參考:
http://fedoraproject.org/wiki/Packaging/NamingGuidelines

Version Tag 要是數字才行
pcmanfm-0.3.0-beta3 算是 Pre-release packages
(Version 中包含 「alpha」, 「beta」, 「rc」, 「cvs」)
我們不能直接用在 Version 中,beta3 的部份要改放到 Release 中

Release Tag for Pre-Release Packages:

格式: 0.%{X}.%{alphatag}
0 不變
%{X} 從 1 開始遞增
%{alphatag} 來自於 Version Tag 中的字串

所以 pcmanfm-0.3.0-beta3 的 Release Tag 就是 0.1.beta3
至於後面的 Dist Tag (%{?dist}) 則是給 mock build 時用的
Dist Tag 請參考: http://fedoraproject.org/wiki/Packaging/DistTag

2.2.Group、License、URL、Source、Patch 及 BuildRoot

Group:          Applications/System
License: GPL
URL: http://pcmanfm.sourceforge.net
Source0: http://jaist.dl.sourceforge.net/sourceforge/pcmanfm/pcmanfm-0.3.0-beta3.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)

Group 部份請參考:
/usr/share/doc/rpm-*/GROUPS 或是 http://fedoraproject.org/wiki/RPMGroups

Source 部份,最好是包含整個網址,而不要只有檔名而已
若有好幾個 Source 則用 Source0 Source1 Source2 … 依此類推
若有 Patch 檔就需要用到 (例: Patch0: pcmanfm-0.3.0-beta3-Makefile.patch)
若有好幾個 Pacth 則用 Patch0 Patch1 Patch2 … 依此類推

必要時需要自己製作 patch 檔案,例:

cd ~/rpmbuild/BUILD/pcmanfm-0.3.0-beta3
cp Makefile Makefile.orig
然後修改 Makefile
cd ~/rpmbuild/BUILD
gendiff pcmanfm-0.3.0-beta3 .Makefile < ../SOURCES/pcmanfm-0.3.0-beta3-Makefile.patch

2.3.BuildRequires 及 Requires

BuildRequires:  automake >= 1.9, gtk2-devel >= 2.6, gamin-devel
Requires: gtk2 >= 2.6, gamin

BuildRequires 及 Requires 的部份就要看原作者是否有提到需要哪些套件
不然,就得從 mock build 時的 build.log 中
慢慢去找出所需要的 BuildRequires 及 Requires

2.4.%description

%description
PCMan File Manager
An extremly fast and lightweight file manager which features tabbed browsing
and user-friendly interface

Features:
Extremly fast and lightweight
Can be started in one second on normal machine
Tabbed browsing (Similar to Firefox)
Drag & Drop support
Files can be dragged among tabs
Load large directories in reasonable time
File association support (Default application)
Basic thumbnail support
Bookmarks support
Handles non-UTF-8 encoded filenames correctly
Provide icon view and detailed list view
Standard compliant (Follows FreeDesktop.org)
Clean and user-friendly interface (GTK+ 2)

%description 要注意的是,每一行最長不要超過 79 個字元

2.5.%changelog

%changelog
* Fri Aug 18 2006 Chung-Yen Chang <candyz0416@gmail.com> - 0.3.0-0.1.beta3
- Initial RPM release

%changelog 部份,就是日期、打包者的姓名及 E-mail 等等
最後面則是要包含這次的 %{version}-%{release}
若有使用 Epoch Tag 則是 %{Epoch}:%{version}-%{release}

2.6.%prep

%prep
%setup -q -n pcmanfm-0.3.0-beta3

%setup macro 會把 source code tarball 解開並自動進到 %{name}-%{version} 的目錄中
因為我們把 Version Tag 0.3.0-beta3 的 beta3 拆到 Release Tag 去
Version Tag 變成 0.3.0,所以 %setup 在 rpmbuild 時會出問題
rpmbuild 會解開 pcmanfm-0.3.0-beta3.tar.gz 並試著進到 pcmanfm-0.3.0 (%{name}-%{version}) 的目錄中
但實際上應該是要進到 pcmanfm-0.3.0-beta3 的目錄才對
因此,我們必須加上 -n pcmanfm-0.3.0-beta3 來解決這個問題
若有 Source2 Source5 等等的 tarball 同時也要解開時,可以使用 -a 參數來指定 (例: %setup -q -a 2 -a 5)
若有 Patch 檔則同樣在這裡做處理 (例: %patch1 -p1 -b .bak)
其他一些在正式 build (make) 前要做的特殊處理,都可以在這裡做
(例: find . -name \*.h -o -name \*.c | xargs chmod ugo-x)

2.7.%build

%build
%configure
make %{?_smp_mflags}

若有需要加 configure 的參數,可以加在 %configure 後面
(例: %configure –prefix=%{_prefix})
若還有其他的編譯指令需要執行時,都可以加在這裡

2.8.%install

%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
%find_lang %{name}
desktop-file-install \
--delete-original \
--vendor fedora \
--dir ${RPM_BUILD_ROOT}/%{_datadir}/applications \
--add-category X-Fedora \
${RPM_BUILD_ROOT}/%{_datadir}/applications/pcmanfm.desktop

若還有其他相關的安裝指令都可以加在這裡
至於 locale mo 檔的部份,則是要改用 %find_lang macro 來處理
另外,關於 desktop 檔的部份,要在 %install 中使用 desktop-file-install 來處理
然後在 %files 中加入一行:

%{_datadir}/applications/fedora-pcmanfm.desktop

BuildRequires 的部份也要加入 desktop-file-utils:

BuildRequires:  automake >= 1.9, gtk2-devel >= 2.6, gamin-devel, desktop-file-utils

另外還要加入:

Requires(post): desktop-file-utils
Requires(postun): desktop-file-utils

%post 及 %postun 的部份也要做處理
Desktop files 請參考: http://fedoraproject.org/wiki/Packaging/Guidelines#desktop

2.9.%clean

%clean
rm -rf $RPM_BUILD_ROOT

2.10.%files

%files -f %{name}.lang
%defattr(-,root,root,-)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO
%{_datadir}/applications/fedora-pcmanfm.desktop

%files 後面的 -f %{name}.lang 則是跟 %find_lang macro 搭配
用來處理 locale mo 檔
%doc 部份,則是放 AUTHORS COPYING ChangeLog INSTALL NEWS README TODO 等文件
至少要放版權的部份 (如 License: GPL 則 COPYING 的內容就是放 GPL 版權的內容)
若不知道還會安裝哪些檔案也沒關係,之後可以利用 rpmbuild -bi 的 log 來查詢

2.11.%post

%post
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :

用來處理套件安裝完成後要執行的指令
例如 update-desktop-database 那行就是在處理 Desktop files 部份

2.12.%postun

%postun
update-desktop-database %{_datadir}/applications >/dev/null 2>&1 || :

用來處理套件移除後要執行的指令
例如 update-desktop-database 那行就是在處理 Desktop files 部份

2.13.%pre
用來處理套件安裝前要執行的指令
在本例中沒有用到

2.14.%preun
用來處理套件移除前要執行的指令
在本例中沒有用到

三、測試打包
除了 %files 的部份還沒完全處理完外,其他部份大致上都沒問題了

1.rpmbuild -bc
rpmbuild -bc 會從一開始一直做到 %build 為止
用來檢查到 %build 為止是否還有問題
若有發現任何錯誤,如 command not found 等等
就要去 check required package 然後加到 Requires/BuildRequires 中

rpmbuild -bc pcmanfm.spec

像我一執行時就出現錯誤:

checking for PACKAGE... configure: error: Package requirements (gtk+-2.0 >= 2.6.
0 gthread-2.0 libstartup-notification-1.0) were not me
t:

No package 'libstartup-notification-1.0' found

查了一下,所需要的套件是 startup-notification-devel

[candyz@candyz:~/rpmbuild/SPECS] locate libstartup-notification-1.0
/usr/lib/pkgconfig/libstartup-notification-1.0.pc
[candyz@candyz:~/rpmbuild/SPECS] rpm -qf /usr/lib/pkgconfig/libstartup-notification-1.0.pc
startup-notification-devel-0.8-3.2.1

因此,修改 BuildRequires 如下:

BuildRequires:  automake >= 1.9, gtk2-devel >= 2.6, gamin-devel, desktop-file-utils, gettext, startup-notification-devel

加進了 startup-notification-devel
而多加了 gettext 則是給 mock build 用的
因為在 mock build 時會去 check 是否有 gettext,有才會去執行 %find_lang macro

2.rpmbuild -bi
rpmbuild -bi 會從一開始一直做到 %install 為止

rpmbuild -bi pcmanfm.spec

例如我執行完的結果,看到以下的警告訊息:

warning: Installed (but unpackaged) file(s) found:
/usr/bin/pcmanfm
/usr/share/applications/pcmanfm.desktop
/usr/share/locale/ca/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/de/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/es/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/fr/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/hu/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/it/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/pl/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/pt_BR/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/ru/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/sv_SE/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/zh_CN/LC_MESSAGES/pcmanfm.mo
/usr/share/locale/zh_TW/LC_MESSAGES/pcmanfm.mo

因此,可以得知,%files 中還少了 /usr/bin/pcmanfm
至於 locale 的 mo 檔部份,可以不用管,改交給 %find_lang macro 去處理了
而 /usr/share/applications/pcmanfm.desktop 則改由 desktop-file-install 處理
因此,修改後的 %files 部份如下:

%files -f %{name}.lang
%defattr(-,root,root,-)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO
%{_bindir}/pcmanfm
%{_datadir}/applications/fedora-pcmanfm.desktop

相關的 macros 可以在 http://fedoraproject.org/wiki/Extras/RPMMacros 查詢到
常見的如:

%{_sysconfdir}        /etc
%{_initrddir} %{_sysconfdir}/rc.d/init.d
%{_prefix} /usr
%{_exec_prefix} %{_prefix}
%{_bindir} %{_exec_prefix}/bin
%{_lib} lib
%{_libdir} %{_exec_prefix}/%{_lib}
%{_libexecdir} %{_exec_prefix}/libexec
%{_sbindir} %{_exec_prefix}/sbin
%{_sharedstatedir} %{_prefix}/com
%{_datadir} %{_prefix}/share
%{_includedir} %{_prefix}/include
%{_oldincludedir} /usr/include
%{_var} /var
%{_tmppath} %{_var}/tmp

請儘量改用 macros 來取代 /etc /usr/bin /usr/lib 的寫法

3.rpmbuild -bs、rpmbuild -bb and rpmbuild -ba
若 rpmbuild -bi 都沒錯誤,接下來就可以開始打包套件了

3.1.用 rpmbuild -bs 來產生 SRPMS

rpmbuild -bs pcmanfm.spec

3.2.用 rpmbuild -bb 來產生 RPMS

rpmbuild -bb pcmanfm.spec

3.3.用 rpmbuild -ba 來同時產生 SRPMS 及 RPMS

rpmbuild -ba pcmanfm.spec

四、使用 rpmlint 來檢查 SRPMS RPMS

rpmlint -i ~/rpmbuild/SRPMS/pcmanfm-0.3.0-0.1.beta3.src.rpm
rpmlint -i ~/rpmbuild/RPMS/i386/pcmanfm-*.rpm

rpmlint 的錯誤訊息請參考:
http://fedoraproject.org/wiki/ParagNemade/CommonRpmlintErrors
及 http://fedoraproject.org/wiki/Packaging/CommonRpmlintIssues

五、使用 mock 來 chroot build
mock 是一個 Chroot Build Tools
關於 mock 的安裝、設定及使用請參考: http://blog.candyz.org/20060818/1307

mock -r fedora-5-i386-core.cfg ~/rpmbuild/SRPMS/pcmanfm-0.3.0-0.1.beta3.src.rpm

六、其他進階部份
1.devel subpackage
所有的可執行檔及 *.so.* 要放在 main package
而所有的 headers, static libraries, libtool archives, *.so files, autotools,
and pkgconfig files 則要放在 -devel subpackage.

若套件有包含一些不重要的 examples 時,可以在 %install 最後的地方刪除掉
把 examples 改放到 -devel 的 %doc 中

請參考:
http://fedoraproject.org/wiki/Docs/Drafts/BuildingPackagesGuide 的範例

2.不需要加到 BuildRequires 中的 Exceptions

bash
bzip2
coreutils
cpio
diffutils
fedora-release (and/or redhat-release)
gcc
gcc-c++
gzip
make
patch
perl
redhat-rpm-config
rpm-build
sed
tar
unzip

which

詳細清單請參考: http://fedoraproject.org/wiki/Extras/FullExceptionList

3.Documentation
若有相關的說明文件,可以獨立成 -doc subpackage
並以 Documentation 當作 Group Tag

4.Configuration files
設定檔請使用 %config(noreplace) 來代替 %config
只有當設定檔有變時,才改用 %config 來覆蓋掉舊的

5.Macros
詳細的 Macros 請參考: http://fedoraproject.org/wiki/Extras/RPMMacros

6.不要使用 %makeinstall macro
直接用:

make DESTDIR=$RPM_BUILD_ROOT install

7.Fedora RPM Development Tools
fedora-rpmdevtools,請參考: http://fedoraproject.org/wiki/fedora-rpmdevtools

8.RPM scriptlet recipes
關於 %pre %post %preun %postun 的用法及注意事項,請參考:
http://fedoraproject.org/wiki/Packaging/ScriptletSnippets

七、GPG Sign
1.rpmbuild –sign
在執行 rpmbuild 時加上 –sign 的參數

2.rpm –addsign
若在 rpmbuild 時沒有使用 –sign 參數,也可以事後再用 rpm –addsign 來 Sign 套件

八、參考文件
http://fedoraproject.org/wiki/Docs/Drafts/BuildingPackagesGuide
http://koti.welho.com/vskytta/packagers-handbook/packagers-handbook.html
http://fedoraproject.org/wiki/Packaging/Guidelines
http://fedoraproject.org/wiki/ParagNemade/PackagingNotes
http://www.rpm.org/max-rpm/

附錄一、完整的 pcmanfm.spec


延伸閱讀:

1.Fedora wiki:RPM打包機學 (正體中文)

2.待續

創作者介紹

胖虎的祕密基地

idobest 發表在 痞客邦 PIXNET 留言(0) 人氣()