亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12345下一頁
最近訪問板塊 發(fā)新帖
查看: 121165 | 回復(fù): 41
打印 上一主題 下一主題

Linux平臺軟件管理系統(tǒng)設(shè)計與規(guī)劃-進階篇(2)-rpm生成:rpmbuild 和 spec文件剖析 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2012-12-16 18:19 |只看該作者 |倒序瀏覽
本帖最后由 duanjigang 于 2012-12-22 22:47 編輯

轉(zhuǎn)載請保留作者信息和來自CU的原站
在第一篇文章中,我們介紹了 rpm 文件的基本概念,協(xié)議格式等基礎(chǔ)知識。最近幾周一直在斷斷續(xù)續(xù)的謀劃第二篇的內(nèi)容,終于定下來:以 RPM 文件的制作為使用情景,
主要介紹 rpm 生成工具 rpmbuild 和 rpm 定義文件 spec 文件。

其中 rpmbuild 部分針對rpmbuild 的使用方法,如何使用該命令來制作rpm文件,step by step.
另外,大多數(shù)內(nèi)容以 spec 文件的語法為主,只有徹底掌握spec 中的各種玄機,才能對 rpm 的生成掌握牢固。
廢話不多,讓我們開始!

論壇徽章:
0
2 [報告]
發(fā)表于 2012-12-16 18:22 |只看該作者
本帖最后由 duanjigang 于 2012-12-16 18:31 編輯

在演講PPT<<2012系統(tǒng)架構(gòu)師大會-Linux平臺軟件管理系統(tǒng)設(shè)計與規(guī)劃.pptx>>有這樣一幅圖,是說明 rpm 是如何產(chǎn)生的。:wink:


從圖中我們可以看到,rpm 的制作過程跟美食的制作工藝很相仿,我們的源代碼其實就是要熬粥的大米,豆子等原料。另外,食譜會告訴你,大米放多少,水放多少,豆子放多少,rpm制作中的 spec 文件也是類似功能,記錄了如何制作rpm,用什么制作rpm等,然后,原料和食譜準備好了,還需要工具,熬粥的砂鍋~~~,要烹制 rpm 這道菜,也需要工具,那就是rpmbuild工具(當然其它生成rpm文件的命令也可以)。

砂鍋按照食譜上的規(guī)范把大米和豆子加工成美味的粥。
rpmbuild按照spec文件中的規(guī)范把源碼加工成功能強大的rpm包。

論壇徽章:
0
3 [報告]
發(fā)表于 2012-12-16 18:37 |只看該作者
本帖最后由 duanjigang 于 2012-12-17 09:37 編輯

從 wget 的 rpm 制作開始

借鑒了 IBM 開發(fā)社區(qū)的文章,我們的話題也從一個例子 rpm 的制作展開。這個例子軟件是wget,版本時1.14。
對于大多數(shù)從事開發(fā)的同學(xué)來說,安裝 wget 的方法很可能是直接下載源碼,解壓縮,configure,make,make install 就OK了。
我們在這里會介紹如果用源碼包制作標準的二進制 rpm 和 源碼 rpm.

首先,看看系統(tǒng)提供的rpm制作環(huán)境是什么樣的,大多數(shù)從事系統(tǒng)管理的同學(xué)都知道,linux 系統(tǒng)自帶的rpm 生成環(huán)境在 /usr/src/redhat 目錄下,
包含的目錄以及作用是:

  1. BUILD:  rpmbuild 命令在這個目錄進行代碼編譯
  2. RPMS: rpmbuild 命令會把最終生成的 rpm 文件存儲在這個目錄。
  3. SOURCES: 制作 rpm 的源碼都應(yīng)該放在這個目錄中。
  4. SPECS:制作rpm時用到的spec 文件應(yīng)該放在這個目錄。
  5. SRPMS: rpmbuild 生成的 源碼rpm包會存儲在這個目錄下。
復(fù)制代碼
幾個月前用openssl的srpm做的rpm就是這樣流程,先 rpm 安裝 openssl 的源碼包,openssl 和眾多patch文件都被安裝到

  1. /usr/src/redhat/SOURCES/
復(fù)制代碼
目錄下了,對應(yīng)的spec文件也被安裝到

  1. /usr/src/redhat/SPECS
