From Fedora Project Wiki
Line 113: Line 113:
如果該程式使用 GNU info 檔案,你需要確保軟體包的安裝與解除安裝都不會干擾到系統上的其他軟體,請遵循下列這段一成不變的陳腐規則:
如果該程式使用 GNU info 檔案,你需要確保軟體包的安裝與解除安裝都不會干擾到系統上的其他軟體,請遵循下列這段一成不變的陳腐規則:


* 刪除 %install 中的 'dir' 檔案 in :  <code>rm -f %{buildroot}/%{_infodir}/dir</code>
* 刪除 %install 中的 'dir' 檔案: <code>rm -f %{buildroot}/%{_infodir}/dir</code>
* <code>Requires(post): info</code> 與 <code>Requires(preun): info</code>
* <code>Requires(post): info</code> 與 <code>Requires(preun): info</code>
* 加入下列步驟:
* 加入下列步驟:

Revision as of 13:24, 12 May 2013

翻譯中...

這是製作 RPM 檔案的簡短快速上手教程,內容包括如何快速設置以製作出簡單的源碼軟體包或二進位軟體包。本文假設您對於預製好的 RPM 軟體包使用、以及對於軟體建置流程有一定的熟悉。

如果想澈底瞭解如何建立出 RPM 檔案的相關資訊,像是詳細的秘訣等,請參考 How to create an RPM package。若您計畫為 Fedora 軟體庫建立 RPM 軟體包,請遵守 How to join the Fedora Package Collection Maintainers 所規範的流程,以及遵守各種 Fedora 規約。

本教程旨在展示 GNU "Hello World" 專案的打包過程。你可能會想說何不打包個簡單 C 語言 Hello World 呢?相比於可將「Hello World」印出至標準輸出上的平凡 C 語言程式,GNU 版本的 Hello World 則包含典型 FOSS 軟體專案所需的常用週邊元件,像是組態/建置/安裝 (configuration/build/install) 環境、文件、國際化... 等。而這個傳統的 GNU 版本,是由一個包含源碼、configure/make 指令稿的封存 tar 檔構成,也不包含打包相關資訊;因此,這是個練習建置 RPM 的絕佳方式。

開發環境

要建置出 RPM,我們需要一套開發工具。這是一次性設置工作,請以系統管理 (root) 帳戶安裝:

# yum install @development-tools
# yum install fedora-packager

若您想在乾淨的 chroot 中測試建置程序,您需要將您的無特權帳號加入「mock」群組中:

# usermod -a -G mock <your username>

以上這些是需要 root 特權的指令。所有剩下的動作都可用您平常的、無特權的帳號,或甚至特地建立給開發工作使用的個別帳戶處理。現代以 RPM 為基礎的系統,包括 Fedora,都可以完全在無特權帳號下建置與測試 RPM 軟體包。指令

$ rpmdev-setuptree

會在您的 ~/rpmbuild 目錄下設置出個 RPM 建置專用區。此目錄包含許多子目錄,供專案源碼、RPM 組態檔、成果源碼包與二進位源碼包使用。

建置 "Hello World" RPM

我們首先需要準備好打包用的軟體專案源碼,一般我們稱之為「上游 (upstream)」源碼。我們先從專案網站上下載源碼,並放到 ~/rpmbuild/SOURCE 目錄中。我們取得的是壓縮的 tarball 封存檔,這種檔案同時也是大多數 FOSS 專案偏好的源碼散布方式。

$ cd ~/rpmbuild/SOURCES
$ wget http://ftp.gnu.org/gnu/hello/hello-2.8.tar.gz

RPM 軟體包透過 .spec 檔案來控制相關設定。我們會在適當地目錄下建立一份範本檔 hello.spec

$ cd ~/rpmbuild/SPECS
$ rpmdev-newspec hello

近期的 Emacsvi 版本都有 .spec 檔案編輯模式,可以自動帶出可製作出新檔的類似範本檔。所以你可以直接用下列範例指令,可自動使用其範本功能。

vi hello.spec

.spec 檔案內部

The fields in our我們 .spec 檔案中的欄位需要稍微編輯一下。請遵循 Fedora 規則 來填寫這些欄位。就這個例子而言,檔案大概如下起頭:

Name:     hello
Version:  2.8
Release:  1
Summary:  The "Hello World" program from GNU
License:  GPLv3+
URL:      http://ftp.gnu.org/gnu/hello    
Source0:  http://ftp.gnu.org/gnu/hello/hello-2.8.tar.gz

%description
The "Hello World" program, done with all bells and whistles of a proper FOSS 
project, including configuration, build, internationalization, help files, etc.

%changelog
* Thu Jul 07 2011 The Coon of Ty <Ty@coon.org> - 2.8-1
- Initial version of the package

Version 欄位應該與上游相同,而 Release 版號則根據我們在 Fedora 中處理的成品而定。

Summary 欄位的第一個字母應該採用大寫,rpmlint 才不會對它有意見。

至於該軟體的 License 狀態為何,應由打包者自己擔負起檢查的責任。檢查方法包括審閱源碼檔與/或其 LICENSE 檔,以及直接跟作者請教。

