談談Linux下動態庫查找路徑的問題
原文地址:
http://blog.chinaunix.net/uid-23069658-id-4028681.html
學習到了一個階段之後,就需要不斷的總結、沈澱、清零,然後才能繼續“上路”。回想起自己當年剛接觸Linux時,不管是用源碼包編譯程序,還是程序運行時出現的和動態庫的各種恩恩怨怨,心裏那真叫一個難受。那時候腦袋裏曾經也犯過嘀咕,為啥Linux不弄成windows那樣呢,裝個軟件那個麻煩不說,連運行軟件都這麽惱火呢?如果那樣的話就不叫Linux了。借用小米公司CEO雷軍一句話:小米,為發燒而生。我認為:Linux,為真理而在。特別是為那些喜歡折騰,熱衷技術背後原理和實現細節的人們而生。
說到和動態庫查找路徑相關的問題,總體上可以分為兩類:
第一類:通過源代碼編譯程序時出現的找不到某個依賴包的問題,而如果此時你恰好已經按照它的要求確確實實、千真萬確、天地良心地把依賴庫給裝好了,它還給你耍混、犯二,有一股折騰不死人不償命的勁兒,那讓人真是氣兒不打一處來,如果Linux此時有頭有臉,你是不是特想抽它丫兩大嘴巴;
第二類:就是在運行程序的時候,明明把那個程序需要的依賴包都已經安裝的妥妥的了,可運行的時候人家就告訴你說“error while loading shared libraries: libxxx
上面兩類問題最大的原因就是,你沒弄白它們的機制和原理。你看到的只是現象,當年學馬克思主義主義哲學原理的時候,老師怎麽教導我們的?要透過現象看本質。如果你把上面兩中應用的原理搞清了,那問題不就自然而然的迎刃而解了麽。下面咱們就一一探討一下這兩個問題,以便對新進學習Linux的朋友們起一個的參考資料的作用。
問題1:通過源代碼安裝程序
通過源碼包安裝程序時,主要用到了“三大步”策略:configure、make和make install 。出問題最多的就是在configure階段,很多初學者由於不知道configure的那麽多參數該怎麽用,所以往往為了省事,一句簡單的“./configure”下去,百分之八九十都能成功,可問題往往就出在剩下的百分之十幾上面了。這讓我們又一次相信了,小概率事件的發生對事情的影響是多麽的深遠。在安裝的configure階段,為了檢測安裝安裝環境是否滿足,通常情況下都是通過一個叫做pkg-config的工具來檢測它需要依賴的動態庫是否存在,這個工具我們在上一篇博文已經認識過了。pkg-config通常情況都是位於/usr/bin目錄下,是個可執行程序。在configure階段,通常都會用pkg-config來判斷所依賴的動態庫是否存在。現在問題就是,這個工具是如何判斷的呢?它的依據是什麽?當這兩個問題弄明白了,真相也就大白了。
一般當我們安裝完某個程序後,如果它提供了動態庫的功能,在源碼中都會有一個或多個以pc結尾的文件,當執行完make install後這些pc文件拷貝到${prefix}/lib/pkgconfig這個目錄裏,這裏的prefix就是我們在configure階段時通過配置參數--prefix指定的,缺省情況這個值就是/usr/local,所以這些pc文件最終會被拷貝到/usr/local/lib/pkgconfig目錄下。可能有人會問,這些pc文件有啥用呢?我們隨便打開一個來瞅瞅:
[root@localhost ~]# cat /usr/local/lib/pkgconfig/librtmp.pc prefix=/usr/local exec_prefix=${prefix} libdir=${exec_prefix}/lib incdir=${prefix}/include Name: librtmp Description: RTMP implementation Version: v2.3 Requires: libssl,libcrypto URL: http://rtmpdump.mplayerhq.hu Libs: -L${libdir} -lrtmp -lz Cflags:-I${incdir}
跟我們configure階段相關的主要集中在Libs和Cflags兩項上面,如果你此時再執行下面這兩條命令,就全明白了:
[root@localhost ~]# pkg-config --cflags librtmp -I/usr/local/include [root@localhost ~]# pkg-config --libs librtmp -L/usr/local/lib -lrtmp -lz -lssl -lcrypto
也就是說,pkg-config把我們以前需要在Makefile裏指定編譯和鏈接時所需要用到的參數從手工硬編碼的模式變成了自動完成,節約了多少跨平臺移植的兼容性問題,我們是不是得感謝人家十八輩兒祖宗。假如說,如果我們將要的編譯的軟件包依賴librtmp這個動態庫,那麽此時在我系統上這個檢測就算通過了。當然這只是第一步,檢測過了不一定兼容,這裏我們只討論能不能找到依賴庫的問題,兼容性問題那都不是個事兒,人家要啥版本你好生伺候就是了,這個沒得商量,最好也不要商量,童叟無欺,不然後果很嚴重。好了,如果說找不到某個庫該怎麽辦。前提是你確確實實已經安裝了它需要的庫,不用多想,原因只有一個,pkg-config找不到這個與這個庫對應的pc文件。為什麽會找不到呢,原因又有兩點:
1、pkg-config搜索了所有它認為合適的目錄都沒找著這個庫對應的pc文件的下落;
2、這個庫在發布時根本就沒有提供它的pc文件。
這裏,我們嚴重“抗議、鄙視+抵制”第二種情況的軟件包,而且也盡量不要它,一個出來混都不自報家門的家夥,肯定也好不到哪裏去。那麽,現在問題就只剩下一個了:pkg-config的查找路徑是哪裏?
pkg-config較老的版本裏,缺省情況下會到/usr/lib/pkgconfig、/usr/loca/lib/pkgconfig、/usr/share/pkgconfig等目錄下去搜索pc文件,據我所知在0.23以及之後的版本裏pkg-config的源碼裏已經沒有關於缺省搜索路徑的任何硬編碼的成分了,至於具體從哪個版本開始我也沒有去追究,還望有知道的朋友分享一下。取而代之的是,當你看pkg-config的man手冊時會有下面一段話:
pkg-config retrieves information about packages from special metadata files. These files are named after the package, with the extension .pc. By default, pkg-config looks in the directory prefix/lib/pkgconfig for these files; it will also look in the colon-separated (on Windows, semicolon-separated) list of directories specified by the PKG_CONFIG_PATH environment variable.
以及這點補充:
PKG_CONFIG_PATH A colon-separated (on Windows, semicolon-separated) list of directories to search for .pc files. The default directory will always be searched after searching the path; the default is libdir/pkg-config:datadir/pkgconfig where libdir is the libdir where pkg-config and datadir is the datadir where pkg-config was installed.
上面提到的prefix、libdir和datadir,就是安裝pkg-config時被設定好的,具體情況是:
1、如果你是通過yum和rpm包安裝的
prefix=/usr
libdir=${prefix}/lib=/usr/lib
datadir=${prefix}/share=/usr/share
2、如果你是通過源碼包安裝的,且沒有指定prefix的值(指定的情況同1)
prefix=/usr/local
libdir=${prefix}/lib=/usr/local/lib
datadir=${prefix}/share=/usr/local/share
pkg-config在查找對應軟件包的信息時的缺省搜索路徑已經很清楚了,有一點寫錯了,不是${libdir}/pkg-config,而應該是${libdir}/pkgconfig和${datadir}/pkgconfig。如果你軟件包對應的pc文件都不在這兩個目錄下時,pkg-config肯定找不到。既然原因都已經找到了,那解決辦法也就多種多樣了。
方案一:我們可以在安裝我們那個被依賴的軟件包時,在configure階段用--prefix參數把安裝目錄指定到/usr目錄下;
方案二:也可以按照上面說的,通過一個名叫PKG_CONFIG_PATH的環境變量來向pkg-config指明我們自己的pc文件所在的路徑,不過要註意的是PKG_CONFIG_PATH所指定的路徑優先級比較高,pkg-config會先進行搜索,完了之後才是去搜索缺省路徑。
前者的優點是以後再通過源碼安裝軟件時少了不少麻煩,缺點是用戶自己的軟件包和系統軟件混到一起不方便管理,所以實際使用中,後者用的要多一些。
方案二在實際操作中有兩種實現方式:
1、針對沒有root權限的情況,大多數情況都是執行:
export PKG_CONFIG_PATH=/your/local/path:$PKG_CONFIG_PATH
然後,在configure時就絕對沒問題了。
2、在用戶的家目錄下的.bash_profile文件裏或系統文件/etc/profile的末尾添加上面一行也成,都可以。
至此,動態庫查找問題的第一種情況就徹底解決了。想了解pc文件的更多細節的,可以參考http://people.freedesktop.org/~dbn/pkg-config-guide.html ; 想學習pkg-config工具更多用法的朋友建議看man手冊。
問題2:程序運行時出現libxxx.so.y => not found
這種情況,在我以前的博文“Linux系統下動態庫和靜態庫那點事兒”裏已經提到一部分,這裏就把它補充完整。在那篇博文裏,我用的配置文件或者“ldconfig 動態庫所在路徑”的方式解決的,也是99%的場合下的解決辦法,那是針對有root權限的用戶的解決辦法。沒有root權限運行軟件時,Linux也為我們提供了一個名為LD_LIBRARY_PATH的環境變量來解決運行時動態庫查找路徑的解決方案。同樣地,由這個環境變量所指定的路徑會被裝載器/lib/ld-2.12.so優先查找,然後才是動態庫庫緩存文件/etc/ld.so.cache,風采瞬間就被LD_LIBRARY_PATH給搶完了,/etc/ld.so.cache表示很不高興。針對LD_LIBRARY_PATH環境變量這種情況,絕對是臨時不能再臨時解決方案了,如果只是測試用,用export像解決PKG_CONFIG_PATH一樣的方式幹凈利索就行了,千萬不要在實際生產上線的運維環境裏把“export LD_LIBRARY_PATH=...” 添加到.bash_profile或者/etc/profile裏,不然到時候悔得你腸子都綠了不可。
其實PKG_CONFIG_PATH和LD_LIBRARY_PATH經常被很多人誤用,特別是新手們在解決問題時,也不分青紅皂白,逮著了就是一頓狂export,根據實際場合,運氣好了說不定問題還真就解決,點兒背了折騰一天半宿也是白忙活。其實要是留點心,還是挺容易明白的:
PKG_CONFIG_PATH從字面意思上翻譯,就是“軟件包的配置路徑”,這不很明顯了麽,編譯軟件時如果出現找不到所依賴的動態庫時都全靠PKG_CONFIG_PATH了;
LD_LIBRARY_PATH也很直白了“裝載器的庫路徑”,LD是Loader的簡寫,在博文“段錯誤到底是何方妖孽”裏我也曾提到過,在Linux系統啟動一個程序的過程就叫做裝載,一個程序要執行時它或多或少的會依賴一些動態庫(靜態編譯的除外)。當你用“ldd 可執行程序名”查看一個軟件啟動時所依賴的動態庫,如果輸出項有“libxxx.so.y=> not found”一項,你這個軟件100%運行不起來。
不信我們來做個試驗:
[root@localhost ~]# echo $LD_LIBRARY_PATH //嘛也沒有 [root@localhost ~]# ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0x00914000) libavdevice.so.54 => /usr/local/lib/libavdevice.so.54 (0x007d0000) libavfilter.so.3 => /usr/local/lib/libavfilter.so.3 (0x001f3000) libavformat.so.54 => /usr/local/lib/libavformat.so.54 (0x002b5000) libavcodec.so.54 => /usr/local/lib/libavcodec.so.54 (0xb68dd000) libpostproc.so.52 => /usr/local/lib/libpostproc.so.52 (0x0083c000) libswresample.so.0 => /usr/local/lib/libswresample.so.0 (0x00a91000) libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x00d80000) libavutil.so.52 => /usr/local/lib/libavutil.so.52 (0x001a7000) libm.so.6 => /lib/libm.so.6 (0x0058b000) libpthread.so.0 => /lib/libpthread.so.0 (0x001d7000) libc.so.6 => /lib/libc.so.6 (0x005e2000) libasound.so.2 => /lib/libasound.so.2 (0x00ec5000) libdc1394.so.22 => /usr/local/lib/libdc1394.so.22 (0x00116000) librt.so.1 => /lib/librt.so.1 (0x00184000) libfreetype.so => /usr/local/lib/libfreetype.so (0x00411000) libass.so.4 => /usr/local/lib/libass.so.4 (0x0091a000) libssl.so.1.0.0 => /usr/local/lib/libssl.so.1.0.0 (0x0048c000) libcrypto.so.1.0.0 => /usr/local/lib/libcrypto.so.1.0.0 (0x00aa8000) librtmp.so.0 => /usr/local/lib/librtmp.so.0 (0x009dd000) libz.so.1 => /lib/libz.so.1 (0x0018d000) libx264.so.132 => /usr/local/lib/libx264.so.132 (0x00fb1000) libvorbisenc.so.2 => /usr/local/lib/libvorbisenc.so.2 (0x0194d000) libvorbis.so.0 => /usr/local/lib/libvorbis.so.0 (0x004e5000) libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x00799000) libtwolame.so.0 => /usr/local/lib/libtwolame.so.0 (0x0050d000) libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x0052d000) libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x00779000) libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00c94000) libmp3lame.so.0 => /usr/local/lib/libmp3lame.so.0 (0x0088c000) libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x00573000) /lib/ld-linux.so.2 (0x005c2000) libdl.so.2 => /lib/libdl.so.2 (0x001a1000) libraw1394.so.11 => /usr/local/lib/libraw1394.so.11 (0x005b5000) libfribidi.so.0 => /usr/local/lib/libfribidi.so.0 (0x007b5000) libfontconfig.so.1 => /usr/local/lib/libfontconfig.so.1 (0x007ea000) libogg.so.0 => /usr/local/lib/libogg.so.0 (0x00583000) libexpat.so.1 => /lib/libexpat.so.1 (0x00933000)
我的系統裏沒有設置LD_LIBRARY_PATH環境變量,上一篇博文裏編譯的ffmpeg運行時依賴的非常多的動態庫。現在我們把其中的一個庫libmp3lame.so.0從/usr/loca/lib下移動到/opt目錄裏,並執行ldconfig,讓libmp3lame.so.0徹底從/etc/ld.so.cache裏面消失。其實libmp3lame.so.0只是libmp3lame.so.0.0.0的一個符號鏈接,我們真正需要移動的是後者,完了之後再執行ldd /usr/local/bin/ffmpeg時結果如下:
[root@localhost ~]# ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0x00249000) libavdevice.so.54 => /usr/local/lib/libavdevice.so.54 (0x00e12000) libavfilter.so.3 => /usr/local/lib/libavfilter.so.3 (0x00ccd000) libavformat.so.54 => /usr/local/lib/libavformat.so.54 (0x00891000) libavcodec.so.54 => /usr/local/lib/libavcodec.so.54 (0xb6877000) libpostproc.so.52 => /usr/local/lib/libpostproc.so.52 (0x001a6000) libswresample.so.0 => /usr/local/lib/libswresample.so.0 (0x00b8f000) libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x0024a000) libavutil.so.52 => /usr/local/lib/libavutil.so.52 (0x005d7000) libm.so.6 => /lib/libm.so.6 (0x007ad000) libpthread.so.0 => /lib/libpthread.so.0 (0x001f6000) libc.so.6 => /lib/libc.so.6 (0x0029f000) libasound.so.2 => /lib/libasound.so.2 (0x00604000) libdc1394.so.22 => /usr/local/lib/libdc1394.so.22 (0x00436000) librt.so.1 => /lib/librt.so.1 (0x00a06000) libfreetype.so => /usr/local/lib/libfreetype.so (0x0052d000) libass.so.4 => /usr/local/lib/libass.so.4 (0x00211000) libssl.so.1.0.0 => /usr/local/lib/libssl.so.1.0.0 (0x00eed000) libcrypto.so.1.0.0 => /usr/local/lib/libcrypto.so.1.0.0 (0x00f46000) librtmp.so.0 => /usr/local/lib/librtmp.so.0 (0x004b9000) libz.so.1 => /lib/libz.so.1 (0x0022a000) libx264.so.132 => /usr/local/lib/libx264.so.132 (0x0765d000) libvorbisenc.so.2 => /usr/local/lib/libvorbisenc.so.2 (0x00a0f000) libvorbis.so.0 => /usr/local/lib/libvorbis.so.0 (0x004ce000) libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x005a8000) libtwolame.so.0 => /usr/local/lib/libtwolame.so.0 (0x006f0000) libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x00710000) libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x00756000) libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00770000) libmp3lame.so.0 => not found //果然飄紅了 :) libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x004a4000) /lib/ld-linux.so.2 (0x0050d000) libdl.so.2 => /lib/libdl.so.2 (0x0023e000) libraw1394.so.11 => /usr/local/lib/libraw1394.so.11 (0x004f6000) libfribidi.so.0 => /usr/local/lib/libfribidi.so.0 (0x0078a000) libfontconfig.so.1 => /usr/local/lib/libfontconfig.so.1 (0x007d7000) libogg.so.0 => /usr/local/lib/libogg.so.0 (0x00243000) libexpat.so.1 => /lib/libexpat.so.1 (0x00806000) [root@localhost ~]# ffmpeg --help ffmpeg: error while loading shared libraries: libmp3lame.so.0: cannot open shared object file: No such file or directory //此時ffmpeg當然運行不起來
我們來試試LD_LIBRARY_PATH,看看好使不:
[root@localhost opt]# export LD_LIBRARY_PATH=/opt:$LD_LIBRARY_PATH [root@localhost opt]# [root@localhost opt]# ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0x00136000) libavdevice.so.54 => /usr/local/lib/libavdevice.so.54 (0x00552000) libavfilter.so.3 => /usr/local/lib/libavfilter.so.3 (0x00655000) libavformat.so.54 => /usr/local/lib/libavformat.so.54 (0x00243000) libavcodec.so.54 => /usr/local/lib/libavcodec.so.54 (0xb68a7000) libpostproc.so.52 => /usr/local/lib/libpostproc.so.52 (0x00137000) libswresample.so.0 => /usr/local/lib/libswresample.so.0 (0x00187000) libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x0047e000) libavutil.so.52 => /usr/local/lib/libavutil.so.52 (0x00a9d000) libm.so.6 => /lib/libm.so.6 (0x00af9000) libpthread.so.0 => /lib/libpthread.so.0 (0x00823000) libc.so.6 => /lib/libc.so.6 (0x0083e000) libasound.so.2 => /lib/libasound.so.2 (0x0055f000) libdc1394.so.22 => /usr/local/lib/libdc1394.so.22 (0x0019e000) librt.so.1 => /lib/librt.so.1 (0x00b3c000) libfreetype.so => /usr/local/lib/libfreetype.so (0x0039f000) libass.so.4 => /usr/local/lib/libass.so.4 (0x00f67000) libssl.so.1.0.0 => /usr/local/lib/libssl.so.1.0.0 (0x00cb3000) libcrypto.so.1.0.0 => /usr/local/lib/libcrypto.so.1.0.0 (0x00d0c000) librtmp.so.0 => /usr/local/lib/librtmp.so.0 (0x0020c000) libz.so.1 => /lib/libz.so.1 (0x00c77000) libx264.so.132 => /usr/local/lib/libx264.so.132 (0x00f80000) libvorbisenc.so.2 => /usr/local/lib/libvorbisenc.so.2 (0x07c66000) libvorbis.so.0 => /usr/local/lib/libvorbis.so.0 (0x0041a000) libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x0076c000) libtwolame.so.0 => /usr/local/lib/libtwolame.so.0 (0x004fe000) libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x00717000) libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x00f0c000) libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00221000) libmp3lame.so.0 => not found //納尼??!!! libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x00124000) /lib/ld-linux.so.2 (0x00bad000) libdl.so.2 => /lib/libdl.so.2 (0x0023b000) libraw1394.so.11 => /usr/local/lib/libraw1394.so.11 (0x007b6000) libfribidi.so.0 => /usr/local/lib/libfribidi.so.0 (0x00442000) libfontconfig.so.1 => /usr/local/lib/libfontconfig.so.1 (0x0051e000) libogg.so.0 => /usr/local/lib/libogg.so.0 (0x009f7000) libexpat.so.1 => /lib/libexpat.so.1 (0x00b60000)
還記得上面提到了軟鏈接麽,libmp3lame.so.0就是libmp3lame.so.0.0.0的軟鏈接,這是動態庫的命名規範的一種公約,我們只要在/opt/目錄下建立一個名為libmp3lame.so.0的到/opt/libmp3lame.so.0.0.0的軟鏈接就OK了:
[root@localhost opt]# ls libmp3lame.so.0.0.0 [root@localhost opt]# ln -s libmp3lame.so.0.0.0 libmp3lame.so.0 [root@localhost opt]# ll total 316 lrwxrwxrwx. 1 root root 19 Dec 7 23:27 libmp3lame.so.0 -> libmp3lame.so.0.0.0 -rwxr-xr-x. 1 root root 321228 Dec 7 23:25 libmp3lame.so.0.0.0 [root@localhost opt]# ldd /usr/local/bin/ffmpeg linux-gate.so.1 => (0x00cc4000) libavdevice.so.54 => /usr/local/lib/libavdevice.so.54 (0x00577000) libavfilter.so.3 => /usr/local/lib/libavfilter.so.3 (0x00e3f000) libavformat.so.54 => /usr/local/lib/libavformat.so.54 (0x00202000) libavcodec.so.54 => /usr/local/lib/libavcodec.so.54 (0x00f01000) libpostproc.so.52 => /usr/local/lib/libpostproc.so.52 (0x00170000) libswresample.so.0 => /usr/local/lib/libswresample.so.0 (0x00750000) libswscale.so.2 => /usr/local/lib/libswscale.so.2 (0x0035e000) libavutil.so.52 => /usr/local/lib/libavutil.so.52 (0x005ba000) libm.so.6 => /lib/libm.so.6 (0x00452000) libpthread.so.0 => /lib/libpthread.so.0 (0x001c0000) libc.so.6 => /lib/libc.so.6 (0x008c2000) libasound.so.2 => /lib/libasound.so.2 (0x0047c000) libdc1394.so.22 => /usr/local/lib/libdc1394.so.22 (0x003d6000) librt.so.1 => /lib/librt.so.1 (0x00db3000) libfreetype.so => /usr/local/lib/libfreetype.so (0x00a80000) libass.so.4 => /usr/local/lib/libass.so.4 (0x001db000) libssl.so.1.0.0 => /usr/local/lib/libssl.so.1.0.0 (0x005e7000) libcrypto.so.1.0.0 => /usr/local/lib/libcrypto.so.1.0.0 (0x00afb000) librtmp.so.0 => /usr/local/lib/librtmp.so.0 (0x00584000) libz.so.1 => /lib/libz.so.1 (0x00599000) libx264.so.132 => /usr/local/lib/libx264.so.132 (0x02bc9000) libvorbisenc.so.2 => /usr/local/lib/libvorbisenc.so.2 (0x05ccd000) libvorbis.so.0 => /usr/local/lib/libvorbis.so.0 (0x00640000) libvo-aacenc.so.0 => /usr/local/lib/libvo-aacenc.so.0 (0x00834000) libtwolame.so.0 => /usr/local/lib/libtwolame.so.0 (0x00668000) libtheoraenc.so.1 => /usr/local/lib/libtheoraenc.so.1 (0x00688000) libtheoradec.so.1 => /usr/local/lib/libtheoradec.so.1 (0x006ce000) libspeex.so.1 => /usr/local/lib/libspeex.so.1 (0x00815000) libmp3lame.so.0 => /opt/libmp3lame.so.0 (0x00767000) //終於圓滿了:) libfaac.so.0 => /usr/local/lib/libfaac.so.0 (0x006e8000) /lib/ld-linux.so.2 (0x003b6000) libdl.so.2 => /lib/libdl.so.2 (0x001f4000) libraw1394.so.11 => /usr/local/lib/libraw1394.so.11 (0x00444000) libfribidi.so.0 => /usr/local/lib/libfribidi.so.0 (0x006f8000) libfontconfig.so.1 => /usr/local/lib/libfontconfig.so.1 (0x00710000) libogg.so.0 => /usr/local/lib/libogg.so.0 (0x001f9000) libexpat.so.1 => /lib/libexpat.so.1 (0x007e3000)
所以說,針對動態庫路徑查找的種種問題,無非就這麽兩大類,關鍵是找對原因,對癥下藥,方能藥到病除。
談談Linux下動態庫查找路徑的問題