Linux 運行的時候,是如何管理共享庫(*.so)的?在 Linux 下面,共享庫的尋找和加載是由 /lib/ld.so 實現的。 ld.so 在標準路經(/lib, /usr/lib) 中尋找應用程序用到的共享庫。html
可是,若是須要用到的共享庫在非標準路經,ld.so 怎麼找到它呢?mysql
目前,Linux 通用的作法是將非標準路經加入 /etc/ld.so.conf,而後運行 ldconfig 生成 /etc/ld.so.cache。 ld.so 加載共享庫的時候,會從 ld.so.cache 查找。linux
傳統上,Linux 的先輩 Unix 還有一個環境變量:LD_LIBRARY_PATH 來處理非標準路經的共享庫。ld.so 加載共享庫的時候,也會查找這個變量所設置的路經。sql
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./libshell
export LD_LIBRARY_PATHbash
可是,有很多聲音主張要避免使用 LD_LIBRARY_PATH 變量,尤爲是做爲全局變量。這些聲音是:eclipse
* LD_LIBRARY_PATH is not the answer - http://prefetch.net/articles/linkers.badldlibrary.htmlfetch
* Why LD_LIBRARY_PATH is bad - http://xahlee.org/UnixResource_dir/_/ldpath.html ui
* LD_LIBRARY_PATH - just say no - http://blogs.sun.com/rie/date/20040710spa
解決這一問題的另外一方法是在編譯的時候經過 -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
可是這種方法只能用在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
運行,一切正常,折騰了一下午,太感動了。