建立 RPM 套件

  • 步驗:
    1. 收集要包裝的軟體。
    2. 產生 spec 檔案,這個檔案說明如何建立套件。
    3. 以 rpmbuild 命令建立套件。
  • 聚集(gather)軟體
    1. 收集應用程式原始碼、建立的檔案(例如 makefile)、線上的使用手冊文件。
    2. 收集軟體最簡單的方法,就是將這些檔案以 tarball 產生方法,裝成一個 tarball。
    3. tarball 的檔案名稱,必須有應用程式名稱和版本編號,例如 myapp-1.0.tar.gz。
    4. 將 myapp-1.0.0.tar.gz 複製到 RPM 的 SOURCES 目錄。
      $ cp myapp-1.0.tar.gz /usr/src/rpm/SOURCES
      

  • 建立程式 myapp 的 RPM spec 檔案,檔案名稱定為 myapp.spec。
    1. 註解:以 # 為行首的資料。在 spec 檔中加入註解,例如:
      # spec file for package myapp (Version 1.0)
      
    2. 標籤( tags ):資料定義。一般格式如下:
      <something>:<something-else>
      
      1. 導文( preamble ):設定套件名稱、版本編號和其它資訊。例如:
        Vendor:           Wrox Press  #發展的廠商
        Distribution:     Any  #
        Name:             myapp  #套件的名稱
        Version:          1.0  #套件的版本資訊
        Release:          1  #版本打包的次數說明
        Packager:         neil@provider.com  #套件打包者
        License:          Copyright 2003 by Wrox Press  #套件的授權模式
        Group:            Applications/Media  #套件的發展團體名稱
        Provides:         goodness  #系統提供的功能
        Requires:         mysql >= 3.23  #套件之相依套件
        Buildroot:        %{_tmppath}/%{name}-%{version}-root
        Source:           %{name}-%{version}.tar.gz  #套件的來源
        Summary:          Trivial application  #主要的套件說明
        
      2. %description 標籤:提供相關說明,不同於上述格式,其以 % 開頭,且可展開成多行。例如:
        %description
        MyApp Trivial Application
        A trivial application used to demonstrate development tools.
        This version pretends it requires MySQL at or above 3.23.
        Authors: Neil Matthew and Richard Stones
        
      3. 套件名稱與版本巨集( marco ),例如:
        Source:           %{name}-%{version}.tar.gz
        
        # %{name} 與 %{version} 為 RPM 的巨集,分別表示套件名稱及版本;
        # 在本例中 rpmbuild 命令會將 %{name} 展開成為 myapp,而 %{version} 展開為 1.0;
        
      4. Buildroot 設定安裝目錄。
        Buildroot:        %{_tmppath}/%{name}-%{version}-root
        # %{_tmppath} 巨集內容可以 rpm --showrc 查詢。
        
    3. RPM 工作腳本( scripts )
      1. %prep: build 前的準備( prepare ) 動作,主要是執行套件解打包壓縮。由於準備動作幾乎是公式化的動作,故已寫成巨集 %setup。例如:
        %prep
        %setup -q  # 選項 -q 代表設定為安靜模式。
        
      2. %build:建立用應用程式。例如:
        %build
        make
        
      3. %install:安裝應用程式、使用手冊和支援的檔案。例如:
        %install
        mkdir -p $RPM_BUILD_ROOT%{_bindir}
        mkdir -p $RPM_BUILD_ROOT%{_mandir}
        install -m755 myapp $RPM_BUILD_ROOT%{_bindir}/myapp
        install -m755 myapp.1 $RPM_BUILD_ROOT%{_mandir}/myapp.1
        # %RPM_BUILD_ROOT 環境變數紀錄 Buildroot 的位置。
        # %{bindir} 和 %{_mandir} 巨集,分別展開為二進位執行檔案目錄和使用手冊目錄。
        
      4. %clean:清除 rpmbuild 命令產生的檔案。例如:
        %clean
        rm -rf $RPM_BUILD_ROOT
        
    4. %files:列出套件包含的檔案。例如:
      %files
      %{_bindir}/myapp
      %{_mandir}/myapp.1
      
    5. %post:套件安裝後執行的腳本。例如:
      %post
      mail root -s "myapp installed - please register" </dev/null
      
    6. 應用程式 myapp 的完整 spec 檔案如下:
      #
      # spec file for package myapp (Version 1.0)
      #
      Vendor:           Wrox Press
      Distribution:     Any
      Name:             myapp
      Version:          1.0
      Release:          1
      Packager:         neil@provider.com
      License:          Copyright 2003 by Wrox Press
      Group:            Applications/Media
      Provides:         goodness
      Requires:         mysql >= 3.23
      Buildroot:        %{_tmppath}/%{name}-%{version}-root
      source:           %{name}-%{version}.tar.gz
      Summary:          Trivial application
      %description
      MyApp Trivial Application
      A trivial application used to demonstrate development tools.
      This version pretends it requires MySQL at or above 3.23.
      Authors: Neil Matthew and Richard Stones
      %prep
      %setup -q
      %build
      make
      %install
      mkdir -p $RPM_BUILD_ROOT%{_bindir}
      mkdir -p $RPM_BUILD_ROOT%{_mandir}
      install -m755 myapp $RPM_BUILD_ROOT%{_bindir}/myapp
      install -m755 myapp.1 $RPM_BUILD_ROOT%{_mandir}/myapp.1
      %clean
      rm -rf $RPM_BUILD_ROOT
      %post
      mail root -s "myapp installed - please register" </dev/null
      %files
      %{_bindir}/myapp
      %{_mandir}/myapp.1
      

  • 利用 rpmbuild 建立一個 RPM 套件。
    1. 語法:rpmbuild -bBuildStage spec_file
      選項 bBuildStage 意義
      -ba 建立所有,包含二進位和原始碼 RPM。
      -bb 建立一個二進位 RPM。
      -bc 建立(編譯)程式,但是不會建立整個 RPM。
      -bp 準備建立一個二進位 RPM。
      -bi 產生一個二進位 RPM,並且安裝它。
      -bl 檢查 RPM 的檔案列表。
      -bs 只建立一個原始碼 RPM。
    2. 建立套件輸出結果:
      $ rpmbuild -ba myapp.spec
      Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.71108
      + umask 022
      + cd /usr/src/redhat/BUILD
      + LANG=C
      + export LANG
      + cd /usr/src/redhat/BUILD
      + rm -rf myapp-1.0
      + /usr/bin/gzip -dc /usr/src/redhat/SOURCES/myapp-1.0.tar.gz
      + tar -xf -
      + STATUS=0
      + '[' 0 -ne 0 ']'
      + cd myapp-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,g-w,o-w .
      + exit 0
      Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.43788
      + umask 022
      + cd /usr/src/redhat/BUILD
      + cd myapp-1.0
      + LANG=C
      + export LANG
      + make
      gcc -g -Wall -ansi   -c -o main.o main.c
      gcc -g -Wall -ansi   -c -o 2.o 2.c
      ar rv mylib.a 2.o
      a - 2.o
      gcc -g -Wall -ansi   -c -o 3.o 3.c
      ar rv mylib.a 3.o
      a - 3.o
      gcc -o myapp main.o mylib.a
      + exit 0
      Executing(%install): /bin/sh -e /var/tmp/rpm-tmp.90688
      + umask 022
      + cd /usr/src/redhat/BUILD
      + cd myapp-1.0
      + LANG=C
      + export LANG
      + mkdir -p /var/tmp/myapp-1.0-root/usr/bin
      + mkdir -p /var/tmp/myapp-1.0-root/usr/share/man
      + install -m755 myapp /var/tmp/myapp-1.0-root/usr/bin/myapp
      + install -m755 myapp.1 /var/tmp/myapp-1.0-root/usr/share/man/myapp.1
      + /usr/lib/rpm/find-debuginfo.sh /usr/src/redhat/BUILD/myapp-1.0
      extracting debug info from /var/tmp/myapp-1.0-root/usr/bin/myapp
      1 block
      + /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
      Processing files: myapp-1.0-1
      Provides: goodness
      Requires(interp): /bin/sh
      Requires(rpmlib): rpmlib(CompressedFileNames) %*<== 3.0.4-1*)
      rpmlib(PayloadFilesHavePrefix) %*<== 4.0-1*)
      Requires(post): /bin/sh
      Requires: libc.so.6 libc.so.6(GLIBC_2.0) mysql >= 3.23
      Processing files: myapp-debuginfo-1.0-1
      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/myapp-1.0-root
      Wrote: /usr/src/redhat/SRPMS/myapp-1.0-1.src.rpm
      Wrote: /usr/src/redhat/RPMS/i386/myapp-1.0-1.i386.rpm
      Wrote: /usr/src/redhat/RPMS/i386/myapp-debuginfo-1.0-1.i386.rpm
      Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.17422
      + umask 022
      + cd /usr/src/redhat/BUILD
      + cd myapp-1.0
      + rm -rf /var/tmp/myapp-1.0-root
      + exit 0
      
  • 建立程式成功後產生之檔案
    1. 在 RPMS 目錄之子目錄(例如 RPMS/i386) 的二進位 RPM 檔:
      myapp-1.0-1.i386.rpm
      
    2. 在 SRPMS 目錄的原始碼 RPM 檔:
      myapp-1.0-1.src.rpm
      
