不管是初步跨入Linux殿堂的新手,還是具有多年經(jīng)驗(yàn)的專家,在安裝或編譯軟件包的過(guò)程中或多或少的都會(huì)遇到包的依賴問(wèn)題,從而導(dǎo)致安裝過(guò)程無(wú)法繼續(xù),比如管理員在安裝LAMP時(shí),包需要libgd.so文件,而這個(gè)文件屬于GD軟件包。但是在安裝GD軟件包時(shí),可能這個(gè)軟件包跟其他軟件包又具有依賴關(guān)系,又需要安裝其他軟件包才行。這時(shí)有的管理員便失去耐心。在遇到這種Linux軟件包依賴關(guān)系問(wèn)題時(shí),該如何解決呢?在談這個(gè)具體的措施之前,先跟大家聊聊Linux系統(tǒng)里的軟件依賴性問(wèn)題。
一、什么是依賴性
程序依賴于程序代碼的共享庫(kù),以便它們可以發(fā)出系統(tǒng)調(diào)用將輸出發(fā)送到設(shè)備或打開(kāi)文件等(共享庫(kù)存在于許多方面,而不只局限于系統(tǒng)調(diào)用)。沒(méi)有共享庫(kù),每次程序員開(kāi)發(fā)一個(gè)新的程序,每個(gè)程序員都需要從頭開(kāi)始重寫(xiě)這些基本的系統(tǒng)操作。當(dāng)編譯程序時(shí),程序員將他的代碼鏈接到這些庫(kù)。如果鏈接是靜態(tài)的,編譯后的共享庫(kù)對(duì)象代碼就添加到程序執(zhí)行文件中;如果是動(dòng)態(tài)的,編譯后的共享庫(kù)對(duì)象代碼只在運(yùn)行時(shí)需要它時(shí)由程序員加載。動(dòng)態(tài)可執(zhí)行文件依賴于正確的共享庫(kù)或共享對(duì)象來(lái)進(jìn)行操作。rpm依賴性嘗試在安裝時(shí)強(qiáng)制實(shí)施動(dòng)態(tài)可執(zhí)行文件的共享對(duì)象需求,以便在以后當(dāng)程序運(yùn)行時(shí)不會(huì)有與動(dòng)態(tài)鏈接過(guò)程有關(guān)的任何問(wèn)題。
注意:還有一種類型的依賴性,它基于顯式的條目,rpm通過(guò)程序員將該依賴性強(qiáng)加到rpm配置文件中,但目前我們不關(guān)心這種類型的依賴性,這種依賴性比較容易解決。這里將重點(diǎn)放在rpm強(qiáng)制實(shí)施的更加復(fù)雜的共享對(duì)象依賴性。
二、動(dòng)態(tài)可執(zhí)行文件和共享對(duì)象
動(dòng)態(tài)可執(zhí)行文件使用最初編譯和鏈接程序時(shí)使用的庫(kù)文件的共享對(duì)象名稱來(lái)查找共享對(duì)象。它們?cè)谏贁?shù)的幾個(gè)標(biāo)準(zhǔn)位置查找,比如在/lib和/usr/lib目錄及在LD_LIBRARY_PATH環(huán)境變量(主要用于指定查找共享庫(kù),比如我們?cè)诎惭bOracle時(shí)指定路徑,export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib:/usr/local/lib)指定的目錄中。順便提一下,在這些庫(kù)目錄中找到的共享對(duì)象可能不是真正的文件;它們可能是指向位于其他位置的真實(shí)庫(kù)文件的符號(hào)鏈接(但通常仍舊在標(biāo)準(zhǔn)庫(kù)目錄的一個(gè)目錄中)。至少?gòu)南到y(tǒng)管理員的觀點(diǎn)是在用于創(chuàng)建共享庫(kù)文件的共享庫(kù)軟件包的名稱和共享庫(kù)文件的名稱之間通常沒(méi)有什么關(guān)系。例如,GLIBC 2.3軟件包用于創(chuàng)建libc.so.6共享庫(kù)文件。也從本示例中注意到,添加到共享庫(kù)文件名結(jié)束的版本號(hào)(.6)跟用于創(chuàng)建它的版本號(hào)(2.3)沒(méi)有關(guān)系。這是由共享庫(kù)軟件包開(kāi)發(fā)人員有意完成的,以便GLIBC的新版本可以重用相同的共享庫(kù)文件名libc.so.6。這允許您在系統(tǒng)上加載新版本的GLIBC,而不用中斷動(dòng)態(tài)鏈接到lib.so.6共享庫(kù)文件的所有程序,當(dāng)然假定新版本的GLIBC向后與動(dòng)態(tài)可執(zhí)行文件最初所鏈接的老版本GLIBC兼容。因此,即使庫(kù)文件或共享對(duì)象文件有與它們相關(guān)的版本號(hào),這些版本號(hào)也不能幫助你確定他們來(lái)自哪個(gè)版本的共享軟件包。
注意:當(dāng)將whatprovides選項(xiàng)用于rpm查詢命令時(shí),可以獲得有關(guān)使用rpm軟件包加載到系統(tǒng)的現(xiàn)有共享對(duì)象的信息。這種混亂是由下面的事實(shí)造成的:?jiǎn)蝹(gè)共享庫(kù)文件可能支持某個(gè)范圍的共享庫(kù)軟件包版本。例如,要檢查soname庫(kù)文件/lib/libc.so.6支持的GLIBC共享庫(kù)軟件包,運(yùn)行下面的命令:
#objdump --all-headers /lib/libc.so.6 | less
向下滾動(dòng)此報(bào)告,直到到達(dá)Version definitions: 部分,以便查看libc.so.6共享庫(kù)文件支持哪些GLIBC版本:
Version definitions:
1 0x01 0x0865f4e6 libc.so.6
2 0x00 0x0d696910 GLIBC_2.0
3 0x00 0x0d696911 GLIBC_2.1
GLIBC_2.0
4 0x00 0x09691f71 GLIBC_2.1.1
GLIBC_2.1
5 0x00 0x09691f72 GLIBC_2.1.2
GLIBC_2.1.1
6 0x00 0x09691f73 GLIBC_2.1.3
GLIBC_2.1.2
7 0x00 0x0d696912 GLIBC_2.2
GLIBC_2.1.3
8 0x00 0x09691a71 GLIBC_2.2.1
GLIBC_2.2
9 0x00 0x09691a72 GLIBC_2.2.2
GLIBC_2.2.1
10 0x00 0x09691a73 GLIBC_2.2.3
GLIBC_2.2.2
11 0x00 0x09691a74 GLIBC_2.2.4
GLIBC_2.2.3
12 0x00 0x09691a76 GLIBC_2.2.6
GLIBC_2.2.4
13 0x00 0x0d696913 GLIBC_2.3
GLIBC_2.2.6
14 0x00 0x09691972 GLIBC_2.3.2
GLIBC_2.3
15 0x00 0x09691973 GLIBC_2.3.3
GLIBC_2.3.2
16 0x00 0x09691974 GLIBC_2.3.4
GLIBC_2.3.3
17 0x00 0x0d696914 GLIBC_2.4
GLIBC_2.3.4
18 0x00 0x0d696915 GLIBC_2.5
GLIBC_2.4
19 0x00 0x0963cf85 GLIBC_PRIVATE
GLIBC_2.5
20 0x00 0x0b792650 GCC_3.0
在本示例中,1ibc.so.6共享庫(kù)文件支持原先為GLIBC版本2.0到2.5而開(kāi)發(fā)的所有動(dòng)態(tài)執(zhí)行文件。注意:也可以使用objdump命令來(lái)從共享庫(kù)文件中提取soname,命令如下所示:
# objdump --all -headers /lib/libcrypto.so.0.9.8b| grep SONAME
SONAME libcrypto.so.6
objdump: /lib/libcrypto.so.0.9.8b: no recognized debugging information
接下來(lái),將討論rpm軟件包是如何生成的,以便在新系統(tǒng)上安裝rpm軟件包時(shí),這些共庫(kù)依賴性是己知的。
三、Rpm軟件包和共享庫(kù)依賴性
當(dāng)程序員生成rpm軟件包時(shí),ldd命令用于報(bào)告動(dòng)態(tài)可執(zhí)行文件軟件包中所有動(dòng)態(tài)可執(zhí)行文件使用的所有共享庫(kù)。另一個(gè)混亂是由下面的事實(shí)帶來(lái)的:相同軟件包中的不同動(dòng)態(tài)可執(zhí)行文什可能與相同的共享庫(kù)軟什包的不同版本進(jìn)行鏈接。例如,Heartbeat軟什包中的不同程序可能已經(jīng)進(jìn)行了開(kāi)發(fā),并動(dòng)態(tài)鏈接到libc.so.6 sonmae共享庫(kù)文件的不同GLIBC版本。對(duì)rpm命令使用-q和--requires參數(shù),可以看到rpm軟件包需要的共享庫(kù)的完整清單。例如,要看到Heartbeat rpm軟件包所有的所需依賴性,請(qǐng)使用命令:
#rpm -q --requires -p heartbeat-1.x.x.i386.rpm
這產(chǎn)生了下面的報(bào)告:
sysklogd
/bin/sh
/bin/sh
/usr/bin/python
ld-linux.so.2
libapphb.so.0
libc.so.6
libc.so.6(GLIBC_2.0)
libc.so.6(GLIBC_2.1)
libc.so.6(GLIBC_2.1.3)
libc.so.6(GLIBC_2.2)
libc.so.6(GLIBC_2.3)
libccmclient.so.0
libdl.so.2
libglib-1.2.so.0
libhbclient.so.0
libpils.so.0
libplumb.so.0
libpthread.so.0
librt.so.1
libstonith.so.0
注意,在此報(bào)告中,libc.so.6 soname是所需要的,此共享庫(kù)必須支持使用GLIBC共享軟件包版本號(hào)2.0、2.1、2.1.3、2.2和2.3進(jìn)行鏈接的動(dòng)態(tài)可執(zhí)行文件。這是由下面的事實(shí)決定的:Heartbeat軟件包中的不同動(dòng)態(tài)可執(zhí)行文件是針對(duì)不同版本的libc.so.6庫(kù)的每個(gè)版本進(jìn)行鏈接的。在了解了動(dòng)態(tài)可執(zhí)行文件、共享對(duì)象、soname和共享庫(kù)軟件包彼此是如何相關(guān)的后,下面準(zhǔn)備來(lái)看這樣的一個(gè)例子:當(dāng)嘗試安裝rpm軟件包,并且它由于依賴性錯(cuò)誤而失敗時(shí),會(huì)發(fā)生什么。yum能夠從指定的服務(wù)器自動(dòng)下載RPM包并且安裝,可以自動(dòng)處理依賴性關(guān)系,并且一次安裝所有依賴的軟體包,無(wú)須繁瑣地一次次下載、安裝。
四、手工解決依賴性問(wèn)題
通常,當(dāng)嘗試安裝發(fā)行版中沒(méi)有包括的軟件包(及不能由像up2date、apt- get或Yum一樣的更新工具自動(dòng)解決其依賴性的軟件包)時(shí),將碰到rpm依賴性錯(cuò)誤。例如,如果嘗試在老的Linux發(fā)行版上使用rpm –ivh *rpm命令,例如所有的Heartbeat rpm包,那么在安裝過(guò)程中就可能碰到下面的錯(cuò)誤:
error: failed dependencies:
libc.so.6(GLIBC_2.3) is needed by heartbeat-1.x.x
libc.so.6(GLIBC_2.3) is needed by heartbeat-pils-1.x.x
libcrypto.so.0.9.6 is needed by heartbeat-stonith-1.x.x
libsnmp-0.4.2.6.so is needed by heartbeat-stonith-1.x.x
注意,rpm命令沒(méi)有干擾報(bào)告所需的每個(gè)GLIBC共享庫(kù)軟件包版本號(hào)——它只報(bào)告所需的最高編號(hào)的版本號(hào)(GLIBC_2.3)。(假定原來(lái)的軟件包開(kāi)發(fā)人員不會(huì)將相同軟件包中的可執(zhí)行文件鏈接到不兼容版本的共享庫(kù)軟件包)所有的這些故障都報(bào)告所需的共享庫(kù)名稱或soname(而不是文件名稱,soname始終以“l(fā)ib”開(kāi)始)。但可以刪除添加到rpm報(bào)告的soname結(jié)束的版本號(hào),并快速檢查以查看是否在系統(tǒng)中使用locate命令安裝這些共享庫(kù)(假設(shè)您的locate數(shù)據(jù)庫(kù)是最新的,有關(guān)更多信息,請(qǐng)參閱locate或slocate的手冊(cè)頁(yè))。例如,要查找libcrypto享庫(kù)文件,要輸入:
#locate libcrypto
[root@localhost ~]# locate libcrypto
/lib/libcrypto.so.0.9.8b
/lib/libcrypto.so.6
/root/.Trash/vmware-tools-distrib/lib/lib32/libcrypto.so.0.9.8
/root/.Trash/vmware-tools-distrib/lib/lib32/libcrypto.so.0.9.8/libcrypto.so.0.9.8
/root/.Trash/vmware-tools-distrib/lib/lib64/libcrypto.so.0.9.8
/root/.Trash/vmware-tools-distrib/lib/lib64/libcrypto.so.0.9.8/libcrypto.so.0.9.8
/usr/lib/libcrypto.a
/usr/lib/libcrypto.so
/usr/lib/pkgconfig/libcrypto.pc
/usr/lib/vmware-tools/lib32/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib32/libcrypto.so.0.9.8/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib64/libcrypto.so.0.9.8
/usr/lib/vmware-tools/lib64/libcrypto.so.0.9.8/libcrypto.so.0.9.8
如果此命令沒(méi)有在系統(tǒng)上找到一個(gè)libcrypto共享庫(kù)文件,將需要轉(zhuǎn)到Internet并找出哪個(gè)共享庫(kù)軟件包包含此共享庫(kù)文件。完成此項(xiàng)工具的一個(gè)快速和簡(jiǎn)便方式是只要在http://rpmfind.net上將共享庫(kù)的名稱輸入到搜索欄中。如果將文本libcrypto.so輸入到此搜索貞中,將很快知道此共享庫(kù)是由openssl軟件包提供的。
libcrypto.so資源包
如果老版本的共享庫(kù)數(shù)據(jù)包已經(jīng)安裝在系統(tǒng)上,可以用如下的命令確認(rèn)此軟件包含您需要的共享庫(kù)文件:
#rpm -q --provides openssl
[root@localhost ~]# rpm -q --provides openssl
config(openssl) = 0.9.8b-10.el5
lib4758cca.so
libaep.so
libatalla.so
libchil.so
libcrypto.so.6
libcswift.so
libgmp.so
libnuron.so
libssl.so.6
libsureware.so
libubsec.so
openssl = 0.9.8b-10.el5
此命令報(bào)告此rpm軟件包中提供的所有內(nèi)容(這包括軟件包提供的共享庫(kù)文件的soname)。注意:如前面指出的,共享庫(kù)軟件包版本號(hào)沒(méi)有并且應(yīng)該沒(méi)有與共享庫(kù)文件( soname)版本號(hào)的任何對(duì)應(yīng)關(guān)系。這里不進(jìn)行這方面的討論,因?yàn)閟oname符號(hào)鏈接可能指向不同版本的共享庫(kù)文件,這也是在盡量避免在安裝新版本的共享軟件包時(shí)中斷現(xiàn)有動(dòng)態(tài)可執(zhí)行文件的情況下完成的。
五、自動(dòng)解決依賴性故障
當(dāng)您使用rpm軟件包來(lái)生成、升級(jí)或添加新的特性到系統(tǒng)時(shí),依賴性故障可能很快變成一場(chǎng)惡夢(mèng)。只要通過(guò)使用您的發(fā)行版供應(yīng)商的升級(jí)服務(wù)或工具,就可以避免這場(chǎng)惡夢(mèng)。例如,當(dāng)選擇要安裝的rpm軟件包時(shí),Red Hat工具up2date自動(dòng)從Red Hat下載并安裝所有rpm依賴性。下面就點(diǎn)上列出了幾個(gè)完成相同事情的支持社區(qū)的免費(fèi)方法:http://www.rpm.org/。下面將只進(jìn)一步看到這些自動(dòng)更新工具中的一種:Yum。
1.使用Yum來(lái)安裝rpm軟件包
Yum(Yellow dog Updater,Modified)程序可從下面網(wǎng)址下載:http://yum.baseurl.org/download/3.4/yum-3.4.3.tar.gz
在下載了此軟件包后,可以使用下面的命令像任何其他rpm軟件包那樣安裝它:
#rpm -ivh yum*
您可能需要更新想用于下載您的rpm軟件包的存儲(chǔ)庫(kù)。有關(guān)Fedora的可用Yum存儲(chǔ)庫(kù)的清單在http://www.fedoratracker.org要切換到不同的存儲(chǔ)庫(kù),下載這些文件中的一個(gè)文件,并將該文件作為/etc/yum.conf文件安裝,F(xiàn)在可以用下面的命令告訴Yum報(bào)告存儲(chǔ)在Yum存儲(chǔ)庫(kù)中、可用于安裝所有軟件包:
#yum list
[root@localhost ~]# yum list |more
This system is not registered with RHN.
RHN support will be disabled.
Loading "security" plugin
Loading "rhnplugin" plugin
Installed Packages
Deployment_Guide-en-US.noarch 5.2-9 installed
Deployment_Guide-zh-CN.noarch 5.2-9 installed
Deployment_Guide-zh-TW.noarch 5.2-9 installed
GConf2.i386 2.14.0-9.el5 installed
GConf2-devel.i386 2.14.0-9.el5 installed
ImageMagick.i386 6.2.8.0-4.el5_1.1 installed
MAKEDEV.i386 3.23-1.2 installed
MySQL-python.i386 1.2.1-1 installed
NetworkManager.i386 1:0.6.4-8.el5 installed
NetworkManager-glib.i386 1:0.6.4-8.el5 installed
2.用Yum安裝新的rpm軟件包
在本示例中,將安裝新的GLIBC軟件包。用簡(jiǎn)單的命令安裝最新的GLIBC及其所有依賴性:
#yum update glibc
如果一切正常,Yum程序?qū)⒆詣?dòng)檢測(cè)、下載并安裝最新GLIBC軟件包所需要的所有rpm軟件包(這里的GLIBC軟件包是為您的發(fā)行版而構(gòu)建的,不一定是可用的最新版GLIBC軟件包(使用發(fā)行版所批準(zhǔn)的GLIBC共享庫(kù)軟件包版本號(hào)或冒險(xiǎn)安裝沒(méi)有使用正常系統(tǒng)操作所需要的動(dòng)態(tài)可執(zhí)行文件的GLIBC軟件包版本)。也可以將list參數(shù)用于Yum和grep命令來(lái)查找要安裝的軟件包。例如,要查找名稱中有SNMP的軟件包,請(qǐng)輸入:
# yum list |grep snmp
此命令返回如下報(bào)告:
This system is not registered with RHN.
RHN support will be disabled.
net-snmp.i386 1:5.3.1-24.el5 installed
net-snmp-libs.i386 1:5.3.1-24.el5 installed
net-snmp-perl.i386 1:5.3.1-24.el5 installed
net-snmp-utils.i386 1:5.3.1-24.el5 installed
現(xiàn)在可以容易地使用YUM下載并安裝所有這些rpm軟件包。
六、關(guān)于升級(jí)Gilbc的建議
Glibc 庫(kù)是Linux 底層的運(yùn)行庫(kù),其性能對(duì)于整個(gè)系統(tǒng)的運(yùn)行有重要的意義。Glibc 庫(kù)包含了大量函數(shù),其中的函數(shù)可大致分成兩類,一類是與操作系統(tǒng)核心溝通的系統(tǒng)調(diào)用接口,它們作為功能型函數(shù)被調(diào)用,提供對(duì)Linux 操作系統(tǒng)調(diào)用的包裝與預(yù)處理。另外一類為一般的函數(shù)對(duì)象,它們提供了經(jīng)常使用的功能的實(shí)現(xiàn),作為工具型函數(shù)使用。在實(shí)踐中,有不少軟件就是依賴與Glibc版本才能安裝并運(yùn)行,說(shuō)白了對(duì)于Glibc版本要求是版本高了不行,低了還不成。這些編譯環(huán)境中的應(yīng)用程序也和其它程序一樣必須有運(yùn)行的環(huán)境,我常遇到管理員在生產(chǎn)中給服務(wù)器裝了最新的Linux發(fā)行版,結(jié)果應(yīng)用軟件裝不上去,原因是Glibc的版本不對(duì),有的是寫(xiě)在原發(fā)行版glibc上升級(jí)有的是降級(jí),結(jié)果倒是整個(gè)系統(tǒng)的崩潰,實(shí)踐經(jīng)驗(yàn)告訴我,你只有選擇相應(yīng)Linux發(fā)行版里對(duì)應(yīng)的glibc,例如我們單位的一個(gè)應(yīng)用軟件時(shí)在rhel3.0下開(kāi)發(fā)的,那么就得要對(duì)應(yīng)的發(fā)行版,換了別的就難說(shuō)了,任何自己升級(jí)或降級(jí)Glibc來(lái)適應(yīng)應(yīng)用軟件的做法都是不可取的,問(wèn)題最后的解決方法是找到了RHEL3裝上就解決了。在表一中,我把幾個(gè)linux發(fā)行版原配的Glibc版本列出,供大家參考。
Glibc庫(kù)與核心功能組件
上圖一說(shuō)明:
GCC依賴于glibc
binutils依賴于glibc (binutils提供了一系列用來(lái)創(chuàng)建、管理和維護(hù)二進(jìn)制目標(biāo)文件的工具程序,如匯編(as)、連接(ld)、靜態(tài)庫(kù)歸檔(ar)、反匯編)
make依賴于glibc
頭文件是在編譯時(shí)候gcc所需要的,但本身都是一些文本文件,因此沒(méi)有需要的運(yùn)行環(huán)境。
常用工具依賴于glibc和各種需要用到的動(dòng)態(tài)庫(kù)。
下表一列出了多個(gè)重要Linux發(fā)行版的Glibc的情況
Linux發(fā)行版 Glibc版本
Redhat 9 glibc-2.3.2-5
Fedora 1 glibc-2.3.2
Redhat EntERPrise Linux As 3 glibc-2.3.2-95
Redhat EntERPrise Linux As 4 glibc-2.3.4
Red hat EntERPrise linux 5 glibc-2.5-24
Red hat Enterprise linux 6 glibc-2.9
Centos 5.x glibc-2.5
Suse Linux Enterprise Server 9 glibc-2.3.2-92
Suse Linux enterprise Server 10 glibc-2.4.31.54
Suse Linux Enterprise Server 11 glibc-2.9
Linux發(fā)行版glibc (32)位
下面介紹幾個(gè)查詢glibc版本號(hào)的方法 :
#ls –al /lib/libc*
或者是用下面的命令也可以實(shí)現(xiàn)
#rpm –qp |grep glibc
基于debian的系統(tǒng)通過(guò)dpkg –l | grep libc6也可以查到,總之一般都在/usr/share/doc目錄下都能看到glibc的相關(guān)信息。
七 、小結(jié)
大部分情況下,在遇到軟件包依賴關(guān)系問(wèn)題的時(shí)候,操作系統(tǒng)提供的文件名字與軟件包名字都會(huì)有直接的聯(lián)系。有可能文件的名字就是軟件包的名字。但是有些時(shí)候文件的名字與軟件包的名字會(huì)相差甚遠(yuǎn)。此時(shí)大部分系統(tǒng)管理員可能光憑文件名字無(wú)法找到對(duì)應(yīng)的軟件包。此時(shí)可以先在系統(tǒng)安裝光盤(pán)里找,如果找到那時(shí)最佳選項(xiàng),然后就需要借助筆者上面談到的一些專業(yè)網(wǎng)站,去查詢軟件包的名字了。當(dāng)系統(tǒng)管理員安裝了某個(gè)軟件之后,如果存在軟件包之間的依賴關(guān)系,則最好能夠拿本子或者通過(guò)其他手段記錄下來(lái)。以便下次方便實(shí)用,注意工作中的積累,相信絕大部分的軟件包依賴關(guān)系問(wèn)題都會(huì)迎刃而解。
轉(zhuǎn)載請(qǐng)注明出處:拓步ERP資訊網(wǎng)http://www.oesoe.com/
本文標(biāo)題:如何解決源碼包安裝時(shí)的依賴性問(wèn)題
本文網(wǎng)址:http://www.oesoe.com/html/support/1112154515.html