復(fù)制代碼
目錄下了。
我們要做的就是一條命令

  1. rpmbuild -ba /usr/src/redhat/SPECS/openssl.spec
復(fù)制代碼
即可完成 rpm 的制作,生成的 rpm 存儲路徑是:

  1. /usr/src/redhat/RPMS/i386/openssl-0.9.8b-8.3.i386.rpm
復(fù)制代碼
本文要說的,是在自定義目錄下通過非root用戶來制作rpm,而不是使用root帳號,在系統(tǒng)默認工作目錄下制作rpm,為什么建議不要用root用戶來編譯生成rpm,在后面的內(nèi)容中會涉及到,在此先不說了。

論壇徽章:
0
4 [報告]
發(fā)表于 2012-12-16 19:04 |只看該作者
本帖最后由 duanjigang 于 2012-12-17 10:26 編輯

wget 源碼包制作rpm

首先下載wget 的源碼包wget-1.14.tar.gz,然后在個人目錄下建立 RPM 的工作目錄:

  1. /home/jigang.djg/lessons/rpmbuild_dir
復(fù)制代碼
然后建立對應(yīng)的幾個目錄:

  1. $mkdir BUILD  RPMS  SOURCES  SPECS  SRPMS
  2. $ls /home/jigang.djg/lessons/rpmbuild_dir
  3. BUILD  RPMS  SOURCES  SPECS  SRPMS
復(fù)制代碼
把源碼挪到 SOURCES目錄下.
然后編寫 wget.spec 文件。

參考
http://www.ibm.com/developerworks/library/l-rpm1/
這里的例子,編寫的 spec 文件內(nèi)容如下:

SPECS/wget.spec

  1. # This is a sample spec file for wget
  2. %define _topdir   /home/jigang.djg/lessons/rpmbuild_dir
  3. %define name  wget
  4. %define release  1
  5. %define version  1.14
  6. %define buildroot %{_topdir}/%{name}-%{version}-root

  7. BuildRoot:  %{buildroot}
  8. Summary:   GNU wget
  9. License:   GPL
  10. Name:    %{name}
  11. Version:   %{version}
  12. Release:   %{release}
  13. Source:   %{name}-%{version}.tar.gz
  14. Prefix:   /usr
  15. Group:    Development/Tools

  16. %description
  17. The GNU wget program downloads files from the Internet using the command-line.

  18. %prep
  19. %setup -q

  20. %build
  21. ./configure
  22. make

  23. %install
  24. make install prefix=$RPM_BUILD_ROOT/usr

  25. %files
  26. %defattr(-,root,root)
  27. #這也是wget默認的安裝目錄
  28. /usr/bin/wget
  29. #文檔的安裝路徑也要根據(jù)wget的默認路徑寫,否則可能出錯,如果你不自己寫 --prefix=xx的話
  30. #如果有報錯的話,就根據(jù)wget-1.14-root里面的列表進行spec文件校準

  31. %doc %attr(0444,root,root) /usr/share/man/man1/wget.1.gz
復(fù)制代碼
然后進行rpm的編譯:

  1. rpmbuild -v -bb SPECS/wget.spec
復(fù)制代碼
并沒有完美的生成rpm,而是報了一堆錯誤。

部分信息如下:

  1. error: Installed (but unpackaged) file(s) found:
  2.    /usr/etc/wgetrc
  3.    /usr/share/info/wget.info.gz
  4.    /usr/share/locale/be/LC_MESSAGES/wget.mo
  5.    /usr/share/locale/bg/LC_MESSAGES/wget.mo
復(fù)制代碼
根據(jù)提示,分析下出錯的原因。

因為在用 wget 的源碼編譯安裝時 make install 會把很多文件(wget-1.14-root下面的所有文件)都安裝到目標目錄,而我們在 $install 段寫的腳本也正好是是 make install(或者你可以逐行的寫 install 安裝單個文件)。但是在%file 段卻沒有把所有 make install 到 wget-1.14-root 下的文件都寫出來,因此 rpmbuild 在封裝包時會報錯,他提示我們: “找到了install 卻沒有 packaged 的文件”,這個提示是正確的。

解決這個問題有以下三個方法:

