如何編寫 RPM 的 spec 檔案

Ankur Sinha "franciscod"發表於2019-11-05

關於 RPM 軟體包構建的上一篇文章中,你瞭解到了源 RPM 包括軟體的原始碼以及 spec 檔案。這篇文章深入研究了 spec 檔案,該檔案中包含了有關如何構建 RPM 的指令。同樣,本文以 fpaste 為例。

瞭解原始碼

在開始編寫 spec 檔案之前,你需要對要打包的軟體有所瞭解。在這裡,你正在研究 fpaste,這是一個非常簡單的軟體。它是用 Python 編寫的,並且是一個單檔案指令碼。當它釋出新版本時,可在 Pagure 上找到:https://pagure.io/releases/fpaste/fpaste-0.3.9.2.tar.gz

如該檔案檔案所示,當前版本為 0.3.9.2。下載它,以便你檢視該檔案檔案中的內容:

$ wget https://pagure.io/releases/fpaste/fpaste-0.3.9.2.tar.gz
$ tar -tvf fpaste-0.3.9.2.tar.gz
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/
-rw-rw-r-- root/root        25 2018-07-25 02:58 fpaste-0.3.9.2/.gitignore
-rw-rw-r-- root/root      3672 2018-07-25 02:58 fpaste-0.3.9.2/CHANGELOG
-rw-rw-r-- root/root     35147 2018-07-25 02:58 fpaste-0.3.9.2/COPYING
-rw-rw-r-- root/root       444 2018-07-25 02:58 fpaste-0.3.9.2/Makefile
-rw-rw-r-- root/root      1656 2018-07-25 02:58 fpaste-0.3.9.2/README.rst
-rw-rw-r-- root/root       658 2018-07-25 02:58 fpaste-0.3.9.2/TODO
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/docs/
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/docs/man/
drwxrwxr-x root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/docs/man/en/
-rw-rw-r-- root/root      3867 2018-07-25 02:58 fpaste-0.3.9.2/docs/man/en/fpaste.1
-rwxrwxr-x root/root     24884 2018-07-25 02:58 fpaste-0.3.9.2/fpaste
lrwxrwxrwx root/root         0 2018-07-25 02:58 fpaste-0.3.9.2/fpaste.py -> fpaste

你要安裝的檔案是:

  • fpaste.py:應該安裝到 /usr/bin/
  • docs/man/en/fpaste.1:手冊,應放到 /usr/share/man/man1/
  • COPYING:許可證文字,應放到 /usr/share/license/fpaste/
  • README.rstTODO:放到 /usr/share/doc/fpaste/ 下的其它文件。

這些檔案的安裝位置取決於檔案系統層次結構標準(FHS)。要了解更多資訊,可以在這裡閱讀:http://www.pathname.com/fhs/ 或檢視 Fedora 系統的手冊頁:

$ man hier

第一部分:要構建什麼?

現在我們知道了原始檔中有哪些檔案,以及它們要存放的位置,讓我們看一下 spec 檔案。你可以在此處檢視這個完整的檔案:https://src.fedoraproject.org/rpms/fpaste/blob/master/f/fpaste.spec

這是 spec 檔案的第一部分:

Name:   fpaste
Version:  0.3.9.2
Release:  3%{?dist}
Summary:  A simple tool for pasting info onto sticky notes instances
BuildArch:  noarch
License:  GPLv3+
URL:    https://pagure.io/fpaste
Source0:  https://pagure.io/releases/fpaste/fpaste-0.3.9.2.tar.gz

Requires:    python3

%description
It is often useful to be able to easily paste text to the Fedora
Pastebin at http://paste.fedoraproject.org and this simple script
will do that and return the resulting URL so that people may
examine the output. This can hopefully help folks who are for
some reason stuck without X, working remotely, or any other
reason they may be unable to paste something into the pastebin

NameVersion 等稱為標籤,它們定義在 RPM 中。這意味著你不能只是隨意寫點標籤,RPM 無法理解它們!需要注意的標籤是:

  • Source0:告訴 RPM 該軟體的原始碼檔案檔案所在的位置。
  • Requires:列出軟體的執行時依賴項。RPM 可以自動檢測很多依賴項,但是在某些情況下,必須手動指明它們。執行時依賴項是系統上必須具有的功能(通常是軟體包),才能使該軟體包起作用。這是 dnf 在安裝此軟體包時檢測是否需要拉取其他軟體包的方式。
  • BuildRequires:列出了此軟體的構建時依賴項。這些通常必須手動確定並新增到 spec 檔案中。
  • BuildArch:此軟體為該計算機體系結構所構建。如果省略此標籤,則將為所有受支援的體系結構構建該軟體。值 noarch 表示該軟體與體系結構無關(例如 fpaste,它完全是用 Python 編寫的)。