練習題
  1. 請說明建立 RPM 套件三步驟。
    Sol. 1.收集要包裝的軟體。2.產生 spec 規格檔案。3.以 rpmbuild 命令建立套件。
  2. 建立 RPM 套件要先收集程式相關檔案,但一般而言,軟體開發所產生之檔案不只一個,最簡單的方法為何?
    Sol. 將所有相關檔案打包壓縮成一個 tarball。
  3. 建立 RPM 套件要先收集程式相關檔案,並將其複製到 RPM 檔案系統下那個目錄?
    Sol. SOURCES
  4. RPM 規格檔案,一般附檔名為何?
    Sol. .spec
  5. 如何在 RPM 規格檔案中加入註解?
    Sol. 行首以 # 開頭。
  6. RPM 規格檔案中標籤定義 Vendor: Wrox Press,意義為何?
    Sol. 發展的廠商 Wrox Press
  7. RPM 規格檔案中標籤定義 Distribution: Any,意義為何?
    Sol. 適用任何的 Linux distribution
  8. RPM 規格檔案中標籤定義 Name: myapp,意義為何?
    Sol. 套件的名稱 myapp
  9. RPM 規格檔案中標籤定義 Version: 1.0,意義為何?
    Sol. 套件的版本為 1.0
  10. RPM 規格檔案中標籤定義 Release: 1,意義為何?
    Sol. 版本打包的次數 1
  11. RPM 規格檔案中標籤定義 Packager: dywang@cyut.edu.tw,意義為何?
    Sol. 套件打包者為 dywang@cyut.edu.tw
  12. RPM 規格檔案中標籤定義 License: GPL ,意義為何?
    Sol. 套件的授權模式 GPL
  13. RPM 規格檔案中標籤定義 Group: Applications/Media,意義為何?
    Sol. 套件的發展團體名為 Applications/Media
  14. RPM 規格檔案中標籤定義 Provides: goodness,意義為何?
    Sol. 系統提供的功能有 goodness
  15. RPM 規格檔案中標籤定義 Requires: mysql >= 3.23,意義為何?
    Sol. 套件之相依套件 mysql 且版本需 >= 3.23
  16. RPM 規格檔案中標籤定義 Buildroot: %{_tmppath}/%{name}-%{version}-root,意義為何?
    Sol. 建立 rpm 套件的暫存工作目錄為 %{_tmppath}/%{name}-%{version}-root
  17. RPM 規格檔案中標籤定義 Source: %{name}-%{version}.tar.gz,意義為何?
    Sol. 套件的來源 %{name}-%{version}.tar.gz
  18. RPM 規格檔案中標籤定義 Summary: Trivial application,意義為何?
    Sol. 主要的套件說明 Trivial application
  19. RPM 規格檔案中標籤 %description,與其他資料定義標籤,主要不同為何?
    Sol. % 開頭,且可展開成多行,可提供套件相關說明。
  20. RPM 規格檔案中標籤定義 Source: %{name}-%{version}.tar.gz,其中 %{name}-%{version} 意義為何?
    Sol. %{name}%{version} 為 RPM 的巨集;rpmbuild 命令會將其展開為套件名稱及版本。
  21. RPM 規格檔案中標籤定義 Buildroot: %{_tmppath}/%{name}-%{version}-root,其中 %{_tmppath} 意義為何?
    Sol. %{_tmppath} 為 RPM 的巨集;rpmbuild 命令會將其展開為:建立 rpm 套件的暫存工作目錄。
  22. RPM 規格檔案中工作腳本 %prep,主要工作內容為何?
    Sol. 建立 rpm 套件前的準備動作,主要是執行套件解打包壓縮。
  23. RPM 規格檔案中工作腳本 %prep,通常是執行那個巨集?為什麼?
    Sol. 由於準備動作幾乎是公式化的動作,故已寫成巨集 %setup
  24. RPM 規格檔案中工作腳本 %setup -q,其中選項 -q 代表意義為何?
    Sol. 安靜模式。
  25. RPM 規格檔案中工作腳本 %build,主要工作內容為何?
    Sol. 建立用應用程式,通常是執行 make 。
  26. RPM 規格檔案之工作腳本中 %RPM_BUILD_ROOT,代表意義為何?
    Sol. %RPM_BUILD_ROOT 為環境變數,紀錄 Buildroot 的位置。
  27. RPM 規格檔案之工作腳本中 %{_bindir},代表意義為何?
    Sol. %{_bindir} 為 RPM 的巨集;rpmbuild 命令會將其展開為二進位執行檔案目錄。
  28. RPM 規格檔案之工作腳本中 %{_mandir},代表意義為何?
    Sol. %{_mandir} 為 RPM 的巨集;rpmbuild 命令會將其展開為使用手冊目錄。
  29. RPM 規格檔案中工作腳本 %clean,主要工作內容為何?
    Sol. 清除 rpmbuild 命令產生的檔案。
  30. RPM 規格檔案中工作腳本 %file,主要工作內容為何?
    Sol. 列出套件包含的檔案。
  31. RPM 規格檔案中工作腳本 %post,主要工作內容為何?
    Sol. 套件安裝後需執行的動作。
  32. 建立 RPM 套件指令為何?
    Sol. rpmbuild
  33. 若 RPM 規格檔為 myapp.spec,如何同時建立 RPM 與 SRPM 套件?
    Sol. rpmbuild -ba myapp.spec
  34. 若 RPM 規格檔為 myapp.spec,如何只建立 RPM 套件?
    Sol. rpmbuild -bb myapp.spec
  35. 若 RPM 規格檔為 myapp.spec,如何建立 RPM 並安裝它?
    Sol. rpmbuild -bi myapp.spec
  36. 若 RPM 規格檔為 myapp.spec,如何只建立 SRPM 套件?
    Sol. rpmbuild -bs myapp.spec

  DYWANG_HOME