其一:  也是最簡單的做法,就是把 “installed but unpackaged” 的文件補充到spec 文件的 files 列表當中去。
其二: 從常理思考,雖然build出了一大堆文件,但是只把一部分封裝到rpm文件中,這個做法應(yīng)該是可以接受的,因為某些時候,我們就只需要一部分重要的文件,別的man文件或許暫時不需要。然后該怎么做呢?人性化的配置是好的軟件不和缺少的,rpm 當然自帶了這個參數(shù)的配置項。

在文件:
/usr/lib/rpm/macros
中有一個配置項:

  1. # Should unpackaged files in a build root terminate a build?
  2. #
  3. # Note: The default value should be 0 for legacy compatibility.
  4. %_unpackaged_files_terminate_build 1
復(fù)制代碼
從字面意思應(yīng)該能看懂,“是否應(yīng)該在build root 目錄發(fā)現(xiàn)未封裝進包的文件時終止編譯?”
系統(tǒng)默認這個值為 1,因此我們的編譯會被終止。

然后將它改為0,再次 build,發(fā)現(xiàn)還是報錯?
原因又何在呢?

查看幫助手冊

  1. man rpmbuild
復(fù)制代碼
能夠看到 rpmbuild 使用的宏定義文件的路徑:

  1. /usr/lib/rpm/macros
  2.        /usr/lib/rpm/redhat/macros
  3.        /etc/rpm/macros
  4.        ~/.rpmmacros
復(fù)制代碼
而且生效順序是從上往下的,這時可以理解,我們在  /usr/lib/rpm/macros 文件中把
%_unpackaged_files_terminate_build 1
改為 %_unpackaged_files_terminate_build 0
后,在 /usr/lib/rpm/redhat/macros 文件中它還是 1,因為這個值被覆蓋了。
為了能夠生效,可以把這個配置寫到

  1. ~/.rpmmacros
復(fù)制代碼
或者

  1. /etc/rpm/macros
復(fù)制代碼
文件中,在此,我們寫進 /etc/rpm/macros 文件中。

  1. echo "%_unpackaged_files_terminate_build 0" >> /etc/rpm/macros
復(fù)制代碼
再次編譯,果然通過,輸出了 rpm 文件

  1. Wrote: /home/jigang.djg/lessons/rpmbuild_dir/RPMS/i386/wget-1.14-1.i386.rpm
  2. Wrote: /home/jigang.djg/lessons/rpmbuild_dir/RPMS/i386/wget-debuginfo-1.14-1.i386.rpm
復(fù)制代碼
然后我們看下rpm的信息:

  1. rpm -qpl RPMS/i386/wget-1.14-1.i386.rpm
  2. /usr/bin/wget
  3. /usr/share/man/man1/wget.1.gz
復(fù)制代碼
能夠看到,不納入到 %files 中的文件確實是 installed but unpackaged 了,呵呵.

其三:就是把不想封裝進包的文件從build輸出的目錄刪掉。
http://blog.163.com/hui_san/blog/static/5710286720125272350508/

這里有個例子,如是說:

  1. make install后刪除這些文件:

  2. rm -rf %{buildroot}
  3. make INSTALL_ROOT=%{buildroot} install

  4. rm -rf %{buildroot}/.channels/.alias/pear.txt %{buildroot}/.channels/.alias/pecl.txt %{buildroot}/.channels/__uri.reg %{buildroot}/.channels/pear.php.net.reg %{buildroot}/.channels/pecl.php.net.reg %{buildroot}/.depdb %{buildroot}/.depdblock %{buildroot}/.filemap %{buildroot}/.lock
復(fù)制代碼
可以借鑒上面的做法。

