Blog Archive

Sunday, December 2, 2018

RPM 打包︰由一竅不通到動手濫用


(说明:本文是在原文的基础上修改错误而生成的)

Linux 世界除了 .tar 之外,有兩大主流打包格式,就是 .deb  .rpm,由於最近工作關係,學了一點點這兩個格式的打包技巧,希望和大家分享一下。
這篇文我們來談一下 .rpm 格式。
有興趣請跟着本文動手,打包你人生第一個 .rpm 檔吧!

簡介
rpm 1997 Erik Troan Marc Ewing 為紅帽 (RedHat Linux) 設計的包裝格式,設計參考一些更早的打包工具(pmpms),名字 rpm 的全寫是「RPM Package Manager」(對,是自我指涉的命名,總之別再問了)。
rpm 想解決的問題
我有一個 .tar 檔,有方法編譯,我應該怎樣指示包裝工具,同時產生源碼和二進制的裝包檔?
對,你只要給予適當的指示,rpm 工具可以同時支援打包源碼檔 SRPM (Source RPM) ,編譯程式,並裝編譯結果打包成 .rpm
如果你沒有打算打包源碼……其實還好,也有方法。
rpm 的解決方法
乾脆把你取得源碼、編譯、打包過程,通通用 bash 和巨集描述,其他的我們幫你。
rpm 打包的核心是 SPEC 設定檔,裏面供定義一些不同情況下執行的 bash 指令稿。
為了節省包裝者的工作,SPEC 支援用 %define 語句去定義變數 (variable) 和巨集 (macro)。除 rpm 官方提供一些內置巨集指令外,個別分發版本也提供一些指令集,支援 makefilepython 或者其他程式語言的打包工作。

動手打包
要動手打包前,首先得安裝相關的軟件。我們需要使用的程式是 rpmbuild
·       如果你是 RHELCentOS 或者 Fedora 的用戶
sudo yum install rpm-build 或者 sudo dnf install rpm-build
·       如果你是 Ubuntu 或者 Debian 的用戶, 
sudo apt-get install rpm
安裝之後,我們來試一試 rpmbuild是否存在︰
shell $  rpmbuild --version
RPM version 4.14.1
似乎可以了。
動手打包你第一個 rpm 吧!
我們得先有一個程式去打包,我們用 bash 指令稿做示範。首先用你愛用的Linux 文字編輯器,輸入下面的指令稿︰



#!/bin/bash # say something, with timestamp, every 5 secondswhile echo "$@"; do sleep 5sdone


存檔時請把它命名為 tick5 ,然後用 chmod u+x tick5來賦予執行權限,接着試用︰
./tick5 come on, James
結果應該像這樣(註︰看悶了請按 Ctrl+C 結束執行)︰
shell $  ./tick5 come on, James
come on, james
come on, james
come on, james
come on, james
come on, james
come on, james
...
...
接着我們在同一個資料匣,加入我們的 SPEC 檔︰


%define srcDir %(pwd) # Some metadata required by an RPM package Name: tick5
Summary: Print a message every 5s
Version: 0.1
Release: 1
License: MIT
%description
tick5 is a simple useless script that echos a message every 5 seconds.
%install
mkdir -p %{buildroot}/usr/bin
cp -pdf %{srcDir}/tick5 %{buildroot}/usr/bin/tick5
chmod 755 %{buildroot}/usr/bin/tick5

如果你上面都做得對,你的資料匣中會同時有這兩個檔案︰
tick5 tick5.spec
既然有了程式,又有了SPEC,我們就可以執行打包的指令︰
rpmbuild -bb tick5.spec
結果應該像這樣︰
shell $  rpmbuild -bb tick5.spec
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.QZ1vBE
+ umask 022
+ cd /home/user/rpmbuild/BUILD
+ mkdir -p /home/user/rpmbuild/BUILDROOT/tick5-0.1-1.x86_64/usr/bin
+ cp -pdf /home/user/tick5/tick5 /home/user/rpmbuild/BUILDROOT/tick5-0.1-1.x86_64/usr/bin/tick5
+ chmod 755 /home/user/rpmbuild/BUILDROOT/tick5-0.1-1.x86_64/usr/bin/tick5
+ exit 0
Processing files: tick5-0.1-1.x86_64
Provides: tick5 = 0.1-1 tick5(x86-64) = 0.1-1
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
Requires: /bin/bash
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/user/rpmbuild/BUILDROOT/tick5-0.1-1.x86_64
Wrote: /home/user/rpmbuild/RPMS/x86_64/tick5-0.1-1.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.XpUHeA
+ umask 022
+ cd /home/user/rpmbuild/BUILD
+ /bin/rm -rf /home/user/rpmbuild/BUILDROOT/tick5-0.1-1.x86_64
+ exit 0
完了啦?怎麼資料匣沒有新檔案的?我的 rpm 檔呢?留意上面的輸出有這樣一句︰
Wrote: /home/user/rpmbuild/RPMS/x86_64/tick5-0.1-1.x86_64.rpm
執行打包時, rpmbuild 會建立自己的「包裝工作間」 (Packaging Workspace),由內部變數 _topdir 定義,而預設的路徑為 $HOME/rpmbuild。你可以在指令加上 --define "_topdir $PWD/rpmbuild" 將路徑改為你目前的資料匣。
打包好了,試試安裝
如果你是 RHELCentOS 或者 Fedora 的用戶
sudo rpm -ivh /home/user/rpmbuild/RPMS/x86_64/tick5-0.1-1.x86.rpm
如果你是 Ubuntu 或者 Debian 的用戶,由於你的系統沒有 rpm 的相依性資料庫,無法知道你 rpm 所需的套件是否有正確安裝,用同一個指令會出現錯誤︰
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
error: Failed dependencies:
 /bin/bash is needed by tick5-0.1-1.x86_64
如果你是
正確安裝方法是安裝 alien 工具,然後用 alien rpm 當成 .deb 安裝︰
sudo apt-get install alien
sudo alien -iv
/home/user/rpmbuild/RPMS/x86_64/tick5-0.1-1.x86.rpm
如果一切正常,你應該可以在系統找到 /usr/bin/tick5 這個無用的指令程式,而你可以這樣執行︰
shell $  tick5 come on, james
come on, james
come on, james
come on, james
come on, james
come on, james
come on, james
...
...

解除 tick5 程式安裝
安裝了沒有用的東西,當然想刪掉。
如果你是 RHELCentOS 或者 Fedora 的用戶
sudo rpm -e tick5
如果你是 Ubuntu 或者 Debian 的用戶︰
sudo apt-get remove tick5
這就把剛剛沒有營養的 tick5 給刪除掉了。

下一篇文章,會比較深入介紹上面其實發生了甚麼事,還有動手修改 SPEC 檔變成 systemd 服務。有興趣的朋友,敬請留意。
[总结]
如果你用:RedHat, CentOS, Fedora:
rpmbuild -bb tick5.spec
sudo rpm -ivh /home/user/rpmbuild/RPMS/x86_64/tick5-0.1-1.x86.rpm
tick5 come on, james
sudo rpm -e tick5



如果你用 Ubuntu, Debian
rpmbuild -bb tick5.spec
sudo apt-get install alien
sudo alien -iv /home/user/rpmbuild/RPMS/x86_64/tick5-0.1-1.x86.rpm 
tick5 come on, james
sudo apt-get remove tick5

=========================