1. 程式人生 > >Moblin:kernel編譯和rpm打包(二):RPM打包

Moblin:kernel編譯和rpm打包(二):RPM打包

  RPM打包對於應用程式是十分有用的,可以下載,可以解除安裝,可以升級,可打補丁,可用於軟體的釋出和管理,以及以後可能的軟體store。如果我們使用MIC2,更換kenrel,如果需要製作的usbimg通過安裝方式能夠成功啟動,我們必須對我們自己新的kernel進行打包。

  我們通過一個簡單的hello world例子來打一個名字為hello的rpm包。 我收集了網上的資料,結合自己的實驗給出下面的內容。有很多的資訊來自共產主義的網路。RPM全稱是 Red Hat Package Manager(Red Hat包管理器)。幾乎所有的 Linux 發行版本都使用這種形式的軟體包管理安裝、更新和解除安裝軟體。RPM有五種基本的操作功能(不包括建立軟體包):安裝、解除安裝、升級、查詢、和驗證。

/** hello.c */

#include <stdio.h>

int main(){
        printf("Hello, world! version 1.0.0/n");
}

  這個是最簡單的例子,放置在目錄hello-1.0.0/的下面,在這個目錄下面,有一個可執行的configure檔案和Makefile檔案。注意,configure的許可權必須是可執行的,否則在打包的過程中會報錯。這麼簡單的程式,我們也沒有什麼特別需要配置的。如下:

echo "hello, This is configure file, do noting."

  Makefile程式如下,屬於常規寫法 ,唯一需要注意的是我們增加了一個DESTDIR的引數,這個與後面打包的相關:

CC      = gcc
CFLAGS  =
INCLUDE =

OBJECTS = hello.o
TARGET  = hello
DESTDIR  =

all:    $(TARGET)

hello.o:
        $(CC) -c hello.c

$(TARGET):      $(OBJECTS)
        $(CC) -o hello $(OBJECTS)

install:
        cp $(TARGET) $(DESTDIR)/usr/local/bin/$(TARGET)

rm:     clean

clean:
        rm -f *.o
        rm $(TARGET) /usr/local/bin/$(TARGET)

  接著我們將目錄進行tar,得到hello-1.0.0.tar.gz。如果我們得到一個tar.gz的原始碼,通常處理就是一、解壓;二、configure;三、make,四、make install。我們的例子中具備了這些步驟,雖然configure我們並沒有任何實際的動作,只是走了形式。

  在當前使用者目錄~下面建立rpmbuild,例如/home/wei/rpmbuild,rpmbuild有五個子目錄,我們可以先建立SOURCES和SPECS,其他的三個目錄在打包的過程中可以自動生成。將hello-1.0.0.tar.gz放置在SOURCES目錄下面,在SPECS目錄下面寫我們的spec檔案,這是打包的關鍵,這個檔案是構造我們rpm包的指令碼檔案。

#################### 檔案頭 #####################
Summary : GNU hello test for rpm building   //這是對軟體包的描述
Name : hello               //這是軟體包的名稱,
最終RPM軟體包是用該名字與版本號,釋出號及體系號來命名軟體包的
Version : 1.0.0             //這是軟體包的版本
Release : 1                 //這是RPM的版本號,如果修復了spec檔案中內容重新發布該rpm,應該增加發行版號
Source0 : %{name}-%{version}.tar.gz //源程式軟體包的名字,這裡是原始檔的壓縮包,即hello-1.0.0.tar.gz,如果有多個,可以有Source0,Source1
License : GPL             //軟體包所採用的版權規則。具體有:GPL(自由軟體),BSD,MIT,Public Domain(公共域),Distributable(貢獻),commercial(商業),Share(共享)等
Group : Development/Tools   //表示軟體型別, 幫助其他人在管理RPM程式中按照組來列出RPM
Vendor : WEI              //軟體開發者的名字

%description          //這是對軟體包的描述,這個以及上面的資訊,在安裝rpm後,可以通過rpm –qi hello中獲得
The GNU hello little program is used to test how to building a simple
rpm, just for study.

#################### %prep段 #####################
#從這裡開始就是嵌入spec的shell文字。這個段是預處理段,通常用來執行一些解開源程式包的命令,為下一步的編譯安裝作準備。%prep負責對軟體包解包。在最常見情況下,您只要用 %setup 巨集即可,它會做適當的事情,在構建目錄下解包源 tar 檔案。加上 -q 項只是為了減少輸出。將會在~/rpmbuild/BUILD目錄下面解開壓縮包
#對於打補丁的部分也放置在這裡
%prep    
%setup -q

#################### %build段 #####################
#本段是建立段,所要執行的命令為生成軟體包服務,如make 命令。編譯該軟體包。該 shell 指令碼從軟體包的子目錄下執行,在我們的例子中,將會在~/rpmbuild/BUILD/hello-1.0.0/下面執行。和通常的編譯一樣,我們執行./configure檔案,以及進行make。這裡給出編譯過程中執行的步驟。如果編譯kernel,我們可能會寫上make bzImage等等。
%build
./configure
make