本節提供有關 fpaste 的常規資訊:它是什麼,正在將什麼版本製作為 RPM,其許可證等等。如果你已安裝 fpaste,並檢視其後設資料時,則可以看到該 RPM 中包含的以下資訊:

$ sudo dnf install fpaste
$ rpm -qi fpaste
Name        : fpaste
Version     : 0.3.9.2
Release     : 2.fc30
...

RPM 會自動新增一些其他標籤,以代表它所知道的內容。

至此,我們掌握了要為其構建 RPM 的軟體的一般資訊。接下來,我們開始告訴 RPM 做什麼。

第二部分:準備構建

spec 檔案的下一部分是準備部分,用 %prep 代表:

%prep
%autosetup

對於 fpaste,這裡唯一的命令是 %autosetup。這只是將 tar 檔案檔案提取到一個新資料夾中,併為下一部分的構建階段做好了準備。你可以在此處執行更多操作,例如應用補丁程式,出於不同目的修改檔案等等。如果你檢視過 Python 的源 RPM 的內容,那麼你會在那裡看到許多補丁。這些都將在本節中應用。

通常,spec 檔案中帶有 字首的所有內容都是 RPM 以特殊方式解釋的巨集或標籤。這些通常會帶有大括號,例如 %{example}

第三部分:構建軟體

下一部分是構建軟體的位置,用 %build 表示。現在,由於 fpaste 是一個簡單的純 Python 指令碼,因此無需構建。因此,這裡是:

%build
#nothing required

不過,通常來說,你會在此處使用構建命令,例如:

configure; make

構建部分通常是 spec 檔案中最難的部分,因為這是從原始碼構建軟體的地方。這要求你知道該工具使用的是哪個構建系統,該系統可能是許多構建系統之一:Autotools、CMake、Meson、Setuptools(用於 Python)等等。每個都有自己的命令和語法樣式。你需要充分了解這些才能正確構建軟體。

第四部分:安裝檔案

軟體構建後,需要在 %install 部分中安裝它:

%install
mkdir -p %{buildroot}%{_bindir}
make install BINDIR=%{buildroot}%{_bindir} MANDIR=%{buildroot}%{_mandir}

在構建 RPM 時,RPM 不會修改你的系統檔案。在一個可以正常執行的系統上新增、刪除或修改檔案的風險太大。如果發生故障怎麼辦?因此,RPM 會建立一個專門打造的檔案系統並在其中工作。這稱為 buildroot。 因此,在 buildroot 中,我們建立由巨集 %{_bindir} 代表的 /usr/bin 目錄,然後使用提供的 Makefile 將檔案安裝到其中。

至此,我們已經在專門打造的 buildroot 中安裝了 fpaste 的構建版本。

第五部分:列出所有要包括在 RPM 中的檔案

spec 檔案其後的一部分是檔案部分:%files。在這裡,我們告訴 RPM 從該 spec 檔案建立的檔案檔案中包含哪些檔案。fpaste 的檔案部分非常簡單:

%files
%{_bindir}/%{name}
%doc README.rst TODO
%{_mandir}/man1/%{name}.1.gz
%license COPYING

請注意,在這裡,我們沒有指定 buildroot。所有這些路徑都是相對路徑。%doc%license命令做的稍微多一點,它們會建立所需的資料夾,並記住這些檔案必須放在那裡。

RPM 很聰明。例如,如果你在 %install 部分中安裝了檔案,但未列出它們,它會提醒你。

第六部分:在變更日誌中記錄所有變更

Fedora 是一個基於社群的專案。許多貢獻者維護或共同維護軟體包。因此,當務之急是不要被軟體包做了哪些更改所搞混。為了確保這一點,spec 檔案包含的最後一部分是變更日誌 %changelog

%changelog
* Thu Jul 25 2019 Fedora Release Engineering < ...> - 0.3.9.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild

* Thu Jan 31 2019 Fedora Release Engineering < ...> - 0.3.9.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild

* Tue Jul 24 2018 Ankur Sinha  - 0.3.9.2-1
- Update to 0.3.9.2

