乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      rpm建包原理

       todaytomo 2007-01-09

      為什么要打包?
      制作 rpm 不僅僅是打包,更可以解決菜單創(chuàng)建、打補釘、完成大量預配置、與其他軟件包互動等操作。使用源代碼安裝要求用戶了解基本的編譯過程、能夠應付各種不能編譯的意外、必須自己完成抽象的配置、甚至懂得軟件開發(fā),能夠自己打補釘,……對非計算機專業(yè)的用戶而言簡直就是天方夜譚。這是把軟件開發(fā)的最后一步拋給了用戶,作為發(fā)行版,這是極不負責任的!也是不現(xiàn)實的,除非用 lfs,但那是一本菜譜,不是真正的發(fā)行版。

      軟件作者發(fā)布源代碼是正確的,負責的作者一般都同時提供 rpm 和 deb 包以及它們的源代碼包。除非他們不會制作。愿意使用什么,那是個人的自由,但對外就不能只想到自己。GNU 精神是一種公益精神,沒有奉獻精神,在自由軟件領域是要遭唾棄的!

      直接使用其他發(fā)行版的 rpm 常常是不行的。不知道大家看沒看“惱人的依賴關系”這個帖子。可以在技術支持區(qū)搜索一下。任何兩個發(fā)行版本在二進制上都是不能兼容的!他們實際是不同的操作系統(tǒng)。不僅使用的庫文件不同,配置也迥異。特別是同一個發(fā)行版的不同版本更不兼容。任何包都必須在本地重新編譯,而且不一定通得過,因為還有 spec 宏的兼容問題!如果要在別的發(fā)行版上使用,必須用源碼編譯,這是常識??紤]文件布局和配置問題,有時直接編譯也是不夠的,必須修改 spec,甚至自己打補丁。



      如何創(chuàng)建 rpm 包?
      rpm 建包原理其實不復雜。寫 spec 相當于一種腳本編程,主要是在 spec 里提供一些軟件相關信息,以及安裝、卸載前后要執(zhí)行的腳本,然后展開壓縮的源代碼包,打上補丁,執(zhí)行編譯,然后利用 make install 可以重新指定安裝目的地的特性,把編譯好的文件安裝到指定的虛擬根目錄下的指定位置里,一般是虛擬的 /usr 里,然后把這些目錄、信息和腳本打成一個壓縮包,即 rpm 包。同時可選地生成源碼包 src.rpm。當然有很多具體細節(jié)問題。您應該首先閱讀軟件的 readme 和 INSTALL 文件。



      打包原則
      1. 任何人都應該在系統(tǒng)現(xiàn)有 src.rpm 的 spec 基礎上修改更新,除非沒有這樣的包。這可以省去很多麻煩,少走彎路。
      2. 任何人都無權刪除別人的 changelog 和原始打包者的信息,這是對別人的不尊重。但你可以追加自己的信息。
      3. 盡可能在 spec 里使用系統(tǒng)的標準宏定義,而不要用非標準寫法。
      4. 任何人都不應該直接提供修改后的源代碼,而應該以補丁形式發(fā)布你的修改,在 spec 里完成打補丁操作。務必做到一個補丁只解決一個問題,這樣才能確保補丁的可重用性,否則版本升級后補丁很容易失效。如果你確信自己的補丁是清潔補丁,盡可能發(fā)給上游開發(fā)者,這樣才能一勞永逸。你所打的任何補丁,其授權方式必須和被修改源代碼保持一致。
      5. rpm 不是跨平臺打包技術。確保軟件的二進制代碼能夠跨平臺運行,不是系統(tǒng)軟件打包者要考慮的事,而是應用軟件作者和獨立二進制代碼發(fā)布者應該考慮的事。我們沒有責任和義務確保從我們系統(tǒng)里拆解下來的部件能夠運行于其他系統(tǒng)上,不支持,更不提倡這種移花接木的作法。

      試圖解決跨平臺問題的打包技術,我印象中有 autopackage 和 klik 技術,參見:
      http://
      http://klik.


      預備知識:
      首先我們觀察一下 rpm 文件名的特點。一個 rpm 包文件名通常由 5 段組成:
      %{name}-%{version}-%{release}.ix86.rpm
      cutedict-1.1-1mgc.i686.rpm
      這里 %{name}=cutedict,%{version}=1.1,%{release}=1mgc,ix86=i686,如果是為 athlon 芯片家族編譯的包,這里就是 athlon,依此類推。

      注意:
      下面是一個spec 模板。
      1. 凡是行首加上 # 的都被注釋掉了,實際運行時不起作用,如要使其生效,請去掉注釋符 #。
      2. 凡是以 %{***} 和 %*** 形式出現(xiàn)的符號都是“宏”,很多宏都是系統(tǒng)預定義的[注2],也可以是自己定義的。
      3. 下面的黑體字是 spec 文件的關鍵字,不能寫錯。
      4. 有不明白的地方可以參見跟帖里的參考文獻。
      5. 如果軟件沒有使用 GNU autotool 創(chuàng)建,而是自己寫的 Makefile,這就導致不能按照常規(guī)方法打包,非常麻煩。
      6. 服務器軟件通常都需要大量預配置工作,spec 打包絕非一兩天能解決,需要深入研究很多東西和反復實踐,建議初學者不要嘗試。
      7. 其他發(fā)行版的 spec 與 src.rpm 是很好的教材,建議打包前先找找 Fedora 或 SuSE 的文件學習,能借鑒最好,但不應該不修改照搬過來或使用 Mandrake/Mandriva 的文件,因為它使用的大量專有宏定義和我們不兼容,甚至 src.rpm 直接編譯都通不過。

      ------------------------------------------------------------------

      [spec 文件頭部]

      # Initial spec file created by autospec #這里是一些注釋
      %define _noautoreq perl(Plot) perl(WidgetDemo) #這里用 %define 自定義一個系統(tǒng)里沒有的叫做 _noautoreq 的宏,后面可以用 %{_noautoreq} 引用。
      Name: software #這是軟件包名稱,后面可以用 %{name} 引用
      Summary: a software #這是軟件包的內容提要
      #Summary(zh_CN): #這里寫入中文內容提要(如果有必要。不建議使用,因為如果系統(tǒng)里的默認編碼與此處不符,會導致顯示亂碼。例如:我們使用 GBK,如果這里的中文是 UTF-8 編碼,在 kpackage 里就會顯示亂碼,但是 synaptic 可能能夠正確顯示,但需要把 zh_CN 改為 zh_CN.UTF-8 )
      Version: number #這是軟件的實際版本號,例如 2.1.6、2.2final 等,后面可以用 %{version} 引用
      Release: number #發(fā)布序列號,我們用 1mgc、2mgc 等等,標明這是第幾次打包。如果軟件本身是預覽版,比如 pre6 版,則寫成 pre6_1mgc、pre6_2mgc,后面可以用 %{release} 引用
      Group: Applications/Multimedia #這是軟件分組,建議使用標準分組,參見下面:[注1]
      #Group(zh_CN): #中文軟件分組(如果有必要)
      License: GPL #這是軟件授權方式,通常是 GPL
      Source: %{name}-%{version}.tar.gz #這是源代碼(通常是壓縮包),可以帶有完整的網址,可以用正整數(shù)標識多個源 Source0 Source4 Source5 Source100,數(shù)字不必連續(xù)排列,后面可以用 %{SOURCE0}、%{SOURCE4}、%{SOURCE5}、%{SOURCE100} 引用。例如 http://www./src/%{name}-%{version}.tar.gz
      BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot #這是 make install 時使用的“虛擬根目錄”也稱為“構建根目錄”,通常是 /var/tmp/軟件名稱-版本號-發(fā)布序列號-buildroot。對于服務器環(huán)境,可能同時有多人操作,為了確保編譯軟件時臨時目錄不會相互覆蓋,還需要加上當前用戶的標識:BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot-%(%{__id_u} -n)
      make install 時一般會將軟件安裝在 /var/tmp/軟件名稱-版本號-發(fā)布序列號-buildroot/usr/ 下的 bin/ 下(可執(zhí)行文件)、share/ 下(數(shù)據(jù)、資源文件)、lib/ 下(動態(tài)共享庫文件,即 .so 文件 <Share Object>,相當于 windows 下的 DLL 文件)等等,例如 /var/tmp/cce-0.51-1mgc-buildroot/usr/bin/cce。不過實際不一定都是這樣,具體情況具體對待
      # 下面是可選的字段
      URL: http://www./ #這是軟件主頁地址
      #Vendor: Red Hat Co.,ltd. #這是發(fā)行商或者打包組織的信息,我們統(tǒng)一寫成 MGC Group,不過這一行可以省略,把它寫入 /usr/lib/rpm/macros 標準宏定義文件里,該文件的 Vendor 這行定義是空的,而且通常前面用 # 注釋掉了
      #Distribution: Red Hat Linux #這是軟件針對的發(fā)行版標識,我們是 Magic Linux
      Patch: src-%{version}.patch #這是補丁源代碼(可以是壓縮包),可以用正整數(shù)標識多個源 Patch1 Patch4 Patch6,數(shù)字不必連續(xù)排列。
      Prefix: %{_prefix} #指定 make install 時在虛擬根目錄里的安裝位置,通常用標準的 %{_prefix} 宏,它代表 /usr。這里指定后,用戶可以在 rpm 安裝階段重新指定安裝到其他位置,如 /opt,否則就不能改變安裝位置。
      Prefix: %{_sysconfdir} #如果軟件有些文件并非都安裝到 %{_prefix},那么你需要指明其他位置。例如你需要把一個配置文件放到 /etc 下面,這顯然不在 /usr 下面,此時你需要前方這種寫法。%{_sysconfdir} 宏代表 /etc。這里指定后,用戶可以在 rpm 安裝階段重新指定這些文件安裝到其他位置,如 /opt/etc,否則就不能改變安裝位置。[注3]
      #BuildArch: noarch #編譯目標處理器架構,就是今后軟件運行時的 CPU 類型。noarch 是不指定架構,通常標準默認是 i386,定義在了系統(tǒng)的標準宏定義文件 /usr/lib/rpm/macros 里 [注2]。實際編譯時可以在 rpmbuild 命令行用 --target=i686 參數(shù),spec 里通常不寫這行。
      #Requires: libpng-devel >= 1.0.20 zlib libpng #這里羅列所有安裝本包時需要先行安裝的包(依賴包),通常軟件會依賴這些包里的一部分文件??梢苑殖啥嘈衼韺憽H绻@里不寫明依賴包,打包時系統(tǒng)僅僅會自動把具體依賴的 .so 文件寫進 rpm 包,而不會注明這些文件屬于哪些軟件包,這會對用戶造成困惑,因為他們很難知道這些文件屬于哪些軟件包。注意:如果使用 >= 這樣的符號,務必在其兩邊各保留一個空格
      #Obsoletes: #這里列出的軟件包都是“陳舊”的,當升級安裝本包的時候,這里列出的包都會被自動卸載!
      NoAutoReq: %{_noautoreq} #這里的意思是禁止自動查找對 spec 文件頭部預定義的 _noautoreq 宏里定義的兩個軟件包[perl(Plot) 和 perl(WidgetDemo)]的依賴關系,通常對于 prel 模塊需要這樣處理。因為即便你在 Requires 字段指明了本包所依賴的包含這兩個模塊的那些軟件包,安裝 本包的時候系統(tǒng)仍然會直接查找是否安裝有這些 perl 模塊,而不會查找那些包含這兩個模塊的軟件包是否已經安裝。
      #PreReq: loop #如果在 %pre 字段執(zhí)行的腳本需要使用一些特殊命令,例如 loop,你需要在此標明
      #Requires(post): loop #這是上面一行的另一種寫法,依此類推,還有其他幾個類似的關鍵字:
      #Requires(pre)
      #Requires(preun)
      #Requires(postun)
      #Autoreq: 0 #這里使用 0 關閉了自動標注本軟件包需要的依賴關系的功能,使用 1 或者不寫此行(默認)就是開啟自動標注依賴關系的功能。自動依賴校驗只會通過 pkgconfig 找出依賴的 .so 文件,而絕對不是軟件包!可以通過命令反查生成的 rpm 包所依賴的這些 .so 文件屬于哪個包,再把這些依賴的包的名稱寫進 spec,最后重新編譯就行了。
      #Autoprov: 0 #這里使用 0 關閉了自動標注本軟件包提供的依賴關系的功能,使用 1 或者不寫此行(默認)就是開啟自動標注依賴關系的功能
      #Autoreqprov: 0 此關鍵字兼具上述兩條的功能
      #BuildRequires: libpng-devel >= 1.0.20 #這是編譯時依賴的包
      #Provides: lda #這里標注本軟件包提供的某些特定功能。例如 sendmail 在沒有本地遞送代理 [local delivery agent (lda)] 時不能工作,而你的軟件包恰好提供了這一功能,你需要在此標明。而在 sendmail 的 spec 里你需要寫明:Requires: lda
      Packager: Tony Black <tony@> #這是打包者的信息

      %description 軟件的詳細說明
      This is the description...

      #%description -l zh_CN 中文軟件說明(如果有必要。不建議使用,因為如果系統(tǒng)里的默認編碼與此處不符,會導致顯示亂碼。例如:我們使用 GBK,如果這里的中文是 UTF-8 編碼,在 kpackage 里就會顯示亂碼,但是 synaptic 可能能夠正確顯示,但需要把 zh_CN 改為 zh_CN.UTF-8 )

      [spec 文件體部]

      %prep #下面開始預處理

      %setup -n %{name}-%{version} #到這里,系統(tǒng)把源碼包從 /usr/src/mBuild/SOURCES 解壓縮到 /usr/src/mBuild/BUILD/%{name}-%{version} ,并轉到那里展開的壓縮包目錄(%{name}-%{version} )里,以便完成打補丁等準備工作,最后還要退回到 /usr/src/mBuild/BUILD 目錄下。-n 后面指定的參數(shù)代表 tar 包展開后生成的目錄名,一般 -n %{name}-%{version} 是不需要的,除非 tar 包名稱和展開后生成的目錄名不符,或者你要處理多個 tar 包。如果打包時報告找不到 ./configure 說明 -n 參數(shù)指定的目錄不對,或者軟件源代碼目錄里沒有 configure 腳本 (比如你的代碼是從 cvs 里 commit out 出來的,你需要進行一些準備工作,比如通過運行 autogen.sh 腳本來自動創(chuàng)建 configure 腳本。這具體看是哪個軟件,不同軟件有不同的方法)。如果有多個源代碼包要編譯,用“-n 名稱”指定多個 setup 字段。

      %patch #這里開始打補丁。例如 %patch0 -p1,%Patch2 -p1 -b .xxx.patch 這里 %patch0 是對第一個補丁的引用,%Patch2 -p1 -b .xxx.patch 表明第二個補丁是壓縮包,要先解壓縮,再打補丁。 -p1 是 patch 命令的常用參數(shù),代表忽略 patch 時的第一(頂)層目錄。(為什么?因為創(chuàng)建補丁時兩個比照的目錄或者文件名肯定是不同的。參見[注5])

      %configure #系統(tǒng)重新進入 /usr/src/mBuild/BUILD/%{name}-%{version} 執(zhí)行 configure 腳本進行配置,然后返回 /usr/src/mBuild/BUILD 目錄下。%configure 是 rpm 定義的標準配置宏,含義很復雜,但絕對標準。具體含義參見 [注2]。非標準寫法:
      CFLAGS="$RPM_OPT_FLAGS" \
      CXXFLAGS="$RPM_OPT_FLAGS" \
      ./configure --prefix=%{_prefix}
      或者:
      CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{_prefix}

      %build #開始構建包。系統(tǒng)重新進入 /usr/src/mBuild/BUILD/%{name}-%{version} 執(zhí)行 make,然后返回 /usr/src/mBuild/BUILD 目錄下。
      make %{?_smp_mflags} OPTIMIZE="%{optflags}" #這是 make 命令,其兩個參數(shù)的含意是:
      %{?_smp_mflags} 如果系統(tǒng)里定義了make 的并行編譯參數(shù),則使用這個參數(shù)。例如: -j2 表示 make 同時執(zhí)行兩個文件的編譯操作。如果你使用多個 CPU 或者非單核 CPU,這個參數(shù)可以明顯提高編譯速度,但是這里指定的數(shù)字不宜超過你的 CPU 內核數(shù)量+1。
      OPTIMIZE="%{optflags}" 如果系統(tǒng)里定義了 gcc 的優(yōu)化參數(shù),則在軟件默認優(yōu)化參數(shù)的基礎上追加使用這里指定的優(yōu)化參數(shù)。例如: -O2 -g -pipe 表示使用 gcc 第二優(yōu)化級、為調試工具 GDB 提供額外的支持信息、使用管道而不是臨時文件以便加快編譯速度。
      這兩個參數(shù)具體定義在:/usr/lib/rpm/mBuild/macros 里。

      %install #下面開始將編譯好的軟件安裝到虛擬的根目錄。系統(tǒng)重新進入 /usr/src/mBuild/BUILD/%{name}-%{version} 執(zhí)行 make install,然后返回 /usr/src/mBuild/BUILD 目錄下。
      rm -rf $RPM_BUILD_ROOT #先清理安裝目的地——虛擬根目錄

      %makeinstall #這是 rpm 定義的標準的安裝宏,含義很復雜,但絕對標準。具體含義參見 [注2]。
      非標準寫法: make DESTDIR=$RPM_BUILD_ROOT install 或者 make prefix=$RPM_BUILD_ROOT install (這行原先寫錯了,非常抱歉)

      %clean #清掃戰(zhàn)場,打包完成后刪掉編譯過程產生的中間文件、目錄
      [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf "$RPM_BUILD_ROOT" #如果虛擬根目錄不是真正的 / 目錄,就刪除掉。這里將軟件打包時安裝到的虛擬根目錄刪掉。通常直接用 rm -rf $RPM_BUILD_ROOT 就很安全。
      rm -rf $RPM_BUILD_DIR/%{name}-%{version} #將 /usr/src/mBuild/BUILD/軟件名稱-版本號 目錄刪掉。這里是編譯過程生成的中間文件。注意:這里的 %{name}-%{version} 必須和 %setup -n %{name}-%{version} 指定的相應內容保持一致。

      按照我們在 /usr/lib/rpm/macros 里的定義,通常
      %clean
      rm -rf $RPM_BUILD_ROOT
      rm -rf $RPM_BUILD_DIR/%{name}-%{version}
      也可以寫成
      %clean
      %{__rm} -rf %{buildroot}
      %{__rm} -rf %{_builddir}/%{name}-%{version}

      %pre #rpm 包安裝前執(zhí)行的腳本。

      %post #rpm 包安裝后執(zhí)行的腳本。
      /sbin/ldconfig #這里舉例,ldconfig 用于安裝庫文件后進行“注冊”,這么說不準確,但好理解。這里可以是任何 sh 腳本。

      %preun #rpm 包卸載前執(zhí)行的腳本。

      %postun #rpm 包卸載后執(zhí)行的腳本。
      if [ "$1" = "0" ]; then
      /sbin/ldconfig
      fi
      或者寫作:
      if [ $1 -eq 0 ]; then
      /sbin/ldconfig
      fi

      ★★★
      如果您的包作為系統(tǒng)包的一部分,需要通過發(fā)行版本的安裝程序安裝的話,不要指望能使用內嵌腳本執(zhí)行任何重要操作,包括創(chuàng)建任何文件。因為安裝程序的運行環(huán)境不可能完全等同于安裝后實際運行時的系統(tǒng)環(huán)境,某些操作是不能正確執(zhí)行的。一般,安裝程序在安裝后期會執(zhí)行一些補償操作,來完成諸如庫文件和內核模塊注冊、初始環(huán)境設置等操作,所以你不必擔心庫文件安裝不正確。
      具體舉例來說:最常見的 %post 小節(jié)的腳本在系統(tǒng)初始化安裝階段就很可能得不到正確執(zhí)行。因為安裝程序所處的小 linux 系統(tǒng)環(huán)境不同于安裝后的真實系統(tǒng),而此時的真實系統(tǒng)還不完整,即便立即 chroot 切換入真實系統(tǒng)也未必能正確執(zhí)行,況且安裝一個 rpm 時其內嵌腳本不可能等你切換入真實系統(tǒng)才執(zhí)行。所以除了 ldconfig 之類的命令外,盡可能不要使用內嵌腳本,特別是不要創(chuàng)建任何文件,比如配置文件或者 desktop 文件,所有這些都必須靜態(tài)創(chuàng)建好。您可以在 install 字段完成這些創(chuàng)建工作,也可以事先創(chuàng)建好,并把它們作為 source 的一部分。
      既然內嵌腳本在系統(tǒng)初始化安裝階段都是不可靠的,那么上文提到的 ldconfig 又有什么作用呢?原來,通常安裝程序都會在安裝包結束后,自動創(chuàng)建 /etc/ld.so.conf,并且執(zhí)行一次 ldconfig,從而完成對所有庫文件的注冊。如果這個包是在系統(tǒng)安裝后額外安裝的,那么所有的內嵌腳本都應該被這個真實的系統(tǒng)正確執(zhí)行,此時的 ldconfig 就會被正確執(zhí)行。

      ★★★
      我們可以看到,在 postun 小節(jié)定義的腳本里多出來一個 if 判斷語句,這事干什么用的呢?這里的 $1 是什么意思呢?原來 rpm 相當強大,以其包升級操作為例,它會這樣執(zhí)行:
      新包的 pre 腳本
      安裝文件
      新包的 post 腳本
      舊包的 preun 腳本
      刪除安裝過程沒有覆蓋的全部文件,但不包括重要配置文件
      舊包的 postun 腳本
      如果有“觸發(fā)”腳本,實際操作會更復雜。
      通常在 postun 腳本里我們執(zhí)行的都是一些清掃垃圾的操作,比如刪除程序額外創(chuàng)建的臨時文件、配置文件(我們建議通過交互式方式執(zhí)行此操作,詢問用戶是否刪除程序運行時創(chuàng)建的配置文件,因為有些配置文件用戶未必想要刪除)。卸載軟件包沒問題,但是升級操作就可能造成災難性后果:剛剛安裝好的軟件包被刪掉了一部分文件。為了避免這樣的局面,rpm 提供了一種信號機制,不同操作會返回不同信號,并且把它存放到默認變量 $1 當中:0 代表卸載、1 代表安裝、2 代表升級。這樣我們就可以通過判斷 $1 的值來決定怎樣執(zhí)行腳本。上面的腳本就表示:僅當執(zhí)行卸載操作的時候才執(zhí)行 /sbin/ldconfig 命令。

      ★★★
      在 rpm 內嵌腳本里的重要命令需要使用完整的或稱絕對路徑,例如 /sbin/ldconfig 等,這是為了確保正確的命令被執(zhí)行。由于用戶自己可能重新定義了 PATH 環(huán)境變量,導致其他位置上的 ldconfig 可執(zhí)行程序的搜索路徑先于 /sbin/ldconfig,可能產生難以預料的后果。


      %files #本節(jié)定義哪些文件、目錄將被打進 rpm 包里。如果你認為哪些文件不必打進 rpm 包里(一般是 debug、src 和 devel 文件、目錄),你就不要列在這里,或者使用 %exclude 關鍵字指明哪些文件不打進 rpm 包里。你甚至可以在 spec 文件的其他字段安裝或者刪除一些特定的文件,這就是比較復雜的技術了。但是如何才能知道到底軟件向系統(tǒng)內安裝了哪些目錄和文件呢?這個問題有點復雜。參見[注4]。注意:此處系統(tǒng)的當前路徑指的就是虛擬的根目錄。所以虛擬的根目錄路徑(例如 /var/tmp/cce-0.51-1mgc-root/)不要寫在這里。應該直接用類似 %{_bindir} 的宏(表示 /usr/bin ) 來指定包含的目錄,也可以單獨指定一個或一組文件。
      %defattr(-,root,root) 指定包裝文件的屬性,代表(mode, owner, group) 即文件屬性、文件屬主、用戶群組,- 代表屬性為默認值,對文本文件是八進制數(shù)0644,可執(zhí)行文件是 0755。下面指定具體哪些目錄或文件將被打進包里,很多宏的定義要看你的具體系統(tǒng)[注2]
      #下面具體指定打進 rpm 包的文件、目錄,例如:
      %dir %{_datadir}/tst/
      %dir %{_datadir}/tst/plugin/
      %{_bindir}/tst
      %{_datadir}/tst/plugin/libtest.so
      "/usr/share/tst/plugin/*.png"
      %{_datadir}/tst/plugin/test.plugin
      %config %{_datadir}/tst/tst.conf

      %exclude /usr/src #如果上面列出的目錄里包含一些你不想要的東西,比如源代碼(src),你可以在此將他們“摳”出去。這里指定具體哪些目錄或文件將被排除在包外,即不打進包,一般是 debug、src 和 devel 文件、目錄。

      %files devel #這里分出 devel 包,主要包含與軟件開發(fā)相關的頭文件與庫文件包。
      %defattr(-,root,root)
      %{_includedir}

      代碼:

      這是 %files 小節(jié)的最簡單寫法:
      %files
      %defattr(-,root,root)
      %{_sysconfdir}    #如果您提供了位于 /etc 的設置文件,需要這行
      %{_prefix}    #將安裝目標目錄里的所有東西都打進 rpm 包,除了 %exclude 列出的內容
      %exclude %{_prefix}/*/debug*    #除掉所有的 debug 調試文件*
      %exclude %{_prefix}/src    #除掉所有的源代碼文件*
      *注意:如果沒有這樣的文件、目錄,則打包過程會出錯,只要在 %exclude 前方加上 # 注釋掉這行就行了。


      [spec 文件尾部]

      %changelog #下面是標準變更日志,日期一定不能寫錯,只能是英文格式。

      * Sun Oct 31 2004 Tony Black <tony@>
      - modify the spec file and rebuild

      * Sun Oct 03 2004 Lover <root@Lover>
      - initial spec file created by autospec ver. 0.8 with rpm 3 compatibility




      -----------------------------------------------------------------------
      把源代碼壓縮包、補丁等等放到 /usr/src/mBuild/SOURCES 目錄里,把 spec 文件放到 /usr/src/mBuild/SPECS 目錄里,在 SPECS 目錄里以 root 身份執(zhí)行:

      rpmbuild -ba --target=i686 xxx.spec

      即可在 /usr/src/mBuild/RPMS/i686 里生成 rpm 包,一般還會有 debug info 包,對普通用戶基本沒什么用。在 /usr/src/mBuild/SRPMS 里則生成 src.rpm 包。

      如果只想生成二進制包,使用下面命令:

      rpmbuild -bb --target=i686 xxx.spec

      如果只想生成源代碼包,使用下面命令:

      rpmbuild -bs --target=i686 xxx.spec





      注1:
      rpm 軟件包系統(tǒng)標準分組在這里:
      /usr/share/doc/rpm-4.3.2/GROUPS

      大致內容如下:
      Amusements/Games
      Applications/Archiving
      Applications/Communications
      Applications/Databases
      Applications/Editors
      Applications/Emulators
      Applications/Engineering
      Applications/File
      Applications/Graphics
      Applications/Internet
      Applications/Multimedia
      Applications/Productivity
      Applications/Publishing
      Applications/System
      Applications/Text
      Development/Debuggers
      Development/Languages
      Development/Libraries
      Development/System
      Development/Tools
      Documentation
      System Environment/Base
      System Environment/Daemons
      System Environment/Kernel
      System Environment/Libraries
      System Environment/Shells
      User Interface/Desktops
      User Interface/X
      User Interface/X Hardware Support

      注2:
      各種宏定義在系統(tǒng)這里:
      /usr/lib/rpm/macros

      通常我們要對其適當優(yōu)化一下,修改如下:
      %vendor MGC Group
      %optflags -O2 -g -pipe
      %_arch i686 這里相當于 rpmbuild 的參數(shù) --target=i686 指將來運行軟件包時的環(huán)境
      %_build_arch i686 這里相當于 rpmbuild 的參數(shù) --build=i686 指建包時的環(huán)境(你的機器),這可以比默認的 i386 快一些。

      常見宏定義(左側是宏名,右側是相應的定義):
      %_prefix /usr
      %_exec_prefix %{_prefix} #展開后是 /usr
      %_bindir %{_exec_prefix}/bin #展開后是 /usr/bin
      %_sbindir %{_exec_prefix}/sbin #展開后是 /usr/sbin
      %_libexecdir %{_exec_prefix}/libexec #展開后是 /usr/libexec
      %_datadir %{_prefix}/share #展開后是 /usr/share
      %_sysconfdir %{_prefix}/etc #展開后是 /usr/etc 但是在 magic linux 里 %_sysconfdir 代表的是 /etc,這是由另一個被發(fā)行版特殊定制的文件決定的!
      %_sharedstatedir %{_prefix}/com #展開后是 /usr/com
      %_localstatedir %{_prefix}/var #展開后是 /usr/var
      %_libdir %{_exec_prefix}/lib #展開后是 /usr/lib
      %_includedir %{_prefix}/include #展開后是 /usr/include
      %_infodir %{_prefix}/info #展開后是 /usr/info
      %_mandir %{_prefix}/man #展開后是 /usr/man 在 magic linux 里 %_mandir 代表的是 /usr/share/man

      ***注意***
      僅當你使用標準配置宏 %configure 的時候,文件才會被指定到上述標準位置上。否則,如果你在 %file 字段使用這些標準宏就可能出錯,系統(tǒng)可能報告找不到這些文件,因為它們可能默認安裝到了別處。
      *********

      已安裝的 RPM 包數(shù)據(jù)庫在這里:
      /var/lib/rpm/

      注3:
      軟件包安裝時用參數(shù) --prefix=<dir> 重新指定安裝位置。例如:
      軟件包默認安裝到 /usr 下,你希望安裝到 /opt/usr 下,則使用命令:
      rpm -ivh --prefix=/opt/usr xxx.rpm
      如果你還有一些文件默認安裝到 /etc 下,你需要安裝到 /usr/etc 下,則要改用參數(shù) --relocate=<old>=<new>,例如:
      rpm xxx.rpm --relocate=/usr=/opt/usr --relocate=/etc=/usr/etc

      如何知道 rpm 軟件包到底向系統(tǒng)什么位置安裝了什么文件呢?,你可以使用下面的命令查詢:
      rpm -qpl xxx.rpm

      注4:
      任何沒有被列在 %files 字段的目錄或文件都不會被自動打進 rpm 包里。反之如果你在任何 %files 字段指定了虛擬根目錄里并不存在的東西,系統(tǒng)就會報錯,包括用 %exclude 排除的東西也是這樣。通常我們只需要在 %files 字段指定所有頂層目錄就可以了。若要了解軟件到底向系統(tǒng)內安裝了哪些目錄和文件,你可以采取下列辦法:

      1. 在 %files 字段內只寫進 %{_prefix}:
      %files
      %defattr(-,root,root)
      %{_prefix}
      這樣所有東西都將被打進 rpm 包。打好包之后,用如下命令查詢生成的 rpm 包的目錄結構:
      rpm -qpl xxx.rpm

      2. 打包前手工執(zhí)行配置、安裝,當 ./configure 執(zhí)行后,重定向安裝到一個虛擬根目錄里。例如(注意大小寫):
      ./configure
      make (這步可以省略,不信就試試)
      make DESTDIR=/var/tmp/xxx install 或者 make prefix=/var/tmp/xxx install
      然后進入 /var/tmp/xxx 目錄查看里面的目錄結構:
      cd /var/tmp/xxx
      tree

      3. 打包前手工執(zhí)行配置、安裝,當 ./configure 執(zhí)行后,查看生成的 Makefile 的 install 字段。注意:如果軟件不符合 GNU 規(guī)范,可能并沒有提供 configure 腳本,而是直接提供了 Makefile。這些通常都是游戲軟件。這比較復雜,如果你不懂編程,可能看不懂 Makefile。 :lol:

      注5:
      補丁通常是這樣創(chuàng)建的:
      diff -Nur directory.old directory.new > xxx.patch
      directory.old 代表舊源代碼目錄,directory.new 代表修改過的新源代碼目錄。

      這里有一個由壓縮包直接創(chuàng)建 rpm/srpm 包的工具,但是它無法知道那些文件、目錄應該被打進包里,你需要指定:
      http:///project/show...release_id=7939


      下面是一個實際例子,更多范例可以瀏覽這里:
      http://www./people/kde/magic/specs/
      --------------------------------------------------------------------
      Summary: KDE graphics package
      Name: kdegraphics
      Version: 3.3.0
      Release: 2mgc
      Copyright: GPL
      URL: http://www.
      Group: desktop/kde
      BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
      Source: %{name}-%{version}.tar.bz2
      Prefix: %{_prefix}
      Requires: qt, arts, kdelibs, kdebase, liblcms, fribidi
      Packager: kanker <這里填寫 kanker 的實際郵件地址,為防垃圾郵件,我把它去掉了>

      %description
      Graphic applications for the K Desktop Environment. provide some useful tools like ksnapshot,kpaint and so on.

      %package devel
      Summary: Development files for kdegraphics
      Requires: %{name}
      Group: Development/Libraries
      Provides: kviewshell-devel
      Provides: libkscan-devel

      %description devel
      Graphic applications for the K Desktop Environment. This package contains header files for developing applications using kdegraphics.

      %prep

      %setup -q -n %{name}-%{version}
      %Build
      rm -rf kcoloredit
      rm -rf kpdf
      rm -rf kruler
      rm -rf kgamma
      rm -rf kuickshow
      rm -rf kview
      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/

      %clean
      rm -rf $RPM_BUILD_ROOT
      rm -rf $RPM_BUILD_DIR/%{name}-%{version}

      %files
      %defattr(-,root,root)
      %{_bindir}
      %{_libdir}
      %{_datadir}
      %exclude %{_libdir}/debug

      %files devel
      %defattr(-,root,root)
      %{_includedir}

      %changelog
      * Sun Oct 3 2004 kde <這里填寫實際郵件地址>
      - fix the spec file and rebuild

      * Sat Oct 2 2004 kanker <這里填寫實際郵件地址>
      - initialize the first spec file

        本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多