重建一個源代碼 RPM

這份文件會指引你如何在你的 CentOS 發行版本上重建一個源代碼 RPM(SRPM)。

你想如此做的其中一個原因可能是去安裝不附帶於 CentOS 軟件庫內的軟件。就算 CentOS 並不提供這個軟件,你亦應該盡量嘗試取得或建立這個軟件的 RPM,因為採用套件管理系統所得的好處會補償你花費在包裝套件上的工夫。使用一個套件管理系統來處理互賴性相比起安裝源代碼提供不少優勢。建立套件後,你或許會考慮建立一個本地的軟件庫,並透過 yum 或圖像介面工具來簡化套件管理。

你是否真的需要重建?

首先請考慮重建 SRPM 將會為你帶來的負擔。每次當有安全性更新發佈時,你須維護及重建它。在你決定重建一個 SRPM 前,你應該檢查所需的套件是否已經藏在現存的軟件庫內。

多數採用軟件庫的用戶期望穫得支援(郵件列表、論壇、錯誤追蹤器、IRC 頻道),以及套件備有安全性及功能上的更新。在 Wiki 的「軟件庫」頁面所列出的網站大多數都有這些資源及功能,但某些則沒有。舉例說,CentOS 'testing' 軟件庫刻意提供升級的途徑。唯有那些以適當的 CentOS GPG 金鑰簽署的套件才算是 CentOS 計劃的產品。

從那裡取得 SRPM 套件

重建一個 SRPM 套件的成功率主要視乎該發行版本與 CentOS 有多近似。舉個例說,你幾乎肯定能成功地重建同一主要版本的 Red Hat 或 CentOS 套件。你也可考慮其它以 Red Hat 為基礎的發行版本的 SRPM,例如 Scientific Linux,因為它們傾向兼容 CentOS 的 base 套件。由於 Red Hat(從而 CentOS)是以 Fedora 的某個穩定子集作為基礎,所以你往往能在 CentOS 重建來自 Fedora 的 SRPM。重建更高版本的 Red Hat 或 CentOS 套件的成數亦很高;在 CentOS-5 上重建來自 Fedora Core 6 或 Fedora 7 的 SRPM 的成數依然偏高;然而重建更高版本 Fedora 的套件的成數便較低了,因為它們與從 FC6 測試版本分支出來的 EL5 存有很大差異。延至 Fedora 11,某至 SRPM 在 CentOS-5 依然能順利地重建,但安裝 F11 或更新的SRPM 時,rpm 指令必須使用 "--nomd5" 選項。針對 CentOS-6,相應的 Fedora 版本是 12/13,亦即是 EL6 的分支版本,很多 Fedora 14 及更新版的 SRPM 也能順利地重建。至於其他以 RPM 為基礎的發行版本,例如 Mandriva 或 SuSE,重建它們的 SRPM 的成數是中等到低。最後,有些跨發行版本的開源軟件亦備有 SRPM 格式。你或許能透過下列指引在你的系統上重建這些 SRPM。

重建 SRPM 時,系統的附加套件比核心套件成功率高。要是你要重建的 SRPM 需要把核心套件更新,這可能是時候找更舊的 SRPM 作為出發點。你大概應該用這個方法將 glibc、gcc、python、perl、或其它核心元件升級到較新版本。如果你這樣做,你要承受系統損壞到難以修復的風險。

如果你想修正一個上游已經修正,但 CentOS 仍未修正的錯誤(這個時差一般很短),你可以看看上游所提供者所發行的 SRPM:

否則,你可以看看那些針對較新版 CentOS 的 SRPM。舉個例子,多數針對 CentOS 5 的 SRPM 都可以在 CentOS 4 機器上重建。CentOS 的 SRPM 已收錄在:

一旦你找到了 SRPM 檔案,你便可以利用 wget 或瀏覽器將它下載到你的機器裡。你可以將檔案儲存到任何目錄。雖然你可以將它存放在你建立 RPM 的目錄內的 SRPMS 位置,你或許不會想這樣做,因為你重建 RPM 時也許會取替了它。

<!> 註:雖然你有機會能成功地重建及使用來自其它發行版本的 SRPM,這並不是必然的。你應該留意,安裝那些重建自其它發行版本的 RPM 或許會將你的系統損壞到一個難以修復的地步。為了安全起見,你應該盡量沿用那些來自 CentOS 或者被推薦軟件庫的套件。請記得,如果系統損壞了,你要獨自收拾殘局。

預備好建立 RPM 的環境

請遵從這些指引來將你的環境設定為可建立 RPM 的。

單一步重建 SRPM

重建 SRPM 最快捷方法就是使用 rpmbuild --rebuild ... 指令。這個指令會將 SRPM 解壓為 spec 檔案及源代碼檔案,然後按照 spec 檔案內的指引建立 RPM。