Group 標籤是一項歷史傳承,用來分類軟體包,應與 /usr/share/doc/rpm-<version>/GROUPS 列出的清單一致。但我們將逐步淘汰它的使用,因此預設情況下不會加入。不過如果你想加它也無妨,目前無害。

%changelog 欄位應該紀錄您 RPM 的準備工作,尤其是您在上游源碼的基礎上還納入一些安全性修補、臭蟲修補的情況下更要仔細寫出。Changelog 資料可由 rpm --changelog -q <packagename> 顯示,這對於要找出安裝的軟體是否已有特定的安全性修補、臭蟲修補的情況下非常有用。勤勞的 Fedora 打包者會將這些資訊以相關的 CVE 編號納入其中。

changelog 條目應該包含版本字串以避免 rpmlint 產生抱怨。

多列的段落,像是 %changelog %description 在指令下方一列開始撰寫,並以空白列結尾。

不需要的列 (例如,BuildRequiresRequires) 可以用井字號 ('#') 直接註解掉。

許多案例中,不少範本中的列都根本不需要更改,at least for the initial attempt。

建置軟體包

我們已準備好執行第一次的源碼包、二進位包、除錯包建置:

$ rpmbuild -ba hello.spec

它會抱怨一下,並列出未打包的檔案,例如那些會安裝到系統中,卻沒有宣告屬於該軟體包的檔案。我們需要在 %files 區段中宣告這些檔案。請務必不要將路徑寫死,像是使用 /usr/bin/ 這類寫法,而是改用巨集寫法,例如 %{_bindir}/hello。使用手冊等類似頁面,則應在 %doc 子區段下宣告:%doc %{_mandir}/man1/hello.1.gz

這個階段的程序是重復性動作:編輯 .spec 檔、回來 rpmbuild 如此不斷反復。

因為我們的程式有使用到翻譯與國際化處理,所以我們會看到一大堆未宣告的 i18 檔案。宣告它們的 建議方法 如下:

  • find the filenames in the %install step: %find_lang %{name}
  • add the required build dependencies: BuildRequires: gettext
  • use the found filenames %files -f %{name}.lang

如果該程式使用 GNU info 檔案,你需要確保軟體包的安裝與解除安裝都不會干擾到系統上的其他軟體,請遵循下列這段一成不變的陳腐規則:

  • 刪除 %install 中的 'dir' 檔案: rm -f %{buildroot}/%{_infodir}/dir
  • Requires(post): infoRequires(preun): info
  • 加入下列步驟:
%post
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :

%preun
if [ $1 = 0 ] ; then
/sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
fi

完整的 hello.spec

以下是 hello.spec 的初始版本:

Name:           hello
Version:        2.8
Release:        1%{?dist}
Summary:        The "Hello World" program from GNU

License:        GPLv3+
URL:            http://ftp.gnu.org/gnu/%{name}
Source0:        http://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.gz

BuildRequires: gettext
      
Requires(post): info
Requires(preun): info

%description 
The "Hello World" program, done with all bells and whistles of a proper FOSS 
project, including configuration, build, internationalization, help files, etc.

%prep
%setup -q

%build
%configure
make %{?_smp_mflags}

%install
%make_install
%find_lang %{name}
rm -f %{buildroot}/%{_infodir}/dir

%post
/sbin/install-info %{_infodir}/%{name}.info %{_infodir}/dir || :

%preun
if [ $1 = 0 ] ; then
/sbin/install-info --delete %{_infodir}/%{name}.info %{_infodir}/dir || :
fi

%files -f %{name}.lang
%doc AUTHORS ChangeLog COPYING NEWS README THANKS TODO
%{_mandir}/man1/hello.1.gz
%{_infodir}/%{name}.info.gz
%{_bindir}/hello

%changelog
* Tue Sep 06 2011 The Coon of Ty <Ty@coon.org> 2.8-1
- Initial version of the package

With this spec file, you should be able to successfully complete the build process, and create the source and binary RPM packages.

Next you should check them for conformance with RPM design rules, by running rpmlint on the spec file and all RPMs:

$ rpmlint hello.spec ../SRPMS/hello* ../RPMS/*/hello*

If there are no warnings or errors, we've succeeded. Otherwise, use rpmlint -i or rpmlint -I <error_code> to see a more verbose description of the rpmlint diagnostics.

mock 組建

若要檢查軟體包組建在 Fedora 受限的建置環境中是否成功,可以用 mock 來檢查。預設的 mock 組態會以 Rawhide - Fedora 開發分支為對象建置軟體包。

$ mock --verbose ../SRPMS/hello-2.7-1.fc19.src.rpm

參考資料

歷史

Przemek Klosowski wrote this tutorial when he worked through Christoph Wickert's IRC session on building RPMs using Rahul Sundaram suggestion of GNU "Hello World" as a test case. After he wrote up his experience, he found out about the excellent and extensive How to create an RPM package page on this wiki, as well as the Christian Lyder Jacobsen's website. However, Christian isn't planning to update his site, and it seemed that a 5-minute 'fast food' alternative to the more extensive article might suit some people. More in-depth information on using and building RPM packages is available from other sources.