Linux實(shí)用工具-rpm軟件包構(gòu)建(2)

一、軟件包制作

1,描述文件

制作rpm軟件包的關(guān)鍵跪解,就是編寫用于生成軟件包的spec文件(描述文件)。該文件描述了制作軟件包時(shí)候所需的信息签孔。下面介紹制作rpm包所需的spec文件的相關(guān)內(nèi)容叉讥。

首先,要在制做rpm包之前饥追,建立好一些必要的目錄結(jié)構(gòu)图仓,例如BUILD,SOURCES,等,然后rpm的相關(guān)工具會(huì)將這些目錄的父目錄以%{_topdir}表示但绕,這個(gè)%{_topdir}默認(rèn)值為系統(tǒng)中的某個(gè)目錄救崔,例如"usr/local/redhat"等,如果使用自己的目錄壁熄,需要自行修改這個(gè)變量帚豪,后面的例子中會(huì)有所說明碳竟。

spec腳本的主體中也包括了很多關(guān)鍵字草丧,描述內(nèi)容主要包含文件頭以及各個(gè)段,主要的段包括:%prep段莹桅,%build段 昌执,%install段烛亦,%files段 ,%changelog段等懂拾,每個(gè)段大致代表一個(gè)處理階段煤禽,下面依次介紹。更具體的信息岖赋,可以參見/usr/share/doc/rpm-<version>中的文檔以及后面的參考資料檬果。

1、文件頭

文件頭內(nèi)容主要如下:

  • Name:軟件包的名稱唐断,后面可使用%{name}的方式引用

  • Summary:軟件包的內(nèi)容概要

  • Version:軟件的實(shí)際版本號(hào)选脊,例如:1.0.1等,后面可使用%{version}引用

  • Release:發(fā)布序列號(hào)脸甘,例如:1linuxing等,標(biāo)明第幾次打包,后面可使用%{release}引用

  • Group:軟件分組坐桩,建議使用標(biāo)準(zhǔn)分組

  • License:軟件授權(quán)方式惧辈,通常就是GPL

  • Source:源代碼包,可以帶多個(gè)用Source1铆遭、Source2等源硝桩,后面也可以用%{source1}、%{source2}引用

  • BuildRoot:這個(gè)是安裝或編譯時(shí)使用的“虛擬目錄”枚荣。

    考慮到多用戶的環(huán)境亿柑,一般定義為:

    %{_tmppath}/%{name}-%{version}-%{release}-root或%{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n}
    

    該參數(shù)非常重要,因?yàn)樵谏蓃pm的過程中棍弄,執(zhí)行make install時(shí)就會(huì)把軟件安裝到上述的路徑中望薄,在打包的時(shí)候,同樣依賴“虛擬目錄”為“根目錄”進(jìn)行操作呼畸。后面可使用$RPM_BUILD_ROOT 方式引用痕支。

  • URL:軟件的主頁

  • Vendor:發(fā)行商或打包組織的信息,例如RedFlag Co,Ltd

  • Disstribution:發(fā)行版標(biāo)識(shí)

  • Patch:補(bǔ)丁源碼蛮原,可使用Patch1卧须、Patch2等標(biāo)識(shí)多個(gè)補(bǔ)丁,使用%patch0或%{patch0}引用

  • Prefix:%{_prefix} 這個(gè)主要是為了解決今后安裝rpm包時(shí)儒陨,并不一定把軟件安裝到rpm中打包的目錄的情況花嘶。這樣,必須在這里定義該標(biāo)識(shí)蹦漠,并在編寫%install腳本的時(shí)候引用椭员,才能實(shí)現(xiàn)rpm安裝時(shí)重新指定位置的功能

  • Prefix:%{_sysconfdir} 這個(gè)原因和上面的一樣,但由于%{_prefix}指/usr笛园,而對(duì)于其他的文件隘击,例如/etc下的配置文件侍芝,則需要用%{_sysconfdir}標(biāo)識(shí)

  • Build Arch:指編譯的目標(biāo)處理器架構(gòu),noarch標(biāo)識(shí)不指定埋同,但通常都是以/usr/lib/rpm/marcros中的內(nèi)容為默認(rèn)值

  • Requires:該rpm包所依賴的軟件包名稱州叠。

    可以用>=或<=表示大于或小于某一特定版本,例如:

    libpng-devel >= 1.0.20 zlib
    

    這里凶赁,“>=”號(hào)兩邊需用空格隔開咧栗,而不同軟件名稱也用空格分開

    還有例如PreReq、Requires(pre)虱肄、Requires(post)楼熄、Requires(preun)、Requires(postun)浩峡、BuildRequires等都是針對(duì)不同階段的依賴指定

  • Provides:指明本軟件一些特定的功能可岂,以便其他rpm識(shí)別

  • Packager:打包者的信息

  • %description 軟件的詳細(xì)說明

2、文件段

%prep段

包含預(yù)處理腳本翰灾,通常用來執(zhí)行一些解開源程序包的命令缕粹,為下一步的編譯安裝作準(zhǔn)備(一般來說,都是從SOURCES目錄中將源代碼解壓到BUILD中)纸淮。腳本運(yùn)行的當(dāng)前目錄在BUILD中平斩。

%prep和下面%build,%install段一樣咽块,除了可以執(zhí)行RPM所定義的宏命令(以%開頭)以外绘面,還可以執(zhí)行SHELL命令,命令可以有很多行侈沪。

  1. %setup -n %{name}-%{version} 把源碼包解壓并放好

    通常從%{_topdir}/SOURCES里的包解壓到%{_topdir}/BUILD/%{name}-%{version}中揭璃。

    一般用%setup -c就可以了,但有兩種情況:一就是同時(shí)編譯多個(gè)源碼包亭罪,二就是源碼的tar包的名稱與解壓出來的目錄不一致瘦馍,此時(shí),就需要使用-n參數(shù)指定一下了应役。

    對(duì)于%setup情组,具體還包含如下選項(xiàng):

    • %setup 不加任何選項(xiàng),僅將軟件包打開箩祥。
    • %setup -n newdir 將軟件包解壓在newdir目錄院崇。
    • %setup -c 解壓縮之前先產(chǎn)生目錄。
    • %setup -b num 將第num個(gè)source文件解壓縮袍祖。
    • %setup -T 不使用default的解壓縮操作底瓣。
    • %setup -T -b 0 將第0個(gè)源代碼文件解壓縮。
    • %setup -c -n newdir 指定目錄名稱newdir盲泛,并在此目錄產(chǎn)生rpm套件濒持。
    • %patch 最簡單的補(bǔ)丁方式键耕,自動(dòng)指定patch level寺滚。
    • %patch 0 使用第0個(gè)補(bǔ)丁文件柑营,相當(dāng)于%patch ?p 0。
    • %patch -s 不顯示打補(bǔ)丁時(shí)的信息村视。
    • %patch -T 將所有打補(bǔ)丁時(shí)產(chǎn)生的輸出文件刪除官套。
  2. %patch 打補(bǔ)丁

    通常補(bǔ)丁都會(huì)一起在源碼tar.gz包中,或放到SOURCES目錄下蚁孔。一般參數(shù)為:

    • %patch -p1 使用前面定義的Patch補(bǔ)丁進(jìn)行奶赔,-p1是忽略patch的第一層目錄
    • %Patch2 -p1 -b xxx.patch 打上指定的補(bǔ)丁,-b是指生成備份文件
  3. %configure

    這個(gè)不是關(guān)鍵字杠氢,而是rpm定義的標(biāo)準(zhǔn)宏命令站刑。意思是執(zhí)行源代碼的configure配置

    在%{_topdir}/BUILD/%{name}-%{version}目錄中進(jìn)行 ,使用標(biāo)準(zhǔn)寫法鼻百,會(huì)引用/usr/lib/rpm/marcros中定義的參數(shù)绞旅。

    另一種不標(biāo)準(zhǔn)的寫法是,可參考源碼中的參數(shù)自定義温艇,例如:

    CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}
    

%build段

包含為生成軟件包服務(wù)所執(zhí)行的命令因悲,通常是編譯生成可執(zhí)行文件。生成的可執(zhí)行文件在install中會(huì)用到勺爱。腳本運(yùn)行的當(dāng)前目錄在BUILD中晃琳。

相當(dāng)于在%{_topdir}/BUILD/%{name}-%{version}目錄中進(jìn)行make的工作 ,常見寫法如:make %{?_smp_mflags} OPTIMIZE="%{optflags}"都是一些優(yōu)化參數(shù)琐鲁,定義在/usr/lib/rpm/marcros卫旱。

%install段

包含把軟件安裝到虛擬的根目錄中的命令。這里的虛擬根目錄就是一個(gè)子目錄围段,其目錄結(jié)構(gòu)和根目錄一樣誊涯,%install會(huì)把最終安裝好的軟件的目錄結(jié)構(gòu)反應(yīng)到這個(gè)虛擬根目錄中。然后根據(jù)這個(gè)虛擬根目錄和后面的%files段內(nèi)容蒜撮,將軟件制作成rpm包暴构。其當(dāng)前工作目錄也是BUILD。它一般會(huì)在%{_topdir}/BUILD/%{name}-%{version}目錄中進(jìn)行make install的操作段磨。這個(gè)很重要取逾,因?yàn)槿绻@里的路徑不對(duì)的話,則下面%file中尋找文件的時(shí)候就會(huì)失敗苹支。 常見內(nèi)容有:

%makeinstall

這不是關(guān)鍵字砾隅,而是rpm定義的標(biāo)準(zhǔn)宏命令。也可以使用非標(biāo)準(zhǔn)寫法:

make DESTDIR=$RPM_BUILD_ROOT install
make prefix=$RPM_BUILD_ROOT install

需要說明的是债蜜,這里的%install主要就是為了后面的%file服務(wù)的晴埂。所以究反,還可以使用常規(guī)的系統(tǒng)命令:

install -d $RPM_BUILD_ROOT/
cp -a * $RPM_BUILD_ROOT/

總之,這里是制作rpm包儒洛,并不是安裝軟件精耐,所以只是將文件安裝到虛擬根目錄中,千萬要指定好了虛擬根目錄琅锻,否則就真的安裝到真實(shí)的系統(tǒng)中了卦停,向虛擬根目錄中安裝好了之后,再利用虛擬根目錄制作rpm包恼蓬,而安裝rpm包的時(shí)候惊完,才真正將軟件安裝到你的系統(tǒng)上。

%clean段