不過個人還是不建議這樣做,最合適的做法就是把缺少的文件補充進去。
把 installed but unpackaged 的文件添加進spec 后,spec 文件如下:

  1. # This is a sample spec file for wget

  2. %define _topdir   /home/jigang.djg/lessons/rpmbuild_dir
  3. %define name  wget
  4. %define release  1
  5. %define version  1.14
  6. %define buildroot %{_topdir}/%{name}-%{version}-root

  7. BuildRoot:  %{buildroot}
  8. Summary:   GNU wget
  9. License:   GPL
  10. Name:    %{name}
  11. Version:   %{version}
  12. Release:   %{release}
  13. Source:   %{name}-%{version}.tar.gz
  14. Prefix:   /usr
  15. Group:    Development/Tools

  16. %description
  17. The GNU wget program downloads files from the Internet using the command-line.

  18. %prep
  19. %setup -q

  20. %build
  21. ./configure  --with-ssl=openssl
  22. make

  23. %install
  24. make install prefix=$RPM_BUILD_ROOT/usr

  25. %files
  26. %defattr(-,root,root)
  27. /usr/bin/wget
  28. /usr/etc/wgetrc
  29. /usr/share/info/wget.info.gz
  30. /usr/share/locale/be/LC_MESSAGES/wget.mo
  31. /usr/share/locale/bg/LC_MESSAGES/wget.mo
  32. /usr/share/locale/ca/LC_MESSAGES/wget.mo
  33. /usr/share/locale/cs/LC_MESSAGES/wget.mo
  34. /usr/share/locale/da/LC_MESSAGES/wget.mo
  35. /usr/share/locale/de/LC_MESSAGES/wget.mo
  36. /usr/share/locale/el/LC_MESSAGES/wget.mo
  37. /usr/share/locale/en_GB/LC_MESSAGES/wget.mo
  38. /usr/share/locale/eo/LC_MESSAGES/wget.mo
  39. /usr/share/locale/es/LC_MESSAGES/wget.mo
  40. /usr/share/locale/et/LC_MESSAGES/wget.mo
  41. /usr/share/locale/eu/LC_MESSAGES/wget.mo
  42. /usr/share/locale/fi/LC_MESSAGES/wget.mo
  43. /usr/share/locale/fr/LC_MESSAGES/wget.mo
  44. /usr/share/locale/ga/LC_MESSAGES/wget.mo
  45. /usr/share/locale/gl/LC_MESSAGES/wget.mo
  46. /usr/share/locale/he/LC_MESSAGES/wget.mo
  47. /usr/share/locale/hr/LC_MESSAGES/wget.mo
  48. /usr/share/locale/hu/LC_MESSAGES/wget.mo
  49. /usr/share/locale/id/LC_MESSAGES/wget.mo
  50. /usr/share/locale/it/LC_MESSAGES/wget.mo
  51. /usr/share/locale/ja/LC_MESSAGES/wget.mo
  52. /usr/share/locale/lt/LC_MESSAGES/wget.mo
  53. /usr/share/locale/nb/LC_MESSAGES/wget.mo
  54. /usr/share/locale/nl/LC_MESSAGES/wget.mo
  55. /usr/share/locale/pl/LC_MESSAGES/wget.mo
  56. /usr/share/locale/pt/LC_MESSAGES/wget.mo
  57. /usr/share/locale/pt_BR/LC_MESSAGES/wget.mo
  58. /usr/share/locale/ro/LC_MESSAGES/wget.mo
  59. /usr/share/locale/ru/LC_MESSAGES/wget.mo
  60. /usr/share/locale/sk/LC_MESSAGES/wget.mo
  61. /usr/share/locale/sl/LC_MESSAGES/wget.mo
  62. /usr/share/locale/sr/LC_MESSAGES/wget.mo
  63. /usr/share/locale/sv/LC_MESSAGES/wget.mo
  64. /usr/share/locale/tr/LC_MESSAGES/wget.mo
  65. /usr/share/locale/uk/LC_MESSAGES/wget.mo
  66. /usr/share/locale/vi/LC_MESSAGES/wget.mo
  67. /usr/share/locale/zh_CN/LC_MESSAGES/wget.mo
  68. /usr/share/locale/zh_TW/LC_MESSAGES/wget.mo

  69. %doc %attr(0444,root,root) /usr/share/man/man1/wget.1.gz

復(fù)制代碼
然后我們還是把%_unpackaged_files_terminate_build 改為1

重新rpmbuild,這次終于成功了。

  1. rpm -qpl RPMS/i386/wget-1.14-1.i386.rpm
復(fù)制代碼
也能看到新添加進去的filelist.