#################### %install段 #####################
#在構建系統上安裝軟體包。為了最後能封裝成rpm,我們需要將所需封裝的檔案及其安裝的目錄放置在$RPM_BUILD_ROOT(即~/rpmbuild/BUILDROOT/hello-1.0.0-1.i386)下面。例如我們需要將編譯後的可執行檔案hello最終方式在/usr/local/bin下面,那麼我們需要將hello拷貝到~rpmbuild/BUILDROOT/hello-1.0.0-1.i386/usr/local/bin/hello。 %install
install -d $RPM_BUILD_ROOT/usr/local/bin
make install DESTDIR=$RPM_BUILD_ROOT

#################### %clean段 #####################
#刪除臨時檔案,在最後執行
%clean
rm –rf $RPM_BUILD_ROOT
 

#################### %file段 #####################
# 檔案段,用於定義軟體包所包含的檔案,分為三類--說明文件(doc),配置檔案(config)及執行程式,還可定義檔案存取許可權,擁有者及組別。
#列出應該捆綁到 RPM 中的檔案,並能夠可選地設定許可權和其它資訊。可以使用 一次 %defattr 來定義預設的許可權、所有者和組;在這個示例中, %defattr(-,root,root) 會安裝 root 使用者擁有的所有檔案,使用當 RPM 從構建系統捆綁它們時它們所具有的任何許可權。可以用 %attr(permissions,user,group) 覆蓋個別檔案的所有者和許可權。可以在 %files 中用一行包括多個檔案
#可以通過在行中新增 %doc 或 %config 來標記檔案。 %doc 告訴 RPM 這是一個文件檔案,因此如果使用者安裝軟體包時使用 --excludedocs ,將不安裝該檔案。您也可以在 %doc 下不帶路徑列出檔名,RPM 會在構建目錄下查詢這些檔案並在 RPM 檔案中包括它們,並把它們安裝到 /usr/share/doc/%{name}-%{version} 。以 %doc 的形式包括 README 和 ChangeLog 這樣的檔案是個好主意。
#%config 告訴 RPM 這是一個配置檔案。在升級時,RPM 將會試圖避免用 RPM 打包的預設配置檔案覆蓋使用者仔細修改過的配置。
%files
%defattr(-,root,root)
/usr/local/bin/hello

#%doc /usr/local/info/hello.info
#%doc %attr(0444,root,root) /usr/local/man/man1/hello.1
#%doc COPYING AUTHORS README NEWS

#################### %changelog段 #####################
#修改日誌段。你可以將軟體的每次修改記錄到這裡,儲存到釋出的軟體包中,以便查詢之用。每一個修改日誌都有這樣一種格式:第一行是:* 星期 月 日 年 修改人電子信箱。其中:星期、月份均用英文形式的前3個字母,用中文會報錯。接下來的行寫的是修改了什麼地方,可寫多行。一般以減號開始,便於後續的查閱。這個例子中我們不需要這個部分。 如果是釋出下一個版本可以加上如下的內容。
* Mon Jul 6 2009 Name<Email-address> –1.0.1-1
- modified …… 可以多行,表面增加或者修改的地方

  此外,在開始部分,通過BuildRequires:列出軟體編譯必須依賴的軟體包,如果有人用你的src.rpm自己編譯,會提示他需要安裝這些包才能編譯。通過Requires:是軟體執行時依賴的軟體包,這個非常重要,因為倉庫安裝要依賴它來同時安裝其他依賴的軟體包(雖然rpm有自動依賴關係判定,但不能100%保險)。

除了上面這些部分外,還有%pre(在安裝包之前執行), %post(在安裝包之後執行), %preun(在解除安裝包之前執行), %postun(在解除安裝包之後執行)。例如我們可以在%post中加上某些連結的檔案。

  在這個例子中,我們在make install中增加了輔助引數DESTDIR,我曾考慮過在configure的配置來進行,但是IBM工程師的文件建議:請注意 要使用./configure --prefix=$RPM_BUILD_ROOT 。這會在假設整個軟體包檔案的最終位置是構建根的情況下安裝整個軟體包。這可能沒有關係,但任何需要在執行時找到其安裝檔案的程式都將失敗,因為當 RPM 最終安裝到使用者系統後,這些檔案就不再位於構建根之下 ― 那只是您構建系統上的一個臨時目錄。

  之後我們執行:rpmbuild –ba hello.spec,我們將在~/rpmbuild/RPMS得到:hello-1.0.0-1.i386.rpm和hello-debuginfo-1.0.0-1.i386.rpm, 在~rpmbuild/SPRMS中得到hello-1.0.0-1.src.rpm。

  如果我們只想得到二進位制的rpm包,使用rpmbuild -bb,我們在RPMS中得到hello-1.0.0-1.i386.rpm,如果只想得到原始碼包,使用rpmbuild –bs,我們在SRPMS中得到hello-1.0.0-1.src.rpm。如果只需要生成原始檔,使用rpmbuild -bp,我們將在BUILD目錄下面得到打好補丁的source code。

  我們執行rpmbuild –ivh hello-1.0.0-1.i386就可以安裝hello rpm包。

有一篇很好的參考文件:

http://www.ibm.com/developerworks/cn/linux/management/package/rpm/part1/ http://www.ibm.com/developerworks/cn/linux/management/package/rpm/part2/ http://www.ibm.com/developerworks/cn/linux/management/package/rpm/part3/

  附:在fc10中,我們直接通過vi hello.spec,已經有相關的模板在裡面。