linux LD_LIBRARY_PATH环境变量
linux?LD_LIBRARY_PATH環(huán)境變量
(2011-09-22 17:59:35) 轉(zhuǎn)載▼標簽: 雜談 | 分類:技術(shù)文章 |
版權(quán)聲明:轉(zhuǎn)載時請以超鏈接形式標明文章原始出處和作者信息及本聲明
http://skatings.blogbus.com/logs/50437681.html
linux共享庫位置配置(LD_LIBRARY_PATH環(huán)境變量 或者 更改/etc/ld.so.conf 或者使用-R選項)
?
今天下午嘗試使用libosip2,安裝比較簡單,按照自帶的help文檔里面的操作進行即可。
$>mkdir linux-build?
$>cd linux-build
$>../libosip2-2.2.0/configure
$>make ? ?? ? ?? ? ?? ? ?? ?(最后2步要在管理員權(quán)限下執(zhí)行)
# make install?
完成之后,會在/usr/local/lib路徑下生成一些lioosipXXX.so的文件,在/usr/local/include下生成關(guān)于osip的頭文件。
為了測試安裝是否正確,在eclipse下建了個測試項目,寫了很簡單的代碼:
#include<sys/time.h>//不加的話,編譯時會報錯,可能osip依賴于time.h
#include <osip2/osip.h>
//之所以能找到/usr/local/include下關(guān)于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?關(guān)于頭文件說明
?
#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-->Toolsettings-->GCC C++Linker-->Libraries加上-lpthread -losip2的選項。
編譯鏈接都沒有問題,運行時報錯:
error while loading shared libraries: libosip2.so.4: cannot openshared object file: No such file or directory
?
然后查到可能是因為共享庫設(shè)置的問題:
下面的幾段是轉(zhuǎn)載的,看了之后明白linux怎么找到共享庫的
===========================================================================================
Linux 運行的時候,是如何管理共享庫(*.so)的?在 Linux 下面,共享庫的尋找和加載是由 /lib/ld.so實現(xiàn)的。 ld.so 在標準路經(jīng)(/lib, /usr/lib) 中尋找應(yīng)用程序用到的共享庫。
但是,如果需要用到的共享庫在非標準路經(jīng),ld.so 怎么找到它呢?
目前,Linux 通用的做法是將非標準路經(jīng)加入 /etc/ld.so.conf,然后運行 ldconfig 生成/etc/ld.so.cache。 ld.so 加載共享庫的時候,會從 ld.so.cache 查找。
傳統(tǒng)上,Linux 的先輩 Unix 還有一個環(huán)境變量:LD_LIBRARY_PATH 來處理非標準路經(jīng)的共享庫。ld.so加載共享庫的時候,也會查找這個變量所設(shè)置的路經(jīng)。
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里面加?xùn)|西,是不用修改/etc/ld.so.conf的,但是完了之后要調(diào)一下ldconfig,不然這個library會找不到
2.想往上面兩個目錄以外加?xùn)|西的時候,一定要修改/etc/ld.so.conf,然后再調(diào)用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中加?xùn)|西(或者是沒有權(quán)限加?xùn)|西)。那也可以,就是export一個全局變量LD_LIBRARY_PATH,然后運行程序的時候就會去這個目錄中找library。一般來講這只是一種臨時的解決方案,在沒有權(quán)限或臨時需要的時候使用。
4. ldconfig做的這些東西都與運行程序時有關(guān),跟編譯時一點關(guān)系都沒有。編譯的時候還是該加-L就得加,不要混淆了。
5.總之,就是不管做了什么關(guān)于library的變動后,最好都ldconfig一下,不然會出現(xiàn)一些意想不到的結(jié)果。不會花太多的時間,但是會省很多的事。
LD_LIBRARY_PATH這個環(huán)境變量是大家最為熟悉的,它告訴loader:在哪些目錄中可以找到共享庫。可以設(shè)置多個搜索目錄,這些目錄之間用冒號分隔開。在linux下,還提供了另外一種方式來完成同樣的功能,你可以把這些目錄加到/etc/ld.so.conf中,然后調(diào)用ldconfig。當然,這是系統(tǒng)范圍內(nèi)全局有效的,而環(huán)境變量只對當前shell有效。按照慣例,除非你用上述方式指明,loader是不會在當前目錄下去找共享庫的,正如shell不會在當前目前找可執(zhí)行文件一樣。
================================================================================================
?
在shell下嘗試設(shè)置LD_LIBRARY_PATH,以下面這種形式設(shè)置,老是報錯bash: LD_LIBRARY_PATH:command not found,
LD_LIBRARY_PATH=/usr/local/lib
LD_LIBRARY_PATH = $ LD_LIBRARY_PATH:/usr/local/lib
可能是因為系統(tǒng)之前沒有設(shè)置過LD_LIBRARY_PATH,于是改成這樣:
export LD_LIBRARY_PATH=/usr/local/lib
然后用 echo $LD_LIBRARY_PATH檢查一下是否真的設(shè)置成功,發(fā)現(xiàn)可以。
接著在該shell下運行eclipse生成的可執(zhí)行文件,沒有錯誤。
?
另外,如果不想每次新啟一個shell都設(shè)置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 就行了。-----------------------------------------------------------
前些天在配置通過OCI的方式連接Oracle中曾進碰到一個關(guān)于“java.lang.UnsatisfiedLinkError: noXXX in java.library.path”這么一個問題,這個問題糾結(jié)了許久才解決,解決方式參考前面的文章。 趁雙休日好好的理解一下產(chǎn)生這個問題的來龍去脈。 先看一段話先:
PATH is the environment variable.
java.library.path is the system properties.
When the java application started, JVM will set java.library.path’svalue using PATH’s value.
In java program, it’s very difficult to get the value ofenvironment variables, but it’s very easy to get/set systemproperties. Use System.getProperty(”project_root”, “..”);
System.setProperty(”project_root”, “..”); java.libaray.path 是systemproperties,在windows系統(tǒng)通常是使用PATH的值,而在Linux上是用LD_LIBRARY_PATH的值。隨便也說一下java.class.path,他是對應(yīng)于CLASSPATH中的值。
那LD_LIBRARY_PATH的值主要是干什么呢?他是來處理非標準路徑下的”共享庫“的,可以理解成windows的dll,但在linux下是*.so的文件。 說完了基本的概念,再來看看OCI是怎么連接Oracle的,其實OCI是通過JNI(java nativeinterface)的方式來訪問Oracle的,請看下圖
1)我們知道Oracle的驅(qū)動是classes12.jar(ojdbc14.jar),這里應(yīng)該對應(yīng)著java-class;
2) 同樣我們在JBOSS啟動腳本中設(shè)置?JBOSS_NATIVE_DIR=”/opt/instantclient_10_2″,其實就是將LD_LIBRARY_PATH=”/opt/instantclient_10_2″,而在這個目錄下有大量的*.so文件,這些應(yīng)該對應(yīng)native;
3)至于jni-stub是一些存根文件,可以參考一下JNI相關(guān)的說明,這里就暫不描述了(有時間可以再深入學(xué)習(xí))。
本文出自 “螞蟻神相”博客,轉(zhuǎn)載請與作者聯(lián)系!
?
但是在安裝BDB后,設(shè)置完LD_LIBRARY_PATH到bdb的lib目錄后,用java訪問還是一直報no db_java-soin java.library.path,沒有辦法最后只好在啟動java程序時加上-Djava.library.path=/usr/local/BerkeleyDB.4.7/lib才訪問成功,可能與我的類加載機制有問題吧(自己做的類加載)。總結(jié)
以上是生活随笔為你收集整理的linux LD_LIBRARY_PATH环境变量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 本周开课 | 第 5 期全基因组/外显子
- 下一篇: 中国中医科学院院长黄璐琦发表2022年新