至此,簡單的RPM總算制作成功了,看下包的信息:

  1. rpm -qpi RPMS/i386/wget-1.14-1.i386.rpm
  2. Name        : wget                         Relocations: /usr
  3. Version     : 1.14                              Vendor: (none)
  4. Release     : 1                             Build Date: 2012年12月15日 星期六 14時32分31秒
  5. Install Date: (not installed)               Build Host: localhost.localdomain
  6. Group       : Development/Tools             Source RPM: wget-1.14-1.src.rpm
  7. Size        : 2032997                          License: GPL
  8. Signature   : (none)
  9. Summary     : 一個使用 HTTP 或 FTP 協(xié)議來檢索文件的工具。
  10. Description :
  11. GNU Wget 是一個文件檢索工具,它既可以使用在
  12. HTTP 協(xié)議上,也可以使用在 FTP 協(xié)議上。Wget
  13. 的功能包括:當您注消后在背景內(nèi)運行的能力,
  14. 遞歸地目錄檢索,文件名通配符匹配,遠程文件
  15. 時間戳貯存和比較,與 FTP 服務(wù)器一起使用 Rest
  16. 和與 HTTP 服務(wù)器一起使用 Range 來在緩慢和不
  17. 可靠的連接上檢索文件,對代理服務(wù)器的支持,以及可配置性
復(fù)制代碼

論壇徽章:
49
15-16賽季CBA聯(lián)賽之福建
日期:2016-06-22 16:22:002015年亞洲杯之中國
日期:2015-01-23 16:25:12丑牛
日期:2015-01-20 09:39:23未羊
日期:2015-01-14 23:55:57巳蛇
日期:2015-01-06 18:21:36雙魚座
日期:2015-01-02 22:04:33午馬
日期:2014-11-25 09:58:35辰龍
日期:2014-11-18 10:40:07寅虎
日期:2014-11-13 22:47:15申猴
日期:2014-10-22 15:29:50摩羯座
日期:2014-08-27 10:49:43辰龍
日期:2014-08-21 10:47:58
5 [報告]
發(fā)表于 2012-12-17 09:23 |只看該作者
非常不錯,感謝原創(chuàng)!

論壇徽章:
0
6 [報告]
發(fā)表于 2012-12-17 09:24 |只看該作者
本帖最后由 duanjigang 于 2012-12-17 09:57 編輯

問題討論:

lofeng410   2012-12-16 22:55
    關(guān)于你在“Linux平臺軟件管理系統(tǒng)設(shè)計與規(guī)劃-進階篇(2)-rpm生成:rpmbuild 和 spec文件剖析”的帖子
    請教個spec文件中語句的問題哈:
    我使用的kernel.spec中有這么一句:
    %if  0%{?__debug_package:1},這個語句是什么意思呢?其中的0,?,:1分別起什么作用呢?
    google也沒有找到相關(guān)說明,還請兄弟指點下哈


@lofeng410
能否把那段對應(yīng)的spec 文件貼出來?

論壇徽章:
8
CU大;照
日期:2013-09-18 15:20:48CU大;照
日期:2013-09-18 15:20:58CU大;照
日期:2013-09-18 15:21:06CU大;照
日期:2013-09-18 15:21:12CU大;照
日期:2013-09-18 15:21:17天秤座
日期:2013-10-30 14:01:03摩羯座
日期:2013-11-29 18:02:31luobin
日期:2016-06-17 17:46:36
7 [報告]
發(fā)表于 2012-12-17 09:49 |只看該作者
@duanjigang
強力支持段總。

論壇徽章:
0
8 [報告]
發(fā)表于 2012-12-17 11:56 |只看該作者
本帖最后由 duanjigang 于 2012-12-17 12:19 編輯

關(guān)于 rpmbuild 的用法可以參考 man 手冊,在這里,我們著重對spec文件的語法細節(jié)進行說明。
SPEC 文件語法解析

一個spec 文件其實就是一個普通人類可讀的文本文件,只不過這個文件由眾多個 entry (entries)組成,每個不同的 entry 有不同的用法。構(gòu)成spec 文件的entry 大致可以分為一下幾類:

  1.     Comments — 人類可讀的字符串,會被RPM忽略,就是為了注釋,備注而生,方便人們理解spec文件。
  2.     Tags — 在spec 中定義數(shù)據(jù)

  3.     Scripts — 腳本,在rpm生成,安裝,升級,卸載等過程的一些時間點執(zhí)行。

  4.     Macros — 宏定義,主要是控制rpm的執(zhí)行流程,為了執(zhí)行不同的命令。

  5.     %files  — 定義 RPM 中將要包含的文件列表。

  6.     Directives — (指令),在%files 中,使得rpm能夠針對不同的file進行不同的處理。

  7.     Conditionals — 條件,根據(jù)不同的操作系統(tǒng),處理器架構(gòu),進行不同的配置,處理。
