linux LD_LIBRARY_PATH环境变量
linux?LD_LIBRARY_PATH環境變量
(2011-09-22 17:59:35) 轉載▼標簽: 雜談 | 分類:技術文章 |
版權聲明:轉載時請以超鏈接形式標明文章原始出處和作者信息及本聲明
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-->Toolsettings-->GCC C++Linker-->Libraries加上-lpthread -losip2的選項。
編譯鏈接都沒有問題,運行時報錯:
error while loading shared libraries: libosip2.so.4: cannot openshared 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 就行了。-----------------------------------------------------------
前些天在配置通過OCI的方式連接Oracle中曾進碰到一個關于“java.lang.UnsatisfiedLinkError: noXXX in java.library.path”這么一個問題,這個問題糾結了許久才解決,解決方式參考前面的文章。 趁雙休日好好的理解一下產生這個問題的來龍去脈。 先看一段話先:
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系統通常是使用PATH的值,而在Linux上是用LD_LIBRARY_PATH的值。隨便也說一下java.class.path,他是對應于CLASSPATH中的值。
那LD_LIBRARY_PATH的值主要是干什么呢?他是來處理非標準路徑下的”共享庫“的,可以理解成windows的dll,但在linux下是*.so的文件。 說完了基本的概念,再來看看OCI是怎么連接Oracle的,其實OCI是通過JNI(java nativeinterface)的方式來訪問Oracle的,請看下圖
1)我們知道Oracle的驅動是classes12.jar(ojdbc14.jar),這里應該對應著java-class;
2) 同樣我們在JBOSS啟動腳本中設置?JBOSS_NATIVE_DIR=”/opt/instantclient_10_2″,其實就是將LD_LIBRARY_PATH=”/opt/instantclient_10_2″,而在這個目錄下有大量的*.so文件,這些應該對應native;
3)至于jni-stub是一些存根文件,可以參考一下JNI相關的說明,這里就暫不描述了(有時間可以再深入學習)。
本文出自 “螞蟻神相”博客,轉載請與作者聯系!
?
但是在安裝BDB后,設置完LD_LIBRARY_PATH到bdb的lib目錄后,用java訪問還是一直報no db_java-soin java.library.path,沒有辦法最后只好在啟動java程序時加上-Djava.library.path=/usr/local/BerkeleyDB.4.7/lib才訪問成功,可能與我的類加載機制有問題吧(自己做的類加載)。總結
以上是生活随笔為你收集整理的linux LD_LIBRARY_PATH环境变量的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 本周开课 | 第 5 期全基因组/外显子
- 下一篇: Linux 动态库的显示调用