[轉] linux共享库位置配置(LD_LIBRARY_PATH环境变量 或者 更改/etc/ld.so.conf 或者 使用-R选项)

出處:http://skatings.blogbus.com/logs/50437681.html

版權聲明:轉載時請以超鏈接形式標明文章原始出處和作者信息及本聲明
http://skatings.blogbus.com/logs/50437681.html
linux共享庫位置配置(LD_LIBRARY_PATH環境變量或者更改/etc/ld.so.conf 或者使用-R選項)
今天下午嘗試使用libosip2,安裝比較簡單,按照自帶的help文檔裡面的操作進行即可。
$>mkdir linux-build 
$>cd linux-build
$>../libosip2-2.2.0/configure
$>make (最後2步要在管理員權限下執行)
# make install 
完成之後,會在/usr/local/lib路徑下生成一些lioosipXXX.so的文件,在/usr/local/include下生成關於osip的頭文件。
為了測試安裝是否正確,在eclipse下建了個測試項目,寫了很簡單的代碼:
#include <sys/time.h>//不加的話,編譯時會報錯,可能osip依賴於time.h
#include <osip2/osip.h>
//之所以能找到/usr/local/include下關於osip的頭文件,是因為eclipse默認把/usr/local/include放到Include directories裡面了。在eclipse的項目屬性–>C++ General–>Path and symbols –>Include裡面可以看到。如果自己寫makefile文件的話,要加上-I 選項,表示程序裡include的頭文件去哪裡找。參見
http://blog.csdn.net/liuzhuan_1986/archive/2009/07/05/4323274.aspx  關於頭文件說明
#include <iostream>
using namespace std;
int main()
{
int i;
osip_t *osip;
i = osip_init(&osip);
if(i != 0)
cout << “error” << endl;
cout << “ok” << endl;
return 0;
}
並且在eclipse的項目屬性–>C/C++ Build–>Settings–>Tool settings–>GCC C++ Linker–>Libraries加上-lpthread -losip2的選項。
編譯鏈接都沒有問題,運行時報錯:
error while loading shared libraries: libosip2.so.4: cannot open shared object file: No such file or directory
然後查到可能是因為共享庫設置的問題:
下面的幾​​段是轉載的,看了之後明白linux怎麼找到共享庫的
================================================== =========================================
Linux 運行的時候,是如何管理共享庫(*.so)的?在Linux 下面,共享庫的尋找和加載是由/lib/ld.so 實現的。ld.so 在標準路經(/lib, /usr/lib) 中尋找應用程序用到的共享庫。
但是,如果需要用到的共享庫在非標準路經,ld.so 怎麼找到它呢?
目前,Linux 通用的做法是將非標準路經加入/etc/ld.so.conf,然後運行ldconfig 生成/etc/ld.so.cache。ld.so 加載共享庫的時候,會從ld.so.cache 查找。
傳統上,Linux 的先輩Unix 還有一個環境變量:LD_LIBRARY_PATH 來處理非標準路經的共享庫。ld.so 加載共享庫的時候,也會查找這個變量所設置的路經。
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./lib
export LD_LIBRARY_PATH
但是,有不少聲音主張要避免使用LD_LIBRARY_PATH 變量,尤其是作為全局變量。這些聲音是:
* LD_LIBRARY_PATH is not the answer – http://prefetch.net/articles/linkers.badldlibrary.html
* Why LD_LIBRARY_PATH is bad – http://xahlee.org/UnixResource_dir/_/ldpath.html 
* LD_LIBRARY_PATH – just say no – http://blogs.sun.com/rie/date/20040710
解決這一問題的另一方法是在編譯的時候通過-R<path> 選項指定run-time path。
1. 往/lib和/usr/lib裡面加東西,是不用修改/etc/ld.so.conf的,但是完了之後要調一下ldconfig,不然這個library會找不到
2. 想往上面兩個目錄以外加東西的時候,一定要修改/etc/ld.so.conf,然後再調用ldconfig,不然也會找不到。
比如安裝了一個mysql到/usr/local/mysql,mysql有一大堆library在/usr/local/mysql/lib下面,這時就需要在/etc/ld.so.conf下面加一行/usr/local/ mysql/lib,保存過後ldconfig一下,新的library才能在程序運行時被找到。
3. 如果想在這兩個目錄以外放lib,但是又不想在/etc/ld.so.conf中加東西(或者是沒有權限加東西)。那也可以,就是export一個全局變量LD_LIBRARY_PATH,然後運行程序的時候就會去這個目錄中找library。一般來講這只是一種臨時的解決方案,在沒有權限或臨時需要的時候使用。
4. ldconfig做的這些東西都與運行程序時有關,跟編譯時一點關係都沒有。編譯的時候還是該加-L就得加,不要混淆了。
5. 總之,就是不管做了什麼關於library的變動後,最好都ldconfig一下,不然會出現一些意想不到的結果。不會花太多的時間,但是會省很多的事。
LD_LIBRARY_PATH 這個環境變量是大家最為熟悉的,它告訴loader:在哪些目錄中可以找到共享庫。可以設置多個搜索目錄,這些目錄之間用冒號分隔開。在linux下,還提供了另外一種方式來完成同樣的功能,你可以把這些目錄加到/etc/ld.so.conf中,然後調用ldconfig。當然,這是系統範圍內全局有效的,而環境變量只對當前shell有效。按照慣例,除非你用上述方式指明,loader是不會在當前目錄下去找共享庫的,正如shell不會在當前目前找可執行文件一樣。
================================================== ==============================================
在shell下嘗試設置LD_LIBRARY_PATH,以下面這種形式設置,老是報錯bash: LD_LIBRARY_PATH: command not found,
LD_LIBRARY_PATH=/usr/local/lib
LD_LIBRARY_PATH = $ LD_LIBRARY_PATH:/usr/local/lib
可能是因為系統之前沒有設置過LD_LIBRARY_PATH,於是改成這樣:
export LD_LIBRARY_PATH=/usr/local/lib
然後用echo $LD_LIBRARY_PATH檢查一下是否真的設置成功,發現可以。
接著在該shell下運行eclipse生成的可執行文件,沒有錯誤。
另外,如果不想每次新啟一個shell都設置LD_LIBRARY_PATH,可以編輯~/.bash_profile文件:
$ vi ~/.bash_profile 
添加:
LD_LIBRARY_PATH=/usr/local/lib
export LD_LIBRARY_PATH
這兩行,完成之後.bash_profile如下所示:
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
LD_LIBRARY_PATH=/usr/local/lib
export PATH
export LD_LIBRARY_PATH
然後運行
$ source ~/.bash_profile 就行了。
但是這種方法只能用在shell下,想在eclipse裡面運行,還是不行:
嘗試了eclipse項目properties裡面的各種設置都不起作用。
用“eclipse LD_LIBRARY_PATH”作為關鍵字(可見關鍵字多麼重要)才搜到這麼篇文章《eclipse+cdt+gcc編譯選項控制》 http://hi.baidu.com/zsffei/blog/item/7b17c043ceb51e1772f05de1.html
才知道應該在eclipse的項目屬性–>C/C++ Build–>Settings–>Tool settings–>GCC C++ Linker–>Miscellaneous的Other options (-Xlinker [option])添加-R/usr/ local/lib
運行,一切正常,折騰了一下午,太感動了。
未經允許不得轉載:GoMCU » [轉] linux共享库位置配置(LD_LIBRARY_PATH环境变量 或者 更改/etc/ld.so.conf 或者 使用-R选项)