復(fù)制代碼
comments

comments 也就是常說的注釋,在 spec 文件中導(dǎo)出都可以寫,就為了方便閱讀理解。rpm 生成時會過濾注釋。
比如我們在 openssl.spec 中看到的注釋:

  1. # Install a makefile for generating keys and self-signed certs, and a script
  2. # for generating them on the fly.
  3. mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/certs
  4. install -m644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/certs/Makefile
  5. install -m755 %{SOURCE6} $RPM_BUILD_ROOT%{_sysconfdir}/pki/tls/certs/make-dummy-cert
復(fù)制代碼

論壇徽章:
0
9 [報告]
發(fā)表于 2012-12-17 12:19 |只看該作者
本帖最后由 duanjigang 于 2012-12-17 12:33 編輯

Tags

Tags 數(shù)據(jù)或者標簽定義。

Tage 一般都被定義在spec 文件的頂端,通過


  1. Tag 名稱: Tag取值
復(fù)制代碼
的方式來定義。Tag 不是大小寫敏感的,要注意這點。
我們在Spec中常見的Tag 有:

vendor: 產(chǎn)生軟件的機構(gòu)名稱

比如:

  1. VeNdOr : White Socks Software, Inc.
  2. vendor:White Socks Software, Inc.
  3. VENDOR    :    White Socks Software, Inc.
復(fù)制代碼
上面三行對spec 文件來說是一樣的。

包命名Tag: Name,Version和Release

比如:

  1. Name: openssl
  2. Version: 0.9.8e
  3. Release: 22%{?dist}.4
復(fù)制代碼
描述Tags:

%description: 對包進行詳細的描述。比如:

  1. %description
  2. The OpenSSL toolkit provides support for secure communications between
  3. machines. OpenSSL includes a certificate management tool and shared
  4. libraries which provide various cryptographic algorithms and
  5. protocols.
復(fù)制代碼
還有:
summary
copyright
distribution
icon
vendor
url
group
packager
這些tags,都是對包的描述信息,基本上可以通過 rpm 的 -i 參數(shù)看到這些信息,比如:

  1. rpm -qpi /usr/src/redhat/RPMS/x86_64/openssl-1.0.0i-1.x86_64.rpm
  2. Name        : openssl                      Relocations: (not relocatable)
  3. Version     : 1.0.0i                            Vendor: (none)
  4. Release     : 1                             Build Date: Sat 21 Apr 2012 01:32:28 PM CST
  5. Install Date: (not installed)               Build Host:test.localhost.mysite.com
  6. Group       : System Environment/Libraries   Source RPM: openssl-1.0.0i-1.src.rpm
  7. Size        : 3294837                          License: GPL
  8. Signature   : (none)
  9. Packager    : Damien Miller <djm@mindrot.org>
  10. URL         : http://www.openssl.org/
  11. Summary     : The OpenSSL toolkit
  12. Description :
  13. The OpenSSL toolkit provides support for secure communications between
  14. machines. OpenSSL includes a certificate management tool and shared
  15. libraries which provide various cryptographic algorithms and
  16. protocols.
復(fù)制代碼

論壇徽章:
0
10 [報告]
發(fā)表于 2012-12-17 14:19 |只看該作者
本帖最后由 duanjigang 于 2012-12-17 20:20 編輯

Dependency (依賴性)TAGS:


我們都知道,一個軟件不可能把所有功能都實現(xiàn)了,調(diào)用或者借助別的軟件來實現(xiàn)自身功能是很常見的一種做法,比如,開發(fā)網(wǎng)絡(luò)相關(guān)程序的同學(xué)會經(jīng)常需要安裝libpcap,做規(guī)則處理或者高速匹配應(yīng)用的程序可能需要pcre庫,做 mysql 數(shù)據(jù)庫開發(fā)的需要libmysql或者 libmysql++,通訊程序的用libevent,ICE等等。

  總之,在不同的應(yīng)用范疇內(nèi),我們幾乎都需要借助別的軟件來實現(xiàn)自己軟件要達到的功能。