這個(gè)段用來清理臨時(shí)文件处硬,在制作好了rpm包之后小槐,執(zhí)行這個(gè)段中的內(nèi)容,清除制作過程中產(chǎn)生的中間文件荷辕。例如BUILD中的凿跳,以及虛擬根目錄中的內(nèi)容。

通常內(nèi)容為:

[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT"
rm -rf $RPM_BUILD_DIR/%{name}-%{version}

這里注意:對(duì)于RPM\_BUILD\_ROOT和RPM_BUILD_DIR:

  • RPM\_BUILD\_ROOT是指開頭定義的BuildRoot桐腌,而RPM_BUILD_DIR通常就是指%{_topdir}/BUILD拄显,其中,前面的才是%file需要的案站。
  • %pre rpm安裝前執(zhí)行的腳本
  • %post rpm安裝后執(zhí)行的腳本
  • %preun rpm卸載前執(zhí)行的腳本
  • %postun rpm卸載后執(zhí)行的腳本
  • %preun %postun 的區(qū)別是什么呢躬审?

前者在升級(jí)的時(shí)候會(huì)執(zhí)行,后者在升級(jí)rpm包的時(shí)候不會(huì)執(zhí)行蟆盐。

%files段

定義哪些文件或目錄會(huì)放入rpm中承边,rpm安裝會(huì)安裝哪些文件。

用于定義軟件包所包含的文件石挂,分為三類–說明文檔(doc)博助,配置文件(config)及執(zhí)行程序,還可定義文件存取權(quán)限痹愚,擁有者及組別富岳。

這里所指定的文件路徑,是相對(duì)于虛擬根目錄下的文件路徑拯腮,千萬不要寫絕對(duì)路徑窖式,而應(yīng)用宏或變量表示相對(duì)路徑。 如果描述為目錄动壤,表示目錄中除%exclude外的所有文件萝喘。

  • %defattr (-,root,root) 指定包裝文件的屬性,分別是(mode,owner,group),-表示默認(rèn)值阁簸,對(duì)文本文件是0644爬早,可執(zhí)行文件是0755。
  • %exclude 列出不想打包到rpm中的文件启妹。這里注意筛严,如果%exclude指定的文件不存在,也會(huì)出錯(cuò)的翅溺。

%changelog段

本段是修改日志段脑漫。你可以將軟件的每次修改記錄到這里髓抑,保存到發(fā)布的軟件包中咙崎,以便查詢之用。

每一個(gè)修改日志都有這樣一種格式:

  • 第一行是: * 星期 月 日 年 修改人 電子信箱 吨拍。其中:星期褪猛、月份均用英文形式,用中文會(huì)出錯(cuò)羹饰。
  • 接下來的行寫的應(yīng)是修改了什么地方伊滋,可寫多行。一般以減號(hào)起始队秩,便于查閱笑旺。

一些rpm相關(guān)雜亂信息

  1. 以上各個(gè)段中,比較容易混淆的就是目錄馍资,我們需要記住兩點(diǎn):

    1. %build和%install中筒主,都必須把編譯和安裝的文件定義到“虛擬根目錄” 中。

      例如:

      %build
      make -f admin/Makefile.common cvs
      ./configure --prefix=%{_prefix} --enable-final --disable-debug \
      --with-extra-includes=%{_includedir}/freetype2 --includedir=%{_includedir}
      make
      %install
      rm -fr $RPM_BUILD_ROOT
      make DESTDIR=$RPM_BUILD_ROOT install
      cp -r $RPM_BUILD_ROOT%{_datadir}/apps/kolourpaint/icons/hicolor/* $RPM_BUILD_ROOT%{_datadir}/icons/crystalsvg/
      
    2. %file中用的是相對(duì)目錄

      例如:

      %files
      %defattr(-,root,root)
      %{_bindir}
      如果寫成:
      %files
      %defattr(-,root,root)
      /usr/bin
      

      則打包的會(huì)是根目錄下的/usr/bin中所有的文件鸟蟹,而不是本軟件中的文件了乌妙。

      • rpm軟件包系統(tǒng)的標(biāo)準(zhǔn)分組:/usr/share/doc/rpm-4.3.3/GROUPS
      • 各種宏定義: /usr/lib/rpm/macros
      • 已經(jīng)安裝的rpm包數(shù)據(jù)庫: /var/lib/rpm

      如果要避免生成debuginfo包:這個(gè)是默認(rèn)會(huì)生成的rpm包。則可以使用下面的命令:

      $echo '%debug_package %{nil}' >> ~/.rpmmacros
      

      由于必須在%file中包括所有套件中的文件建钥,所以藤韵,我們需要清楚編譯完的套件到底包括那些文件

      常見的做法是,人工模擬一次編譯的過程:

      $./configrue --prefix=/usr/local/xxx
      $make
      $make DESTDIR=/usr/local/xxx install
      

      $make prefix=/usr/local/xxx install
      

      這樣熊经,整個(gè)套件的內(nèi)容就會(huì)被放到/usr/local/xxx中泽艘,可根據(jù)情況編寫%file和%exclude段(當(dāng)然,這個(gè)只能對(duì)源碼按GNU方式編寫镐依,并使用GNU autotool創(chuàng)建的包有效匹涮,若自定義Makefile則不能一概而論)。

  2. 關(guān)于rpm中的執(zhí)行腳本

    如果正在制作的rpm包是準(zhǔn)備作為放到系統(tǒng)安裝光盤中的話馋吗,則需要考慮rpm中定義的腳本是否有問題学歧。

    由于系統(tǒng)在安裝的時(shí)候只是依賴于一個(gè)小環(huán)境進(jìn)行系奉,而該環(huán)境與實(shí)際安裝完的環(huán)境有很大的區(qū)別谍憔,所以泽台,大部分的腳本在該安裝環(huán)境中都是無法生效,甚至?xí)砺闊┑摹?/p>

    所以销钝,對(duì)于這樣的,需要放到安裝光盤中的套件,不加入執(zhí)行腳本是較佳的方法鞋真。

  3. 信號(hào)機(jī)制

    為提供操作中可參考的信息,rpm還提供了一種信號(hào)機(jī)制:不同的操作會(huì)返回不同的信息沃于,并放到默認(rèn)變量$1中涩咖。對(duì)于信號(hào)值,0代表卸載繁莹、1代表安裝檩互、2代表升級(jí)。

    例如可這樣使用:

    %postun
    if [ "$1" = "0" ]; then
    /sbin/ldconfig
    fi
    
  4. 下面是宏對(duì)應(yīng)路徑一覽表

    1. 一些模仿autoconf的變量

      • %{_sysconfdir} /etc
      • %{_prefix} /usr
      • %{_exec_prefix} %{_prefix}
      • %{_bindir} %{_exec_prefix}/bin
      • %{_lib} lib (lib64 on 64bit systems)
      • %{_libdir} %{_exec_prefix}/%{_lib}
      • %{_libexecdir} %{_exec_prefix}/libexec
      • %{_sbindir} %{_exec_prefix}/sbin
      • %{_sharedstatedir} /var/lib
      • %{_datadir} %{_prefix}/share
      • %{_includedir} %{_prefix}/include
      • %{_oldincludedir} /usr/include
      • %{_infodir} /usr/share/info
      • %{_mandir} /usr/share/man
      • %{_localstatedir} /var
      • %{_initddir} %{_sysconfdir}/rc.d/init.d

      注意:比Fedora10早的版本(或EPEL)中咨演,%{_initddir}沒有闸昨。這時(shí)候可以使用舊的%{_initrddir}宏。

    2. RPM目錄的宏

      • %{_topdir} %{getenv:HOME}/rpmbuild
      • %{_builddir} %{_topdir}/BUILD
      • %{_rpmdir} %{_topdir}/RPMS
      • %{_sourcedir} %{_topdir}/SOURCES
      • %{_specdir} %{_topdir}/SPECS
      • %{_srcrpmdir} %{_topdir}/SRPMS
      • %{_buildrootdir} %{_topdir}/BUILDROOT

      注意:比Fedora10早的版本(或EPEL)中薄风, %{_buildrootdir} 沒有饵较。

    3. 編譯編輯宏

      • %{_global_cflags} -O2 -g -pipe
      • %{_optflags} %{__global_cflags} -m32 -march=i386 -mtune=pentium4 # if redhat-rpm-config is installed
    4. 其它宏

      • %{_var} /var
      • %{_tmppath} %{_var}/tmp
      • %{_usr} /usr
      • %{_usrsrc} %{_usr}/src
      • %{_docdir} %{_datadir}/doc
  5. 一個(gè)帶有注釋的較為完整的spec文件的例子

    #+++++++++以下是文件內(nèi)容+++++++++++#
    ######頭部######
    Summary:一個(gè)簡單的打印hello的程序
    Name:myapplication
    Version:1.0
    Release:1
    Vendor:QuietHeart (quiet_heart000@126.com)
    License:Share
    SOURCE:%{name}-%{version}.tgz
    BuildRoot:%{_tmppath}/%{name}-%{version}-%{release}-root
    Group:Applications/Editors
    URL:quietheart.sf.net
    Prefix:%{_prefix}
    Prefix:%{_sysconfdir}
    Prefix:%{_datadir}
    Packager:QuietHeart
    %define myconfig myconfig.conf
    %define mylib libmy.so
    %description
    描述省略。
    
    ######prep,build,install三個(gè)段都可以執(zhí)行shell命令######
    # 預(yù)處理段遭赂,為下一步的編譯安裝作準(zhǔn)備循诉。例如將源代碼拷貝到BUILDS目錄。
    %prep
    # prep start.
    echo "======>In :prep section $(pwd)"
    echo "======>In :prep section " %{_topdir}
    echo "======>In :prep section $RPM_BUILD_ROOT"
    echo "======>In :prep section " %{_sourcedir}
    #echo "======>In :prep section $RPM_SOURCE_DIR"
    #將源代碼包解壓并放好撇他,也可以使用tar命令茄猫,解壓好的目錄:%{name}-%{version},存在BUILD中逆粹。
    %setup -n %{name}-%{version}
    #tar -xzvf %{_sourcedir}/%{name}-%{version}.tgz -C %{_builddir}
    
    # 建立段募疮,執(zhí)行一些編譯命令以便生成軟件包。工作于BUILDS僻弹。
    %build
    # build start.
    echo "======>In :build section $(pwd)"
    echo "======>In :build section " %{_topdir}
    echo "======>In :build section $RPM_BUILD_ROOT"
    echo "======>In :build section " %{_builddir}
    #echo "======>In :build section $RPM_BUILD_DIR"
    #自動(dòng)進(jìn)入myapplication-1.0中了阿浓。
    make
    
    # 安裝段,在安裝軟件包階段執(zhí)行的命令蹋绽。
    # 安裝的內(nèi)容安裝到“虛擬根目錄中”install是為了后面的file段服務(wù)的芭毙。
    %install
    # install start.
    echo "======>In :install section $(pwd)"
    echo "======>In :install section " %{_topdir}
    echo "======>In :install section $RPM_BUILD_ROOT"
    mkdir -p $RPM_BUILD_ROOT/usr/bin
    mkdir -p $RPM_BUILD_ROOT/usr/lib
    mkdir -p $RPM_BUILD_ROOT/etc
    #這里使用%{name}表示開始定義的Name,即myapplication卸耘。
    cp %{name} $RPM_BUILD_ROOT/usr/bin
    cp lib/%{mylib} $RPM_BUILD_ROOT/usr/lib
    cp %{myconfig} $RPM_BUILD_ROOT/etc
    
    ######其它的一些段######
    %clean
    # clean start.
    echo "======>In :clean section $(pwd)"
    
    #文件段退敦,定義軟件包所包含的文件。具體可由后面"%defattr","%doc","%config"宏定義蚣抗。
    #主要包含:config(配置文件),doc(文檔文件),bin(二進(jìn)制文件)
    %files
    #定義文件屬性:%defattr(權(quán)限侈百,屬主,屬組)。其中權(quán)限'-'表默認(rèn)钝域,可用'0777'形式讽坏。
    %defattr (-,root,root)
    
    #定義制作軟件包包含的文檔文件,每個(gè)宏定義一個(gè)例证,可指定絕對(duì)路徑路呜。
    #一般文檔文件會(huì)被安裝到"/usr/doc/Name-Version-Release"目錄下。
    %doc README
    %doc COPYRIGHT
    
    #定義軟件包所需要的配置文件(還是安裝的配置文件位置??)
    #當(dāng)卸載軟件的時(shí)候會(huì)將沒有修改過的卸掉织咧,修改過的備份為<name>.rpmsave胀葱。
    %config %{_sysconfdir}/%{myconfig}
    
    #軟件包所包含的二進(jìn)制文件,可以為目錄
    %{_bindir}/%{name}
    %{_libdir}/%{mylib}
    
    #修改日志段笙蒙,可以記錄每次的修改日志抵屿。
    #第一行是:* 星期 月 日 年 修改人 電子信箱。
    #其中:星期手趣、月份均用英文形式晌该,用中文會(huì)出錯(cuò)肥荔。
    #接下來的行寫的應(yīng)是修改了什么地方绿渣,可寫多行。一般以減號(hào)起始燕耿,便于查閱中符。
    #修改的時(shí)候,新的必須在上面誉帅。
    %changelog
    *Fri Sep 30 2011 QuietHeart
    - 增加XXX內(nèi)容2
    
    *Fri Sep 29 2011 QuietHeart
    - 增加XXX內(nèi)容1
    #+++++++++以下是文件內(nèi)容+++++++++++#
    

2淀散,制做rpm包的具體方法

2.1,工具

通過rpmbuild可以生成相應(yīng)的軟件包蚜锨,下面介紹這個(gè)工具的使用档插,以及幾個(gè)完整的制作rpm軟件包的例子。更多使用這個(gè)工具的信息亚再,參見"man rpmbuild"郭膛。

rpmbuild {-ba|-bb|-bp|-bc|-bi|-bl|-bs} [rpmbuild-options] SPECFILE ...
rpmbuild {-ta|-tb|-tp|-tc|-ti|-tl|-ts} [rpmbuild-options] TARBALL ...
rpmbuild {--rebuild|--recompile} SOURCEPKG ...

功能

創(chuàng)建rpm軟件包。

描述

rpmbuild可以用來制作二進(jìn)制或者源碼軟件包氛悬。軟件包包含文件以及一些meta-data则剃,可以用來安裝或者卸載軟件之用。mata-data包含幫助腳本如捅,文件屬性以及軟件包的其他描述信息棍现。軟件包有兩種形式:二進(jìn)制軟件包,用來安裝軟件時(shí)候使用(一般就是將已經(jīng)編譯好可以直接運(yùn)行的程序打包而成)镜遣;源碼軟件包己肮,包含源代碼等可以構(gòu)建二進(jìn)制軟件包的文件。

這個(gè)工具有三種必選的基本模式:Build Package, Build Package from Tarball, Recompile Package, Show Configuration.這里重點(diǎn)介紹第一種,也就是構(gòu)建軟件包(rpm包)的模式谎僻。

  1. 通用選項(xiàng)

    以下是各種模式下都可以使用的通用選項(xiàng):

    • -?, –help: 打印幫助信息窖剑。
    • –version: 打印單行的,被使用的rpm的版本信息戈稿。
    • –quiet: 打印盡可能少的信息西土,通常只包含錯(cuò)誤信息。
    • -v: 打印詳細(xì)信息鞍盗,一般都包含處理過程需了。
    • -vv: 打印盡可能多的信息。
    • –rcfile FILELIST: 依次讀取FILELIST中被":"分割的文件用于配置信息般甲。第一個(gè)文件必須存在肋乍,默認(rèn)FILELIST是:"usr/lib/rpm/rpmrc:/usr/lib/rpm/redhat/rpmrc:/etc/rpmrc:~.rpmrc".
    • –pipe CMD: 將輸出通過管道輸送給CMD命令。
    • –dbpath DIRECTORY: 使用DIRECTORY中的數(shù)據(jù)庫敷存,而不是默認(rèn)的"var/lib/rpm"中的數(shù)據(jù)庫墓造。
    • –root DIRECTORY: 使用DIRECTORY做為所有操作的相對(duì)的文件系統(tǒng)根目錄。注意這也意味著chroot到DIRECTORY之后锚烦,DIRECTORY中的數(shù)據(jù)庫被用來做依賴性的檢查以及運(yùn)行一些腳本片段(例如:安裝時(shí)候的%post觅闽,或者編譯時(shí)候的%prep)。
  2. BUILD模式的選項(xiàng)

    rpm的build命令一般形式為:

    rpmbuild -bSTAGE|-tSTAGE [ rpmbuild-options ] FILE ...
    

    如果使用spec文件進(jìn)行構(gòu)建涮俄,那么使用的為-b參數(shù)蛉拙,如果使用tar文件中的spec文件進(jìn)行構(gòu)建,那么使用-t的參數(shù)彻亲。-b或者-t參數(shù)之后的STAGE參數(shù)指定了執(zhí)行構(gòu)建軟件包中的哪個(gè)階段(對(duì)應(yīng)于spec文件中的預(yù)處理孕锄,構(gòu)建,安裝等各個(gè)階段)苞尝。

    • -ba: 構(gòu)建二進(jìn)制和源代碼包(執(zhí)行完spec文件中的%prep,%build,和%install階段之后做)畸肆。
    • -bb: 構(gòu)建二進(jìn)制包(執(zhí)行完spec文件中的%prep,%build,和%install階段之后做)。
    • -bp: 執(zhí)行spec文件中的"%prep"段中的內(nèi)容宙址。這個(gè)段一般都是用來解壓準(zhǔn)備生成將要編譯的源代碼以及應(yīng)用補(bǔ)丁等時(shí)候用的轴脐。
    • -bc: 執(zhí)行spec文件中的"%build"段中的內(nèi)容(先運(yùn)行%prep段之后運(yùn)行)。這個(gè)段一般就是相當(dāng)于進(jìn)入源代碼中曼氛,執(zhí)行"make"豁辉,生成可以安裝甚至執(zhí)行的二進(jìn)制文件。
    • -bi: 執(zhí)行spec文件中的"%install"段中的內(nèi)容(先運(yùn)行%prep,%build段之后運(yùn)行)舀患。這個(gè)段一般就是相當(dāng)于進(jìn)入源代碼中徽级,執(zhí)行"make install",將生成的二進(jìn)制等文件安裝到一個(gè)虛擬的根目錄中(就是將那個(gè)目錄當(dāng)做根目錄來看待聊浅,那個(gè)目錄中有usr,etc等根目錄中相同的結(jié)構(gòu))餐抢,以便后面打包時(shí)候使用现使,以后安裝的時(shí)候,一般就按照虛擬根目錄中的結(jié)構(gòu)將軟件安裝旷痕。
    • -bl: 進(jìn)行文件列表檢查碳锈,spec文件的"%files"段是一個(gè)宏擴(kuò)展,這個(gè)檢查用來確保每個(gè)文件是存在的欺抗。
    • -bs: 只構(gòu)建生成源碼軟件包售碳。

    下面是一些build模式中的額外選項(xiàng):

    • –buildroot DIRECTORY: 構(gòu)建軟件包的時(shí)候,將spec文件中的BuildRoot路徑用DIRECTORY來替代(就是指定DIRECTORY為虛擬根目錄)绞呈。
    • –clean: 制作好軟件包之后贸人,清除編譯目錄。如果不指定佃声,那么構(gòu)建好軟件包之后艺智,BUILD下還有解壓的軟件源代碼以及編譯中間文件。
    • –nobuild: 不執(zhí)行任何編譯階段的內(nèi)容圾亏,用于測試spec文件十拣。
    • –rmsource: 構(gòu)建之后,刪除源碼(可以單獨(dú)使用志鹃,例如 "rpmbuild –rmsource foo.spec")夭问。
    • –rmspec: 構(gòu)建之后,刪除spec文件(可以單獨(dú)使用弄跌,例如 "rpmbuild –rmspec foo.spec")甲喝。

    另外,命令: "rpmbuild –showrc" 可以顯示rpmbuild將要使用的當(dāng)前rpmrc中設(shè)置的所有選項(xiàng)和宏值铛只。

2.2,舉例

一個(gè)簡單的測試

這里糠溜,對(duì)于rpmbuild命令淳玩,假設(shè)建立一個(gè)簡單的spec文件myapplication.rpm.spec,然后對(duì)它的各種命令選項(xiàng)進(jìn)行測試非竿。

  1. 1)進(jìn)行之前蜕着,查看當(dāng)前路徑以及文件如下

    # pwd
    /root/test/rpm_test/BUILD
    # ls
    Copyright libmy.so myapplication myapplication.rpm.spec myconfig1.conf myconfig2.conf README
    
  2. 2)查看myapplication.rpm.spec文件如下

    #cat myapplication.rpm.spec
    #+++++++++以下是文件內(nèi)容+++++++++++#
    ######頭部######
    Summary:一個(gè)簡單的打印hello的程序
    Name:myapplication
    Version:1.0
    Release:1
    Vendor:QuietHeart (quiet_heart000@126.com)
    License:Share
    BuildRoot:%{_tmppath}/%{name}-%{version}-%{release}-root
    Group:Applications/Editors
    URL:quietheart.sf.net
    Prefix:%{_prefix}
    Prefix:%{_sysconfdir}
    Prefix:%{_datadir}
    Packager:QuietHeart
    %description
    描述省略。
    
    ######prep,build,install三個(gè)段都可以執(zhí)行shell命令######
    # 預(yù)處理段红柱,為下一步的編譯安裝作準(zhǔn)備承匣。例如將源代碼拷貝到BUILDS目錄。
    %prep
    # prep start.
    echo "======>In :prep section $(pwd)"
    #echo "======>In :prep section " %{_topdir}
    #echo "======>In :prep section $RPM_BUILD_ROOT"
    #echo "======>In :prep section " %{_sourcedir}
    #echo "======>In :prep section $RPM_SOURCE_DIR"
    
    # 建立段锤悄,執(zhí)行一些編譯命令以便生成軟件包韧骗。工作于BUILDS。
    %build
    # build start.
    echo "======>In :build section $(pwd)"
    #echo "======>In :build section " %{_topdir}
    #echo "======>In :build section $RPM_BUILD_ROOT"
    #echo "======>In :build section " %{_builddir}
    #echo "======>In :build section $RPM_BUILD_DIR"
    
    # 安裝段零聚,在安裝軟件包階段執(zhí)行的命令袍暴。
    # 安裝的內(nèi)容安裝到“虛擬根目錄中”install是為了后面的file段服務(wù)的些侍。
    %install
    # install start.
    echo "======>In :install section $(pwd)"
    #echo "======>In :install section " %{_topdir}
    #echo "======>In :install section $RPM_BUILD_ROOT"
    
    ######其它的一些段######
    
    #文件段,定義軟件包所包含的文件政模。具體可由后面"%defattr","%doc","%config"宏定義岗宣。
    #主要包含:config(配置文件),doc(文檔文件),bin(二進(jìn)制文件)
    %files
    
    #定義文件屬性:%defattr(權(quán)限,屬主淋样,屬組)耗式。其中權(quán)限'-'表默認(rèn),可用'0777'形式趁猴。
    %defattr (-,root,root)
    
    #定義制作軟件包包含的文檔文件纽什,每個(gè)宏定義一個(gè),可指定絕對(duì)路徑躲叼。
    #一般文檔文件會(huì)被安裝到"/usr/doc/Name-Version-Release"目錄下芦缰。
    %doc README
    %doc Copyright
    
    #定義軟件包所需要的配置文件(還是安裝的配置文件位置??)
    #當(dāng)卸載軟件的時(shí)候會(huì)將沒有修改過的卸掉,修改過的備份為<name>.rpmsave枫慷。
    %config %{_sysconfdir}/myconfig1.conf
    %config %{_sysconfdir}/myconfig2.conf
    
    #軟件包所包含的二進(jìn)制文件让蕾,可以為目錄
    #%{_bindir}/myapplication
    #%{_libdir}/libmy.so
    
    #修改日志段,可以記錄每次的修改日志或听。
    #第一行是:* 星期 月 日 年 修改人 電子信箱探孝。
    #其中:星期、月份均用英文形式誉裆,用中文會(huì)出錯(cuò)顿颅。
    #接下來的行寫的應(yīng)是修改了什么地方,可寫多行足丢。一般以減號(hào)起始粱腻,便于查閱。
    #修改的時(shí)候斩跌,新的必須在上面绍些。
    %changelog
    *Fri Sep 30 2011 QuietHeart
    - 增加XXX內(nèi)容2
    
    *Fri Sep 29 2011 QuietHeart
    - 增加XXX內(nèi)容1
    #+++++++++以上是文件內(nèi)容+++++++++++#
    
  3. 3)依次測試常用的rpmbuild命令如下

    1. 執(zhí)行myapplication.rpm.spec文件中的prep段

      #rpmbuild -bp myapplication.rpm.spec
      

      輸入之后,輸出如下:

      Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.23258
      + umask 022
      + cd /usr/src/redhat/BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :prep section /usr/src/redhat/BUILD'
      ======>In :prep section /usr/src/redhat/BUILD
      + exit 0
      

      這里耀鸦,prep段是編譯之前的預(yù)處理段柬批,一般都用做將一些類似源代碼文件等拷貝到合適的位置,有待編譯袖订。由此可知氮帐,處理prep的時(shí)候,自動(dòng)將當(dāng)前路徑切換到了"/usr/src/redhat/BUILD"中洛姑。

    2. 執(zhí)行myapplication.rpm.spec文件中的build段

      #rpmbuild -bc myapplication.rpm.spec
      

      輸入之后上沐,輸出如下:

      Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.36144
      + umask 022
      + cd /usr/src/redhat/BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :prep section /usr/src/redhat/BUILD'
      ======>In :prep section /usr/src/redhat/BUILD
      + exit 0
      Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.36144
      + umask 022
      + cd /usr/src/redhat/BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :build section /usr/src/redhat/BUILD'
      ======>In :build section /usr/src/redhat/BUILD
      + exit 0
      

      這里,build段一般都是執(zhí)行源代碼編譯的動(dòng)作。由這里可見盗棵,執(zhí)行build段之前會(huì)先執(zhí)行prep段。處理build的時(shí)候贱勃,自動(dòng)將當(dāng)前路徑切換到了"/usr/src/redhat/BUILD"中昂勒。

    3. 執(zhí)行myapplication.rpm.spec文件中的install段

      #rpmbuild -bi myapplication.rpm.spec
      

      輸入之后蜀细,輸出如下:

      Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.27835
      + umask 022
      + cd /usr/src/redhat/BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :prep section /usr/src/redhat/BUILD'
      ======>In :prep section /usr/src/redhat/BUILD
      + exit 0
      Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.27835
      + umask 022
      + cd /usr/src/redhat/BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :build section /usr/src/redhat/BUILD'
      ======>In :build section /usr/src/redhat/BUILD
      + exit 0
      Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.27835
      + umask 022
      + cd /usr/src/redhat/BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :install section /usr/src/redhat/BUILD'
      ======>In :install section /usr/src/redhat/BUILD
      + /usr/lib/rpm/redhat/brp-compress
      + /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
      + /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
      + /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
      + /usr/lib/rpm/brp-python-bytecompile
      + /usr/lib/rpm/redhat/brp-java-repack-jars
      Processing files: myapplication-1.0-1
      error: File not found: /var/tmp/myapplication-1.0-1-root/etc/myconfig1.conf
      error: File not found: /var/tmp/myapplication-1.0-1-root/etc/myconfig2.conf
      Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.88394
      + umask 022
      + cd /usr/src/redhat/BUILD
      + DOCDIR=/var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + export DOCDIR
      + rm -rf /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + /bin/mkdir -p /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + cp -pr README /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      cp: 無法 stat “README”: 沒有那個(gè)文件或目錄
      error: Bad exit status from /var/tmp/rpm-tmp.88394 (%doc)
      Checking for unpackaged file(s): /usr/lib/rpm/check-files /var/tmp/myapplication-1.0-1-root
      
      
      RPM build errors:
      File not found: /var/tmp/myapplication-1.0-1-root/etc/myconfig1.conf
      File not found: /var/tmp/myapplication-1.0-1-root/etc/myconfig2.conf
      Bad exit status from /var/tmp/rpm-tmp.88394 (%doc)
      

      這里,由于install段沒有建立相應(yīng)的文件戈盈,出現(xiàn)了錯(cuò)誤奠衔,但是根據(jù)錯(cuò)誤的提示,我們還是可以知道究竟rpmbuild做了什么的塘娶。

      install段主要就是為了后面指定的file段服務(wù)的归斤,也就是說install段將需要安裝的文件安裝到虛擬根目錄中,然后file段指定被安裝到虛擬根目錄中的文件刁岸。從這里看出脏里,install沒有做任何的動(dòng)作,并且執(zhí)行install段的時(shí)候已經(jīng)執(zhí)行了prep段和build段虹曙,同時(shí)當(dāng)前路徑為'/usr/src/redhat/BUILD'迫横,然后就將install段執(zhí)行完了。接著酝碳,將自動(dòng)執(zhí)行file段矾踱,根據(jù)file段指示的文件以及之前在install段拷貝好的一些文件,以及虛擬根目錄myapplication.rpm.spec中的"BuildRoot:%{_tmppath}/%{name}-%{version}-%{release}-root"指定的路徑疏哗,執(zhí)行一些動(dòng)作呛讲。另外實(shí)踐發(fā)現(xiàn),這里使用"rpmbuild -ba myapplication.rpm.spec"以及"rpmbuild -bb myapplication.rpm.spec"所顯示的輸出一樣返奉。如果設(shè)置好了贝搁,沒有出錯(cuò)的話,那么此處就會(huì)在虛擬根目錄中安裝上相應(yīng)的文件(也就是files指定的文件)衡瓶。如果使用的是"rpmbuild -bb myapplication.rpm.spec"那么就會(huì)繼續(xù)根據(jù)虛擬根目錄徘公,制作相應(yīng)的rpm包,存放在與BUILD目錄同級(jí)的RPMS下哮针。

    4. 自定義"%{_topdir}"

      # pwd
      /root/test/rpm_test/BUILD
      # echo %_topdir $(pwd)/../ >~/.rpmmacros
      # rpmbuild -bi myapplication.rpm.spec
      Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.18065
      + umask 022
      + cd /root/test/rpm_test/BUILD/..//BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :prep section /root/test/rpm_test/BUILD'
      ======>In :prep section /root/test/rpm_test/BUILD
      + exit 0
      Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.18065
      + umask 022
      + cd /root/test/rpm_test/BUILD/..//BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :build section /root/test/rpm_test/BUILD'
      ======>In :build section /root/test/rpm_test/BUILD
      + exit 0
      Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.18065
      + umask 022
      + cd /root/test/rpm_test/BUILD/..//BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :install section /root/test/rpm_test/BUILD'
      ======>In :install section /root/test/rpm_test/BUILD
      + /usr/lib/rpm/redhat/brp-compress
      + /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
      + /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
      + /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
      + /usr/lib/rpm/brp-python-bytecompile
      + /usr/lib/rpm/redhat/brp-java-repack-jars
      Processing files: myapplication-1.0-1
      error: File not found: /var/tmp/myapplication-1.0-1-root/etc/myconfig1.conf
      error: File not found: /var/tmp/myapplication-1.0-1-root/etc/myconfig2.conf
      Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.18065
      + umask 022
      + cd /root/test/rpm_test/BUILD/..//BUILD
      + DOCDIR=/var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + export DOCDIR
      + rm -rf /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + /bin/mkdir -p /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + cp -pr README /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + cp -pr Copyright /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + exit 0
      Checking for unpackaged file(s): /usr/lib/rpm/check-files /var/tmp/myapplication-1.0-1-root
      
      
      RPM build errors:
      File not found: /var/tmp/myapplication-1.0-1-root/etc/myconfig1.conf
      File not found: /var/tmp/myapplication-1.0-1-root/etc/myconfig2.conf
      

      這里,其實(shí)前面例子的"/usr/src/redhat"是"%{_topdir}"坦袍,類似的變量有很多十厢,不列舉了,具體可以查看"/usr/lib/rpm/macros"中的定義捂齐。如果修改它蛮放,就可以定義rpm默認(rèn)的build路徑,默認(rèn)為/usr/src/redhat奠宜,所以我們這樣修改:

      echo %_topdir $(pwd)/../ >~/.rpmmacros
      

      當(dāng)然包颁,這假設(shè)當(dāng)前路徑為:"/root/test/rpm_test/BUILD"瞻想,這樣執(zhí)行prep,build娩嚼,install等就會(huì)在當(dāng)前路徑下進(jìn)行而不是切換到默認(rèn)的"/usr/src/redhat/BUILD"了蘑险。

一個(gè)好用的例子

這里例子將展示把一個(gè)編譯好的可執(zhí)行程序打包。

  1. 1)查看制作之前的目錄結(jié)構(gòu)

    # pwd
    /root/test/rpm_test
    # ls
    BUILD RPMS
    # tree BUILD/ RPMS
    BUILD/
    |-- COPYRIGHT
    |-- Copyright
    |-- README
    |-- libmy.so
    |-- myapplication
    |-- myapplication.rpm.spec
    `-- myconfig.conf
    RPMS
    `-- i386
    `-- myapplication-1.0-1.i386.rpm
    
    1 directory, 8 files
    
  2. 2)建立的rpm的spec文件如下

    # cd BUILD/
    # cat myapplication.rpm.spec
    #+++++++++以下是文件內(nèi)容+++++++++++#
    ######頭部######
    Summary:一個(gè)簡單的打印hello的程序
    Name:myapplication
    Version:1.0
    Release:1
    Vendor:QuietHeart (quiet_heart000@126.com)
    License:Share
    BuildRoot:%{_tmppath}/%{name}-%{version}-%{release}-root
    Group:Applications/Editors
    URL:quietheart.sf.net
    Prefix:%{_prefix}
    Prefix:%{_sysconfdir}
    Prefix:%{_datadir}
    Packager:QuietHeart
    %define myconfig myconfig.conf
    %define mylib libmy.so
    %description
    描述省略岳悟。
    
    ######prep,build,install三個(gè)段都可以執(zhí)行shell命令######
    # 預(yù)處理段佃迄,為下一步的編譯安裝作準(zhǔn)備。例如將源代碼拷貝到BUILDS目錄贵少。
    %prep
    # prep start.
    echo "======>In :prep section $(pwd)"
    echo "======>In :prep section " %{_topdir}
    echo "======>In :prep section $RPM_BUILD_ROOT"
    echo "======>In :prep section " %{_sourcedir}
    #echo "======>In :prep section $RPM_SOURCE_DIR"
    
    # 建立段呵俏,執(zhí)行一些編譯命令以便生成軟件包。工作于BUILDS滔灶。
    %build
    # build start.
    echo "======>In :build section $(pwd)"
    echo "======>In :build section " %{_topdir}
    echo "======>In :build section $RPM_BUILD_ROOT"
    echo "======>In :build section " %{_builddir}
    #echo "======>In :build section $RPM_BUILD_DIR"
    echo "nothing" >>README
    echo "By QuietHeart" >>COPYRIGHT
    
    # 安裝段普碎,在安裝軟件包階段執(zhí)行的命令。
    # 安裝的內(nèi)容安裝到“虛擬根目錄中”install是為了后面的file段服務(wù)的录平。
    %install
    # install start.
    echo "======>In :install section $(pwd)"
    echo "======>In :install section " %{_topdir}
    echo "======>In :install section $RPM_BUILD_ROOT"
    mkdir -p $RPM_BUILD_ROOT/usr/bin
    mkdir -p $RPM_BUILD_ROOT/usr/lib
    mkdir -p $RPM_BUILD_ROOT/etc
    #這里使用%{name}表示開始定義的Name麻车,即myapplication。
    cp %{name} $RPM_BUILD_ROOT/usr/bin
    cp %{mylib} $RPM_BUILD_ROOT/usr/lib
    cp %{myconfig} $RPM_BUILD_ROOT/etc
    
    ######其它的一些段######
    #制作完之后萄涯,會(huì)執(zhí)行這里绪氛,以便刪除例如$RPM_BUILD_ROOT之類的臨時(shí)文件。
    %clean
    # clean start.
    echo "======>In :clean section $(pwd)"
    echo "======>In :clean section $RPM_BUILD_ROOT"
    #[ -d $RPM_BUILD_ROOT] && rm -rf $RPM_BUILD_ROOT
    
    #文件段涝影,定義軟件包所包含的文件枣察。具體可由后面"%defattr","%doc","%config"宏定義。
    #主要包含:config(配置文件),doc(文檔文件),bin(二進(jìn)制文件)
    %files
    #定義文件屬性:%defattr(權(quán)限燃逻,屬主序目,屬組)。其中權(quán)限'-'表默認(rèn)伯襟,可用'0777'形式猿涨。
    %defattr (-,root,root)
    
    #定義制作軟件包包含的文檔文件,每個(gè)宏定義一個(gè)姆怪,可指定絕對(duì)路徑叛赚。
    #一般文檔文件會(huì)被安裝到"/usr/doc/Name-Version-Release"目錄下。
    %doc README
    %doc Copyright
    
    #定義軟件包所需要的配置文件(還是安裝的配置文件位置??)
    #當(dāng)卸載軟件的時(shí)候會(huì)將沒有修改過的卸掉稽揭,修改過的備份為<name>.rpmsave俺附。
    %config %{_sysconfdir}/%{myconfig}
    
    #軟件包所包含的二進(jìn)制文件,可以為目錄
    %{_bindir}/%{name}
    %{_libdir}/%{mylib}
    
    #修改日志段溪掀,可以記錄每次的修改日志事镣。
    #第一行是:* 星期 月 日 年 修改人 電子信箱。
    #其中:星期揪胃、月份均用英文形式璃哟,用中文會(huì)出錯(cuò)氛琢。
    #接下來的行寫的應(yīng)是修改了什么地方,可寫多行随闪。一般以減號(hào)起始阳似,便于查閱。
    #修改的時(shí)候蕴掏,新的必須在上面障般。
    %changelog
    *Fri Sep 30 2011 QuietHeart
    - 增加XXX內(nèi)容2
    
    *Fri Sep 29 2011 QuietHeart
    - 增加XXX內(nèi)容1
    #+++++++++以上是文件內(nèi)容+++++++++++#
    
  3. 3)制作rpm包

    # echo %_topdir $(pwd)/../ >~/.rpmmacros
    # rpmbuild -bb myapplication.rpm.spec
    Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.35758
    + umask 022
    + cd /root/test/rpm_test/BUILD/..//BUILD
    + LANG=C
    + export LANG
    + unset DISPLAY
    ++ pwd
    + echo '======>In :prep section /root/test/rpm_test/BUILD'
    ======>In :prep section /root/test/rpm_test/BUILD
    + echo '======>In :prep section ' /root/test/rpm_test/BUILD/../
    ======>In :prep section /root/test/rpm_test/BUILD/../
    + echo '======>In :prep section /var/tmp/myapplication-1.0-1-root'
    ======>In :prep section /var/tmp/myapplication-1.0-1-root
    + echo '======>In :prep section ' /root/test/rpm_test/BUILD/..//SOURCES
    ======>In :prep section /root/test/rpm_test/BUILD/..//SOURCES
    + exit 0
    Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.35758
    + umask 022
    + cd /root/test/rpm_test/BUILD/..//BUILD
    + LANG=C
    + export LANG
    + unset DISPLAY
    ++ pwd
    + echo '======>In :build section /root/test/rpm_test/BUILD'
    ======>In :build section /root/test/rpm_test/BUILD
    + echo '======>In :build section ' /root/test/rpm_test/BUILD/../
    ======>In :build section /root/test/rpm_test/BUILD/../
    + echo '======>In :build section /var/tmp/myapplication-1.0-1-root'
    ======>In :build section /var/tmp/myapplication-1.0-1-root
    + echo '======>In :build section ' /root/test/rpm_test/BUILD/..//BUILD
    ======>In :build section /root/test/rpm_test/BUILD/..//BUILD
    + echo nothing
    + echo 'By QuietHeart'
    + exit 0
    Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.35758
    + umask 022
    + cd /root/test/rpm_test/BUILD/..//BUILD
    + LANG=C
    + export LANG
    + unset DISPLAY
    ++ pwd
    + echo '======>In :install section /root/test/rpm_test/BUILD'
    ======>In :install section /root/test/rpm_test/BUILD
    + echo '======>In :install section ' /root/test/rpm_test/BUILD/../
    ======>In :install section /root/test/rpm_test/BUILD/../
    + echo '======>In :install section /var/tmp/myapplication-1.0-1-root'
    ======>In :install section /var/tmp/myapplication-1.0-1-root
    + mkdir -p /var/tmp/myapplication-1.0-1-root/usr/bin
    + mkdir -p /var/tmp/myapplication-1.0-1-root/usr/lib
    + mkdir -p /var/tmp/myapplication-1.0-1-root/etc
    + cp myapplication /var/tmp/myapplication-1.0-1-root/usr/bin
    + cp libmy.so /var/tmp/myapplication-1.0-1-root/usr/lib
    + cp myconfig.conf /var/tmp/myapplication-1.0-1-root/etc
    + /usr/lib/rpm/redhat/brp-compress
    + /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
    + /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
    + /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
    + /usr/lib/rpm/brp-python-bytecompile
    + /usr/lib/rpm/redhat/brp-java-repack-jars
    Processing files: myapplication-1.0-1
    Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.35758
    + umask 022
    + cd /root/test/rpm_test/BUILD/..//BUILD
    + DOCDIR=/var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + export DOCDIR
    + rm -rf /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + /bin/mkdir -p /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + cp -pr README /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + cp -pr Copyright /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + exit 0
    Provides: config(myapplication) = 1.0-1 libmy.so
    Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
    Requires: config(myapplication) = 1.0-1 libc.so.6 libc.so.6(GLIBC_2.0) libc.so.6(GLIBC_2.1.3) libgcc_s.so.1 libm.so.6 libmy.so libstdc++.so.6 libstdc++.so.6(CXXABI_1.3) libstdc++.so.6(GLIBCXX_3.4) rtld(GNU_HASH)
    Checking for unpackaged file(s): /usr/lib/rpm/check-files /var/tmp/myapplication-1.0-1-root
    warning: Could not canonicalize hostname: lv-k.domain.com
    Wrote: /root/test/rpm_test/RPMS/i386/myapplication-1.0-1.i386.rpm
    Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.13498
    + umask 022
    + cd /root/test/rpm_test/BUILD/..//BUILD
    ++ pwd
    + echo '======>In :clean section /root/test/rpm_test/BUILD'
    ======>In :clean section /root/test/rpm_test/BUILD
    + exit 0
    
  4. 4)查看制作結(jié)果

    # tree ../BUILD/ ../RPMS
    ../BUILD/
    |-- COPYRIGHT
    |-- Copyright
    |-- README
    |-- libmy.so
    |-- myapplication
    |-- myapplication.rpm.spec
    `-- myconfig.conf
    ../RPMS
    `-- i386
    `-- myapplication-1.0-1.i386.rpm
    
    1 directory, 8 files
    

    可見,生成的結(jié)果在../RPMS/i386之中盛杰。

    另外挽荡,根據(jù)spec文件,可知道即供,在"var/tmp/myapplication-1.0-1-root"下還生成一些制作rpm包時(shí)候的臨時(shí)文件定拟,如下:

    # tree /var/tmp/myapplication-1.0-1-root/
    /var/tmp/myapplication-1.0-1-root/
    |-- etc
    | `-- myconfig.conf
    `-- usr
    |-- bin
    | `-- myapplication
    |-- lib
    | `-- libmy.so
    `-- share
    `-- doc
    `-- myapplication-1.0
    |-- Copyright
    `-- README
    
    7 directories, 5 files
    

    這些文件,可以在spec文件中的clean段里面指定刪除逗嫡。另外還需要注意的是青自,這里使用rpmbuild的-bb選項(xiàng),如果使用-ba的話也會(huì)報(bào)錯(cuò)驱证,如下:

    # rpmbuild -ba myapplication.rpm.spec
    ...前面省略...
    ======>In :install section /var/tmp/myapplication-1.0-1-root
    + mkdir -p /var/tmp/myapplication-1.0-1-root/usr/bin
    + mkdir -p /var/tmp/myapplication-1.0-1-root/usr/lib
    + mkdir -p /var/tmp/myapplication-1.0-1-root/etc
    + cp myapplication /var/tmp/myapplication-1.0-1-root/usr/bin
    + cp libmy.so /var/tmp/myapplication-1.0-1-root/usr/lib
    + cp myconfig.conf /var/tmp/myapplication-1.0-1-root/etc
    + /usr/lib/rpm/redhat/brp-compress
    + /usr/lib/rpm/redhat/brp-strip /usr/bin/strip
    + /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
    + /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
    + /usr/lib/rpm/brp-python-bytecompile
    + /usr/lib/rpm/redhat/brp-java-repack-jars
    Processing files: myapplication-1.0-1
    Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.6317
    + umask 022
    + cd /root/test/rpm_test/BUILD/..//BUILD
    + DOCDIR=/var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + export DOCDIR
    + rm -rf /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + /bin/mkdir -p /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + cp -pr README /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + cp -pr Copyright /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
    + exit 0
    Provides: config(myapplication) = 1.0-1 libmy.so
    Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
    Requires: config(myapplication) = 1.0-1 libc.so.6 libc.so.6(GLIBC_2.0) libc.so.6(GLIBC_2.1.3) libgcc_s.so.1 libm.so.6 libmy.so libstdc++.so.6 libstdc++.so.6(CXXABI_1.3) libstdc++.so.6(GLIBCXX_3.4) rtld(GNU_HASH)
    Checking for unpackaged file(s): /usr/lib/rpm/check-files /var/tmp/myapplication-1.0-1-root
    warning: Could not canonicalize hostname: lv-k.domain.com
    error: Could not open /root/test/rpm_test/SRPMS/myapplication-1.0-1.src.rpm: 沒有那個(gè)文件或目錄
    
  5. 5)使用制作好的rpm包

    1. 查看軟件包頭

      # rpm -qpi ../RPMS/i386/myapplication-1.0-1.i386.rpm
      Name : myapplication Relocations: /usr /etc /usr/share
      Version : 1.0 Vendor: QuietHeart (quiet_heart000@126.com)
      Release : 1 Build Date: 2011年10月07日 星期五 14時(shí)40分35秒
      Install Date: (not installed) Build Host: lv-k.domain.com
      Group : Applications/Editors Source RPM: myapplication-1.0-1.src.rpm
      Size : 12504 License: Share
      Signature : (none)
      Packager : QuietHeart
      URL : quietheart.sf.net
      Summary : 一個(gè)簡單的打印hello的程序
      Description :
      描述省略延窜。
      
    2. 查看軟件包的全部文件列表

      # rpm -qpl ../RPMS/i386/myapplication-1.0-1.i386.rpm
      /etc/myconfig.conf
      /usr/bin/myapplication
      /usr/lib/libmy.so
      /usr/share/doc/myapplication-1.0
      /usr/share/doc/myapplication-1.0/Copyright
      /usr/share/doc/myapplication-1.0/README
      

      這里,顯示的就是安裝軟件將要向哪些目錄安裝什么文件抹锄。

    3. 安裝軟件

      # rpm -ivh ../RPMS/i386/myapplication-1.0-1.i386.rpm
      Preparing... ########################################### [100%]
      1:myapplication ########################################### [100%]
      
    4. 查詢被安裝的軟件

      # rpm -qa |grep myapplication
      myapplication-1.0-1
      
    5. 運(yùn)行軟件

      # myapplication
      begin test
      hello
      

      這里逆瑞,軟件源代碼省略,以后會(huì)有更詳細(xì)的講解伙单。

    6. 卸載軟件

      # rpm -e myapplication-1.0-1
      

一個(gè)較完整的例子

這里是一個(gè)較完整的制作rpm軟件包的例子获高,先只給出簡單過程,然后詳細(xì)介紹吻育。

  1. a念秧,最簡過程

    # pwd
    /root/test/rpm_test
    # tree
    .
    |-- BUILD
    |-- RPMS
    | `-- i386
    |-- SOURCES
    | `-- myapplication-1.0.tgz
    |-- SPECS
    | `-- myapplication.rpm.spec
    `-- SRPMS
    
    6 directories, 2 files
    # echo %_topdir $(pwd) >~/.rpmmacrosmacros
    # rpmbuild -ba SPECS/myapplication.rpm.spec
    
    # tree
    .
    |-- BUILD
    | `-- myapplication-1.0
    | |-- COPYRIGHT
    | |-- Makefile
    | |-- README
    | |-- debugfiles.list
    | |-- debuglinks.list
    | |-- debugsources.list
    | |-- lib
    | | |-- Makefile
    | | |-- libmy.so
    | | |-- myfile.cpp
    | | |-- myfile.h
    | | `-- myfile.o
    | |-- main.cpp
    | |-- main.o
    | |-- myapplication
    | |-- myconfig.conf
    | `-- myfile.h
    |-- RPMS
    | `-- i386
    | |-- myapplication-1.0-1.i386.rpm
    | `-- myapplication-debuginfo-1.0-1.i386.rpm
    |-- SOURCES
    | `-- myapplication-1.0.tgz
    |-- SPECS
    | `-- myapplication.rpm.spec
    `-- SRPMS
    `-- myapplication-1.0-1.src.rpm
    
    8 directories, 21 files
    
  2. b,詳細(xì)過程

    1. 1)查看文件結(jié)構(gòu)

      # pwd
      /root/test/rpm_test
      # tree
      .
      |-- BUILD
      |-- RPMS
      | `-- i386
      |-- SOURCES
      | `-- myapplication-1.0.tgz
      |-- SPECS
      | `-- myapplication.rpm.spec
      `-- SRPMS
      
      6 directories, 2 files
      
    2. 2)源代碼和rpm的spec文件內(nèi)容

      1. 2.1)源代碼文件相關(guān)

        假設(shè)將SOURCES/myapplication-1.0.tgz解壓(實(shí)際運(yùn)行"rpm -bp"的時(shí)候就是這樣做的布疼,并且解到BUILD供后面的步驟使用)摊趾,

        #tree myapplication
        myapplication-1.0
        |-- COPYRIGHT
        |-- Makefile
        |-- README
        |-- lib
        | |-- Makefile
        | |-- myfile.cpp
        | `-- myfile.h
        |-- main.cpp
        |-- myconfig.conf
        `-- myfile.h
        
        1 directory, 9 files
        

        每個(gè)文件內(nèi)容依次如下:

        # cat myapplication-1.0/COPYRIGHT
        By QuietHeart
        
        # cat myapplication-1.0/Makefile
        myapplication:main.o libmy.so
        g++ main.o -L./lib/ -lmy -o myapplication
        main.o:main.cpp
        libmy.so:
        make -C ./lib
        
        .PHONY:clean
        clean:
        make -C ./lib clean
        rm *.o myapplication
        
        # cat myapplication-1.0/README
        nothing
        
        # cat myapplication-1.0/main.cpp
        #include<iostream>
        #include "myfile.h"
        using std::cout;
        using std::endl;
        int main(int argc, char *argv[])
        {
        cout<<"begin test"<<endl;
        printInfo();
        return 0;
        }
        
        # cat myapplication-1.0/myconfig.conf
        configure content
        
        # cat myapplication-1.0/myfile.h
        #ifndef __MYFILE_H
        #define __MYFILE_H
        void printInfo();
        #endif
        
        # cat myapplication-1.0/lib/Makefile
        libmy.so:myfile.o
        g++ -shared -o libmy.so myfile.o
        myfile.o:myfile.cpp
        
        .PHONY:clean
        clean:
        rm *.so *.o
        
        # cat myapplication-1.0/lib/myfile.cpp
        #include "myfile.h"
        #include <iostream>
        using std::cout;
        using std::endl;
        void printInfo()
        {
        cout<<"hello"<<endl;
        }
        
        # cat myapplication-1.0/lib/myfile.h
        #ifndef __MYFILE_H
        #define __MYFILE_H
        void printInfo();
        #endif
        
      2. 2.2)spec文件相關(guān)

        # tree SPECS/
        SPECS/
        `-- myapplication.rpm.spec
        
        0 directories, 1 file
        

        查看其文件內(nèi)容如下:

        # cat SPECS/myapplication.rpm.spec
        ######頭部######
        Summary:一個(gè)簡單的打印hello的程序
        Name:myapplication
        Version:1.0
        Release:1
        Vendor:QuietHeart (quiet_heart000@126.com)
        License:Share
        SOURCE:%{name}-%{version}.tgz
        BuildRoot:%{_tmppath}/%{name}-%{version}-%{release}-root
        Group:Applications/Editors
        URL:quietheart.sf.net
        Prefix:%{_prefix}
        Prefix:%{_sysconfdir}
        Prefix:%{_datadir}
        Packager:QuietHeart
        %define myconfig myconfig.conf
        %define mylib libmy.so
        %description
        描述省略。
        
        ######prep,build,install三個(gè)段都可以執(zhí)行shell命令######
        # 預(yù)處理段游两,為下一步的編譯安裝作準(zhǔn)備严就。例如將源代碼拷貝到BUILDS目錄。
        %prep
        # prep start.
        echo "======>In :prep section $(pwd)"
        echo "======>In :prep section " %{_topdir}
        echo "======>In :prep section $RPM_BUILD_ROOT"
        echo "======>In :prep section " %{_sourcedir}
        #echo "======>In :prep section $RPM_SOURCE_DIR"
        #將源代碼包解壓并放好器罐,也可以使用tar命令,解壓好的目錄:%{name}-%{version}渐行,存在BUILD中轰坊。
        %setup -n %{name}-%{version}
        #tar -xzvf %{_sourcedir}/%{name}-%{version}.tgz -C %{_builddir}
        
        # 建立段铸董,執(zhí)行一些編譯命令以便生成軟件包。工作于BUILDS肴沫。
        %build
        # build start.
        echo "======>In :build section $(pwd)"
        echo "======>In :build section " %{_topdir}
        echo "======>In :build section $RPM_BUILD_ROOT"
        echo "======>In :build section " %{_builddir}
        #echo "======>In :build section $RPM_BUILD_DIR"
        #自動(dòng)進(jìn)入myapplication-1.0中了粟害。
        make
        
        # 安裝段,在安裝軟件包階段執(zhí)行的命令颤芬。
        # 安裝的內(nèi)容安裝到“虛擬根目錄中”install是為了后面的file段服務(wù)的悲幅。
        %install
        # install start.
        echo "======>In :install section $(pwd)"
        echo "======>In :install section " %{_topdir}
        echo "======>In :install section $RPM_BUILD_ROOT"
        mkdir -p $RPM_BUILD_ROOT/usr/bin
        mkdir -p $RPM_BUILD_ROOT/usr/lib
        mkdir -p $RPM_BUILD_ROOT/etc
        #這里使用%{name}表示開始定義的Name,即myapplication站蝠。
        cp %{name} $RPM_BUILD_ROOT/usr/bin
        cp lib/%{mylib} $RPM_BUILD_ROOT/usr/lib
        cp %{myconfig} $RPM_BUILD_ROOT/etc
        
        ######其它的一些段######
        %clean
        # clean start.
        echo "======>In :clean section $(pwd)"
        
        #文件段汰具,定義軟件包所包含的文件。具體可由后面"%defattr","%doc","%config"宏定義菱魔。
        #主要包含:config(配置文件),doc(文檔文件),bin(二進(jìn)制文件)
        %files
        #定義文件屬性:%defattr(權(quán)限留荔,屬主,屬組)澜倦。其中權(quán)限'-'表默認(rèn)聚蝶,可用'0777'形式。
        %defattr (-,root,root)
        
        #定義制作軟件包包含的文檔文件藻治,每個(gè)宏定義一個(gè)碘勉,可指定絕對(duì)路徑。
        #一般文檔文件會(huì)被安裝到"/usr/doc/Name-Version-Release"目錄下桩卵。
        %doc README
        %doc COPYRIGHT
        
        #定義軟件包所需要的配置文件(還是安裝的配置文件位置??)
        #當(dāng)卸載軟件的時(shí)候會(huì)將沒有修改過的卸掉验靡,修改過的備份為<name>.rpmsave。
        %config %{_sysconfdir}/%{myconfig}
        
        #軟件包所包含的二進(jìn)制文件吸占,可以為目錄
        %{_bindir}/%{name}
        %{_libdir}/%{mylib}
        
        #修改日志段晴叨,可以記錄每次的修改日志。
        #第一行是:* 星期 月 日 年 修改人 電子信箱矾屯。
        #其中:星期兼蕊、月份均用英文形式,用中文會(huì)出錯(cuò)件蚕。
        #接下來的行寫的應(yīng)是修改了什么地方孙技,可寫多行。一般以減號(hào)起始排作,便于查閱牵啦。
        #修改的時(shí)候,新的必須在上面妄痪。
        %changelog
        *Fri Sep 30 2011 QuietHeart
        - 增加XXX內(nèi)容2
        
        *Fri Sep 29 2011 QuietHeart
        - 增加XXX內(nèi)容1
        
    3. 3)制作rpm包

      # echo %_topdir $(pwd) >~/.rpmmacrosmacros
      # rpmbuild -ba SPECS/myapplication.rpm.spec
      Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.87076
      + umask 022
      + cd /root/test/rpm_test/BUILD/..//BUILD
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :prep section /root/test/rpm_test/BUILD'
      ======>In :prep section /root/test/rpm_test/BUILD
      + echo '======>In :prep section ' /root/test/rpm_test/BUILD/../
      ======>In :prep section /root/test/rpm_test/BUILD/../
      + echo '======>In :prep section /var/tmp/myapplication-1.0-1-root'
      ======>In :prep section /var/tmp/myapplication-1.0-1-root
      + echo '======>In :prep section ' /root/test/rpm_test/BUILD/..//SOURCES
      ======>In :prep section /root/test/rpm_test/BUILD/..//SOURCES
      + cd /root/test/rpm_test/BUILD
      + rm -rf myapplication-1.0
      + /bin/gzip -dc /root/test/rpm_test/SOURCES/myapplication-1.0.tgz
      + tar -xvvf -
      drwxrwxrwx root/root 0 2011-10-07 15:29:19 myapplication-1.0/
      -rw-r--r-- root/root 14 2011-10-07 15:28:56 myapplication-1.0/COPYRIGHT
      drwxrwxrwx root/root 0 2011-10-07 15:16:34 myapplication-1.0/lib/
      -rwxrwxrwx root/root 117 2009-11-21 17:12:18 myapplication-1.0/lib/myfile.cpp
      -rwxr-xr-x root/root 63 2011-09-29 18:17:29 myapplication-1.0/lib/myfile.h
      -rw-r--r-- root/root 106 2011-10-07 15:16:29 myapplication-1.0/lib/Makefile
      -rwxrwxrwx root/root 63 2009-11-21 17:12:18 myapplication-1.0/myfile.h
      -rw-r--r-- root/root 8 2011-10-07 15:28:51 myapplication-1.0/README
      -rw-r--r-- root/root 18 2011-10-07 15:29:19 myapplication-1.0/myconfig.conf
      -rwxrwxrwx root/root 1734 2009-12-10 09:09:06 myapplication-1.0/main.cpp
      -rw-r--r-- root/root 178 2011-10-07 15:16:07 myapplication-1.0/Makefile
      + STATUS=0
      + '[' 0 -ne 0 ']'
      + cd myapplication-1.0
      ++ /usr/bin/id -u
      + '[' 0 = 0 ']'
      + /bin/chown -Rhf root .
      ++ /usr/bin/id -u
      + '[' 0 = 0 ']'
      + /bin/chgrp -Rhf root .
      + /bin/chmod -Rf a+rX,u+w,g-w,o-w .
      + exit 0
      Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.87076
      + umask 022
      + cd /root/test/rpm_test/BUILD/..//BUILD
      + cd myapplication-1.0
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :build section /root/test/rpm_test/BUILD/myapplication-1.0'
      ======>In :build section /root/test/rpm_test/BUILD/myapplication-1.0
      + echo '======>In :build section ' /root/test/rpm_test/BUILD/../
      ======>In :build section /root/test/rpm_test/BUILD/../
      + echo '======>In :build section /var/tmp/myapplication-1.0-1-root'
      ======>In :build section /var/tmp/myapplication-1.0-1-root
      + echo '======>In :build section ' /root/test/rpm_test/BUILD/..//BUILD
      ======>In :build section /root/test/rpm_test/BUILD/..//BUILD
      + make
      g++ -c -o main.o main.cpp
      make -C ./lib
      make[1]: Entering directory `/root/test/rpm_test/BUILD/myapplication-1.0/lib'
      g++ -c -o myfile.o myfile.cpp
      g++ -shared -o libmy.so myfile.o
      make[1]: Leaving directory `/root/test/rpm_test/BUILD/myapplication-1.0/lib'
      g++ main.o -L./lib/ -lmy -o myapplication
      + exit 0
      Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.83304
      + umask 022
      + cd /root/test/rpm_test/BUILD/..//BUILD
      + cd myapplication-1.0
      + LANG=C
      + export LANG
      + unset DISPLAY
      ++ pwd
      + echo '======>In :install section /root/test/rpm_test/BUILD/myapplication-1.0'
      ======>In :install section /root/test/rpm_test/BUILD/myapplication-1.0
      + echo '======>In :install section ' /root/test/rpm_test/BUILD/../
      ======>In :install section /root/test/rpm_test/BUILD/../
      + echo '======>In :install section /var/tmp/myapplication-1.0-1-root'
      ======>In :install section /var/tmp/myapplication-1.0-1-root
      + mkdir -p /var/tmp/myapplication-1.0-1-root/usr/bin
      + mkdir -p /var/tmp/myapplication-1.0-1-root/usr/lib
      + mkdir -p /var/tmp/myapplication-1.0-1-root/etc
      + cp myapplication /var/tmp/myapplication-1.0-1-root/usr/bin
      + cp lib/libmy.so /var/tmp/myapplication-1.0-1-root/usr/lib
      + cp myconfig.conf /var/tmp/myapplication-1.0-1-root/etc
      + /usr/lib/rpm/find-debuginfo.sh /root/test/rpm_test/BUILD/..//BUILD/myapplication-1.0
      + /usr/lib/rpm/redhat/brp-compress
      + /usr/lib/rpm/redhat/brp-strip-static-archive /usr/bin/strip
      + /usr/lib/rpm/redhat/brp-strip-comment-note /usr/bin/strip /usr/bin/objdump
      + /usr/lib/rpm/brp-python-bytecompile
      + /usr/lib/rpm/redhat/brp-java-repack-jars
      Processing files: myapplication-1.0-1
      Executing(%doc): /bin/sh -e /var/tmp/rpm-tmp.83304
      + umask 022
      + cd /root/test/rpm_test/BUILD/..//BUILD
      + cd myapplication-1.0
      + DOCDIR=/var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + export DOCDIR
      + rm -rf /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + /bin/mkdir -p /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + cp -pr README /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + cp -pr COPYRIGHT /var/tmp/myapplication-1.0-1-root/usr/share/doc/myapplication-1.0
      + exit 0
      Provides: config(myapplication) = 1.0-1 libmy.so
      Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
      Requires: config(myapplication) = 1.0-1 libc.so.6 libc.so.6(GLIBC_2.0) libc.so.6(GLIBC_2.1.3) libgcc_s.so.1 libm.so.6 libmy.so libstdc++.so.6 libstdc++.so.6(CXXABI_1.3) libstdc++.so.6(GLIBCXX_3.4) rtld(GNU_HASH)
      Processing files: myapplication-debuginfo-1.0-1
      Provides: libmy.so.debug
      Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1
      Checking for unpackaged file(s): /usr/lib/rpm/check-files /var/tmp/myapplication-1.0-1-root
      warning: Could not canonicalize hostname: lv-k.domain.com
      Wrote: /root/test/rpm_test/SRPMS/myapplication-1.0-1.src.rpm
      Wrote: /root/test/rpm_test/RPMS/i386/myapplication-1.0-1.i386.rpm
      Wrote: /root/test/rpm_test/RPMS/i386/myapplication-debuginfo-1.0-1.i386.rpm
      Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.76622
      + umask 022
      + cd /root/test/rpm_test/BUILD/..//BUILD
      + cd myapplication-1.0
      ++ pwd
      + echo '======>In :clean section /root/test/rpm_test/BUILD/myapplication-1.0'
      ======>In :clean section /root/test/rpm_test/BUILD/myapplication-1.0
      + exit 0
      
    4. 4)查看生成的文件

      # tree
      .
      |-- BUILD
      | `-- myapplication-1.0
      | |-- COPYRIGHT
      | |-- Makefile
      | |-- README
      | |-- debugfiles.list
      | |-- debuglinks.list
      | |-- debugsources.list
      | |-- lib
      | | |-- Makefile
      | | |-- libmy.so
      | | |-- myfile.cpp
      | | |-- myfile.h
      | | `-- myfile.o
      | |-- main.cpp
      | |-- main.o
      | |-- myapplication
      | |-- myconfig.conf
      | `-- myfile.h
      |-- RPMS
      | `-- i386
      | |-- myapplication-1.0-1.i386.rpm
      | `-- myapplication-debuginfo-1.0-1.i386.rpm
      |-- SOURCES
      | `-- myapplication-1.0.tgz
      |-- SPECS
      | `-- myapplication.rpm.spec
      `-- SRPMS
      `-- myapplication-1.0-1.src.rpm
      
      8 directories, 21 files
      

      由上面可見哈雏,生成的文件分別是:

      • BUILD/myapplication-1.0目錄,在prep段指定的命令中解壓SOURCES目錄中的內(nèi)容生成。
      • RPMS/i386/*.rpm裳瘪,制作后期二進(jìn)制rpm包生成土浸。(可以用"rpmbuild -bb"單獨(dú)生成這個(gè))。
      • SRPMS/*.rpm彭羹,制作后期源碼rpm包生成黄伊。(可以用"rpmbuild -bs"單獨(dú)生成這個(gè))。
    5. 5)使用制作的rpm包

      1. 查看軟件包頭

        # rpm -qpi RPMS/i386/myapplication-1.0-1.i386.rpm
        Name : myapplication Relocations: /usr /etc /usr/share
        Version : 1.0 Vendor: QuietHeart (quiet_heart000@126.com)
        Release : 1 Build Date: 2011年10月07日 星期五 16時(shí)13分09秒
        Install Date: (not installed) Build Host: lv-k.domain.com
        Group : Applications/Editors Source RPM: myapplication-1.0-1.src.rpm
        Size : 12580 License: Share
        Signature : (none)
        Packager : QuietHeart
        URL : quietheart.sf.net
        Summary : 一個(gè)簡單的打印hello的程序
        Description :
        描述省略派殷。
        
      2. 查看軟件包的全部文件列表

        # rpm -qpl RPMS/i386/myapplication-1.0-1.i386.rpm
        /etc/myconfig.conf
        /usr/bin/myapplication
        /usr/lib/libmy.so
        /usr/share/doc/myapplication-1.0
        /usr/share/doc/myapplication-1.0/COPYRIGHT
        /usr/share/doc/myapplication-1.0/README
        

        這里还最,顯示的就是安裝軟件將要向哪些目錄安裝什么文件。

      3. 安裝軟件

        # rpm -ivh RPMS/i386/myapplication-1.0-1.i386.rpm
        Preparing... ########################################### [100%]
        1:myapplication ########################################### [100%]
        
      4. 指定前綴的安裝軟件

        # rpm -ivh --relocate=/usr=/root/myprefix/usr --relocate=/etc=/root/myprefix/etc myapplication-1.0-1.i386.rpm
        Preparing... ########################################### [100%]
        1:myapplication ########################################### [100%]
        

        這里毡惜,因?yàn)閟pec中指定了多個(gè)Prefix拓轻,所以使用這個(gè)方式進(jìn)行指定前綴,如果使用"–prefix"虱黄,那么會(huì)如下:

        # rpm -ivh --prefix=/root/myprefix myapplication-1.0-1.i386.rpm
        error: package myapplication is not relocatable
        

        使用–relocate指定之后悦即,查看安裝好的路徑,如下:

        # tree /root/myprefix/
        /root/myprefix/
        |-- etc
        | `-- myconfig.conf
        `-- usr
        |-- bin
        | `-- myapplication
        |-- lib
        | `-- libmy.so
        `-- share
        `-- doc
        `-- myapplication-1.0
        |-- COPYRIGHT
        `-- README
        
        7 directories, 5 files
        

        實(shí)踐發(fā)現(xiàn)橱乱,如果不存在/root/myprefix會(huì)自動(dòng)創(chuàng)建辜梳,如果使用"rpm -e"卸載這樣安裝的軟件,那么只是刪除了/root/myprefix泳叠,但是目錄卻保留作瞄,如下:

        # tree /root/myprefix/
        /root/myprefix/
        |-- etc
        `-- usr
        |-- bin
        |-- lib
        `-- share
        `-- doc
        
        6 directories, 0 files
        

        另外,如果卸之前修改了/etc文件危纫,那么會(huì)提示宗挥,如下:

        # rpm -e myapplication-1.0-1
        warning: /root/myprefix/etc/myconfig.conf saved as /root/myprefix/etc/myconfig.conf.rpmsave
        # tree /root/myprefix/
        /root/myprefix/
        |-- etc
        | `-- myconfig.conf.rpmsave
        `-- usr
        |-- bin
        |-- lib
        `-- share
        `-- doc
        
        6 directories, 1 file
        
      5. 查詢被安裝的軟件

        # rpm -qa |grep myapplication
        myapplication-1.0-1
        
      6. 運(yùn)行軟件

        # myapplication
        begin test
        hello
        

        這里,軟件源代碼省略种蝶,以后會(huì)有更詳細(xì)的講解契耿。

      7. 卸載軟件

        # rpm -e myapplication-1.0-1
        
      8. 查看源碼包頭

        # rpm -qpi SRPMS/myapplication-1.0-1.src.rpm
        Name : myapplication Relocations: (not relocatable)
        Version : 1.0 Vendor: QuietHeart (quiet_heart000@126.com)
        Release : 1 Build Date: 2011年10月07日 星期五 16時(shí)13分09秒
        Install Date: (not installed) Build Host: lv-k.domain.com
        Group : Applications/Editors Source RPM: (none)
        Size : 5084 License: Share
        Signature : (none)
        Packager : QuietHeart
        URL : quietheart.sf.net
        Summary : 一個(gè)簡單的打印hello的程序
        Description :
        描述省略。
        
      9. 查看源碼包文件列表

        # rpm -qpi SRPMS/myapplication-1.0-1.src.rpm
        myapplication-1.0.tgz
        myapplication.rpm.spec
        
      10. 安裝源碼包

        # rpm -ivh SRPMS/myapplication-1.0-1.src.rpm
        1:myapplication ########################################### [100%]
        
      11. 查看剛剛的安裝

        # rpm -qa |grep myapplication
        

        這里螃征,看不出來搪桂,究竟安裝到了哪里。但是實(shí)際上盯滚,是安裝到了SOURCES中和SPECS中了踢械,如果將SOURCES和SPECS中原來的刪掉,再安裝魄藕,就能夠看出來了内列。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市背率,隨后出現(xiàn)的幾起案子话瞧,更是在濱河造成了極大的恐慌嫩与,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件移稳,死亡現(xiàn)場離奇詭異蕴纳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)个粱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翻翩,“玉大人都许,你說我怎么就攤上這事∩┒常” “怎么了胶征?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長桨仿。 經(jīng)常有香客問我睛低,道長,這世上最難降的妖魔是什么服傍? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任钱雷,我火速辦了婚禮,結(jié)果婚禮上吹零,老公的妹妹穿的比我還像新娘罩抗。我一直安慰自己,他們只是感情好灿椅,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布套蒂。 她就那樣靜靜地躺著,像睡著了一般茫蛹。 火紅的嫁衣襯著肌膚如雪操刀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音蒙揣,去河邊找鬼茉贡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛卡啰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播警没,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼匈辱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了杀迹?” 一聲冷哼從身側(cè)響起亡脸,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后浅碾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體大州,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年垂谢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厦画。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡滥朱,死狀恐怖根暑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情徙邻,我是刑警寧澤排嫌,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站缰犁,受9級(jí)特大地震影響淳地,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜帅容,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一颇象、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丰嘉,春花似錦夯到、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至路幸,卻和暖如春荐开,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背简肴。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國打工晃听, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人砰识。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓能扒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親辫狼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子初斑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容