<!> 不論是用 RPM 套件管理系統、抑或是舊式的 tar 檔案,以 root 身份來建立軟件可能會導致災難。這裡對此事有更詳細的討論。

舉個例子,要重建 /tmp/mypackage-1.0.0-1.src.rpm 這個套件,執行這個指令:

[user@host ~]$ rpmbuild --rebuild /tmp/mypackage-1.0.0-1.src.rpm

一切順利的話,你便會產生一個 mypackage-1.0.0-1.i386.rpm 檔案在 ~/rpmbuild/RPMS/i386 目錄裡(如果你的架構是 i386,否則檔案名稱及目錄都會相應地有變)。

假如重建 RPM 的過程中出了問題,錯誤信息應該能讓你估計甚麼地方出了錯及需要修正。很多時問題出於你未安裝好重建 RPM 時所需的工具。請參閱這裡來看看重建 RPM 時一般所需的工具清單。有時候,你可能要為重新命名或改版的套件調整 BuildRequires,或在 spec 檔加增違漏了的依賴性。

安裝 SRPM 然後以 spec 檔案重建

另一個做法就是先安裝來自 SRPM 的檔案,然後利用 rpmbuild 按照 spec 檔案重建。Fedora >= 11 的 RPM 必須這樣處理。

要安裝一個 SRPM,請執行 rpm -i 指令並提供 SRPM 套件的名稱作為參數。請留意用沒有特殊權限的戶口執行 rpm -i,而不是 root。你亦可以利用 rpm -qpl 來列出 SRPM 套件內的檔案。當你安裝一個 SRPM 套件時,spec 檔案(也就是有 .spec 副檔名的那個)會被放進你的 ~/rpmbuild/SPECS 目錄內,而其它來自 SRPM 的檔案(多數是 tar 壓縮檔及修正檔)會被放進你的 ~/rpmbuild/SOURCES 目錄內。舉個例說,要解壓 /tmp/mypackage-1.0.0-1.src.rpm 這個套件的內容,這執行這個指令:

[user@host ~]$ rpm -i /tmp/mypackage-1.0.0-1.src.rpm

假如是後期 Fedora 的 RPMS,或者出現的錯誤類似 "error: unpacking of archive failed on file /builddir/build/SOURCES/mypackage-1.0.0.tar.gz;4dc983a7: cpio: MD5 sum mismatch":

[user@host ~]$ rpm --nomd5 -i /tmp/mypackage-1.0.0-1.src.rpm

當你將 SRPM 解壓後,你便會留意到在 ~/rpmbuild/SPECS 目錄內多了一個 spec 檔案(在這個例子裡它多數會稱為 mypackage.spec)。你就是利用這個檔案來建立 RPM。要這樣做,請使用下列指令:

[user@host ~]$ cd ~/rpmbuild/SPECS
[user@host SPECS]$ rpmbuild -ba mypackage.spec

rpmbuild -ba 這個指令會執行 RPM 建立過程裡的所有步驟,然後在完成時建立一個 RPM 套件(它會被儲存在 ~/rpmbuild/RPMS/i386 內,或者對應你架構的目錄內),與及一個新的 SRPM 檔案(它會被儲存在 ~/rpmbuild/SRPMS 內)。

先將 SRPM 解壓然後利用 rpmbuild -ba 以 spec 檔案重建的好處,就是你可以按需要修改 spec 檔案(或者加入修正檔案,甚至乎將 tar 壓縮檔升級)。對比起重建 SRPM,這卻是一個較複雜的情況,所以如果你要走這條路,你應該參考下面的建議閱讀更多關於這方面的資料,不過程序上它大致是:

  1. cd ~/rpmbuild/SPECS/
  2. rpmbuild -bp mypackage.spec
  3. cd ~/rpmbuild/BUILD/
  4. cp existing_directory existing_directory.orig
  5. cd existing_directory
  6. 尋找你要更改的檔案,修改它。
  7. cd ~/rpmbuild/BUILD/
  8. diff -Npru existing_directory.orig exiting_directory > name_of_your_patch_file.patch

  9. cp name_of_your_patch_file.patch ~/rpmbuild/SOURCES/
  10. cd ~/rpmbuild/SPECS/
  11. 編輯 mypackage.spec 檔並加入 name_of_your_patch_file.patch 的定義和應用它 —— 做法可參考該檔案的內容。
  12. rpmbuild -ba mypackage.spec

假如你決定要按自己的需要自訂一個 spec 檔案,這裡有些非常好的資源可以提供幫助:

Translation of revision 28

zh-tw/HowTos/RebuildSRPM (last edited 2012-02-25 16:59:34 by TimothyLee)