對于 rpm 也存在這樣的情況:安裝B軟件,它需要A軟件的功能支持,因此,在安裝B之前,需要把A安裝成功;卸載C軟件時,D軟件還用到C軟件的功能,因此不能直接卸載C,或者需要卸載掉D之后,再卸載C,或者為了D的正常運轉(zhuǎn),C就不能卸載掉。這是最常見的依賴。

因此,RPM 的 SPEC 語法中提供了 Dependency(依賴性)  這個TAG,當然,SPEC 中的依賴性 TAG 設(shè)計的比較靈活,可以說是一個比較普適的Dependency 語法。這些會在介紹中看到。

為了詳細說明 Dependency ,我們設(shè)計了兩個例子包,一個叫 test-baby-1.1,另外一個叫 test-daday-1.1

首先看 provides:
provides: 主要是說明本包提供了什么,這里的provides 的取值可以是任何字符串,代表了一個虛擬的包,這個tag的最常用場景就是多個包提供了相同的功能,為了標識他們提供的相同功能可用,著多個包之間就可以provides 出來一個同名的虛擬 package,一旦任何一個包被安裝了,只要虛擬的package可用,則依賴于這個功能的軟件包就能夠安裝了。

看下三個包的spec 文件中的 Requires 和 Provides tag是怎么寫的:

daddy.spec

  1. #daddy.spec
  2. Requires:                 baby-is-provided
復(fù)制代碼
baby.spec

  1. Provides:                 baby-is-provided
復(fù)制代碼
girl.spec

  1. Provides:                 baby-is-provided
復(fù)制代碼
然后編譯生成三個rpm包。

  1. RPMS/x86_64/test-baby-1.1-1.x86_64.rpm
  2. RPMS/x86_64/test-daddy-1.1-1.x86_64.rpm
  3. RPMS/x86_64/test-girl-1.1-1.x86_64.rpm
復(fù)制代碼
看下 test-daddy 的Require 和 test-girl 和 test-baby 的 Provides

  1. rpm -qp RPMS/x86_64/test-daddy-1.1-1.x86_64.rpm --requires
  2. /bin/sh  
  3. baby-is-provided  
  4. libc.so.6()(64bit)  
  5. libc.so.6(GLIBC_2.2.5)(64bit)  
  6. rpmlib(CompressedFileNames) <= 3.0.4-1
  7. rpmlib(PayloadFilesHavePrefix) <= 4.0-1
  8. rtld(GNU_HASH)  

  9. rpm -qp RPMS/x86_64/test-baby-1.1-1.x86_64.rpm --provides
  10. baby-is-provided  
  11. test-baby = 1.1-1

  12. rpm -qp RPMS/x86_64/test-girl-1.1-1.x86_64.rpm --provides
  13. baby-is-provided  
  14. test-girl = 1.1-1
復(fù)制代碼
能夠看到,test-girl 和 test-baby 都提供了 test-daddy 需要的 requires.
直接安裝 test-daddy 看下:

  1. rpm -ivh RPMS/x86_64/test-daddy-1.1-1.x86_64.rpm
  2. error: Failed dependencies:
  3.         baby-is-provided is needed by test-daddy-1.1-1.x86_64
復(fù)制代碼
提示: "baby-is-provided" 未被提供。

我們嘗試安裝 test-girl 或者 test-baby,然后再安裝test-daddy

  1. sudo rpm -i RPMS/x86_64/test-baby-1.1-1.x86_64.rpm
  2. $ sudo rpm -i RPMS/x86_64/test-daddy-1.1-1.x86_64.rpm
  3. rpm -qa test-daddy
  4. test-daddy-1.1-1
復(fù)制代碼
這次確實能成功安裝了。

  1. sudo rpm -e test-baby
  2. error: Failed dependencies:
  3.         baby-is-provided is needed by (installed) test-daddy-1.1-1.x86_64
復(fù)制代碼
也能夠看到 test-baby 通過的 “baby-is-provided” 被 test-daddy 使用著,不能卸載。
然后:

  1. sudo rpm -i RPMS/x86_64/test-girl-1.1-1.x86_64.rpm
  2. $ sudo rpm -e test-baby