* Fri Jul 13 2018 Fedora Release Engineering < ...> - 0.3.9.1-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild

* Wed Feb 07 2018 Fedora Release Engineering < ..> - 0.3.9.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild

* Sun Sep 10 2017 Vasiliy N. Glazov < ...> - 0.3.9.1-2
- Cleanup spec

* Fri Sep 08 2017 Ankur Sinha  - 0.3.9.1-1
- Update to latest release
- fixes rhbz 1489605
...
....

spec 檔案的每項變更都必須有一個變更日誌條目。如你在此處看到的,雖然我以維護者身份更新了該 spec 檔案,但其他人也做過更改。清楚地記錄變更內容有助於所有人知道該 spec 檔案的當前狀態。對於系統上安裝的所有軟體包,都可以使用 rpm 來檢視其更改日誌:

$ rpm -q --changelog fpaste

構建 RPM

現在我們準備構建 RPM 包。如果要繼續執行以下命令,請確保遵循上一篇文章中的步驟設定系統以構建 RPM。

我們將 fpaste 的 spec 檔案放置在 ~/rpmbuild/SPECS 中,將原始碼檔案檔案儲存在 ~/rpmbuild/SOURCES/ 中,現在可以建立源 RPM 了:

$ cd ~/rpmbuild/SPECS
$ wget https://src.fedoraproject.org/rpms/fpaste/raw/master/f/fpaste.spec

$ cd ~/rpmbuild/SOURCES
$ wget https://pagure.io/fpaste/archive/0.3.9.2/fpaste-0.3.9.2.tar.gz

$ cd ~/rpmbuild/SOURCES
$ rpmbuild -bs fpaste.spec
Wrote: /home/asinha/rpmbuild/SRPMS/fpaste-0.3.9.2-3.fc30.src.rpm

讓我們看一下結果:

$ ls ~/rpmbuild/SRPMS/fpaste*
/home/asinha/rpmbuild/SRPMS/fpaste-0.3.9.2-3.fc30.src.rpm

$ rpm -qpl ~/rpmbuild/SRPMS/fpaste-0.3.9.2-3.fc30.src.rpm
fpaste-0.3.9.2.tar.gz
fpaste.spec

我們看到源 RPM 已構建。讓我們同時構建源 RPM 和二進位制 RPM:

$ cd ~/rpmbuild/SPECS
$ rpmbuild -ba fpaste.spec
..
..
..

RPM 將向你顯示完整的構建輸出,並在我們之前看到的每個部分中詳細說明它的工作。此“構建日誌”非常重要。當構建未按預期進行時,我們的打包人員將花費大量時間來遍歷它們,以跟蹤完整的構建路徑來檢視出了什麼問題。

就是這樣!準備安裝的 RPM 應該位於以下位置:

$ ls ~/rpmbuild/RPMS/noarch/
fpaste-0.3.9.2-3.fc30.noarch.rpm

概括

我們已經介紹瞭如何從 spec 檔案構建 RPM 的基礎知識。這絕不是一份詳盡的文件。實際上,它根本不是文件。它只是試圖解釋幕後的運作方式。簡短回顧一下:

  • RPM 有兩種型別:源 RPM 和 二進位制 RPM。
  • 二進位制 RPM 包含要安裝以使用該軟體的檔案。
  • 源 RPM 包含構建二進位制 RPM 所需的資訊:完整的原始碼,以及 spec 檔案中的有關如何構建 RPM 的說明。
  • spec 檔案包含多個部分,每個部分都有其自己的用途。    在這裡,我們已經在安裝好的 Fedora 系統中本地構建了 RPM。雖然這是個基本的過程,但我們從儲存庫中獲得的 RPM 是建立在具有嚴格配置和方法的專用伺服器上的,以確保正確性和安全性。這個 Fedora 打包流程將在以後的文章中討論。

你想開始構建軟體包,並幫助 Fedora 社群維護我們提供的大量軟體嗎?你可以從這裡開始加入軟體包集合維護者

如有任何疑問,請釋出到 Fedora 開發人員郵件列表,我們隨時樂意為你提供幫助!

參考

這裡有一些構建 RPM 的有用參考:


via: https://fedoramagazine.org/how-rpm-packages-are-made-the-spec-file/

作者:Ankur Sinha FranciscoD 選題:lujun9972 譯者:wxy 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出

如何編寫 RPM 的 spec 檔案

訂閱“Linux 中國”官方小程式來檢視

相關文章