復(fù)制代碼
這次,test-baby 能夠卸載了,因為新安裝的 test-girl 也提供了虛擬包 "baby-is-provided" 供 test-daddy 依賴。
到此,相信已經(jīng)對 Provides 理解透徹了吧。


其次是 requires  tag:
provides 提供了虛擬包或者實體的包,requires 表明自己需要哪些包為前提,只有requires 的包安裝了,才能安裝當前包
使用 requires 注意版本的書寫,如果你的應(yīng)用明確需要某個版本的第三方包的話,可以寫上版本,如果沒有特殊版本需要,建議還是不要寫,因為很可能當你的程序從rhel4升級到rhle5或者rhel6時,require 的包版本也升級了,如果寫 :

  1. requires pkgname = 1.23
復(fù)制代碼
這樣的,很可能在5u 或者 6u的 機器上就需要重現(xiàn)改寫spec文件生成rpm了。
requires 支持包的版本運算符有5個。

  1. requires: pkgname  = 1.2-2
  2. requires: pkgname  > 1.2
  3. requires: pkgname  >= 1.2
  4. requires: pkgname  < 1.2
  5. requires: pkgname  <= 1.2-5
復(fù)制代碼
沒有不等于運算符。


另外還有 conflicts

conflicts  與requires 相反, Requires 說明 “我必須與這個包一起安裝在這臺機器上”,而 conflicts  則表明:“我不能與這個(版本的)包共處一臺機器上”。
我們稍微修改下 test-baby 的spec 文件:

  1. rpm -qp RPMS/x86_64/test-girl-1.1-1.x86_64.rpm --provides
  2. baby-is-provided  
  3. test-girl = 1.1-1
  4. $ rpm -qa test-girl
  5. test-girl-1.1-1
  6. $ rpm -ivh RPMS/x86_64/test-baby-1.1-1.x86_64.rpm
  7. error: Failed dependencies:
  8.         baby-is-provided conflicts with test-baby-1.1-1.x86_64
復(fù)制代碼
能夠看到, test-girl provides 了 “baby-is-provided”,而 test-baby conflicts with "baby-is-provided"
因此,當 test-girl 安裝后, test-baby 的安裝就會失敗。


還有一個比較惡心的tag是 serial ,這個tag 專門是為了當版本比較不能夠標明包的新舊時,用serial 的值來標識。
serial  大的rpm 就是新包,從根本上不建議使用這個tag。當你用到這個tag區(qū)分版本時,說明你的rpm 已經(jīng)管理的比較亂了。呵呵。

最后一個是不太用卻比較重要的 Tag:autoreqprov

autoreqprov  是用來自動產(chǎn)生 rpm 依賴的,它的取值為 yes 或者no, 1 或者 0,
當autoreqprov tag 打開時,在 rpm 包編譯的時候,會執(zhí)行以下操作:

  1. (1):所有打包進rpm 的二進制程序需要的共享庫都會被分析出來,然后打包進rpm 的  requirements 中。
  2. (2):所有該rpm 提供的 so 文件的名字都會被自動添加到該RPM的 provides 中。
復(fù)制代碼
以 test-baby 為例,沒有配置 autoreqprov 時 autoreq 默認 為 1,看下它的Requires

  1. $ rpm -qp RPMS/x86_64/test-baby-1.1-1.x86_64.rpm --requires
  2. /bin/sh  
  3. libc.so.6()(64bit)  
  4. libc.so.6(GLIBC_2.2.5)(64bit)  
  5. rpmlib(CompressedFileNames) <= 3.0.4-1
  6. rpmlib(PayloadFilesHavePrefix) <= 4.0-1
  7. rtld(GNU_HASH)  
復(fù)制代碼
加上: autoreq: 0
后,再看:

  1. rpm -qp RPMS/x86_64/test-baby-1.1-1.x86_64.rpm --requires
  2. /bin/sh  
  3. rpmlib(PayloadFilesHavePrefix) <= 4.0-1
  4. rpmlib(CompressedFileNames) <= 3.0.4-1
復(fù)制代碼
很明顯可以看到,對于 libc 的共享庫的自動添加 requires 被取消了。provides 的自動添加,大家可以自己測試。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP