1. 程式人生 > >linux下添加動態鏈接庫路徑、動態庫加載等方法

linux下添加動態鏈接庫路徑、動態庫加載等方法

文件 -c 指定 時有 歸檔 最好 開始 動態 SM

linux下添加動態鏈接庫路徑的方法

2017年01月20日 10:08:17 閱讀數:5596 Linux共享庫路徑配置

  Linux下找不到共享庫文件的典型現象為明明已經安裝某個軟包(如libnet,MySQL),編譯連接可以正常進行,但是在運行時出現如“error while loading shared libraries: libnet.so.1:cannot open shared object file :No such file or directory”的錯誤提示。

  原因是Linux下的共享庫路徑配置不正確。默認的linux共享庫搜索路徑為/lib和/usr/lib兩個目錄(不包含子目錄),若共享庫不在這兩個路徑,不能自動連接到(最典型的就是/usr/local/lib)。

解決方法有五種:

1,連接時使用靜態庫(.a文件)。在g++命令上寫入該.a文件的完整路徑。

2,使用LD_LIBRARY_PATH環境變量。(臨時有效,且有時候沒有效果),把需要添加的路徑加入到LD_LIBRARY_PATH中,註意如果多於一個要用冒號隔開。如:export LD_LIBRARY_PATH=/usr/local/lib/minigui

3,將動態庫文件復制到可以搜索到的路徑(一般是系統默認的路徑,如/lib、/usr/lib)裏面,這樣比較狠,但是可能導致一些後即問題。

4,編譯的時候設定:在編譯源碼的時候可以用參數:-Wl, -rpath指定動態搜索的路徑即可。

5,修改系統文件/etc/ld.so.conf,添加路徑,運行ldconfig命令。

第五種方法的說明如下:

在/etc/ld.so.conf文件中指定了默認的動態鏈接庫查找路徑,我的/etc/ld.so.conf文件內容是這樣的include /etc/ld.so.conf.d/*.conf。也就是說它間接的指定了定義路徑的文件,我們只需要把需要的路徑加到/etc/ld.so.conf.d目錄下的任何一個文件中,再運行ldconfig就可以了,但為了容易理解,最好是找一個相關的文件,或者重新建立一個文件,把需要添加的路徑寫入然後運行ldconfig

ldconfig幾個需要註意的地方
1. 往/lib和/usr/lib裏面加東西,是不用修改/etc/ld.so.conf的,但是完了之後要調一下ldconfig,不然這個library會找不到
2. 想往上面兩個目錄以外加東西的時候,一定要修改/etc/ld.so.conf,然後再調用ldconfig,不然也會找不到

PS

1、linux庫文件分為靜態庫和動態庫兩種。靜態庫習慣以.a 結尾,而動態庫習慣以.so(shared object)結尾。而且必須以lib開頭。

2、靜態庫的原則是“以空間換時間”,增加程序體積,減少運行時間;

生成:在編譯時候,先生成目標文件.o,然後用ar文件對目標文件歸檔,生成靜態庫文件。

例如:ar -rc libtest.a myalib.o (註意:ar -rc 目標 .o文件名),目標一定要以lib開頭。

3、使用時候,在鏈接時候,加上選項 -l 後接庫文件名,註意:必須是文件名去掉後綴和lib,
如:gcc -o main main.o -ltest 。而且-ltest必須放在main.o的後面,(規則是,越底層的庫越要放在後面)。

4、gcc的其他常用的選項,

-c 編譯成目標文件 如:gcc -c main.c 就是編譯main.c成目標文件main.o

-I 頭文件的查找路徑,如:gcc -c main.c -I./inc 意思是:頭文件的查找路徑除了默認的之外,再加上./inc目錄下的。

-L 庫文件的查找路徑,如:gcc -o main main.o -L./lib -ltest 說明:libtest.a 或者 libtest.so 庫文件的查找路徑除了默認之外,再加上./lib目錄。

-MM 導出文件的依賴關系(用#include 中的內容)如:gcc -MM main.c找出main.c的所依賴的頭文件

-o 生成最終目標

-D宏定義 相當於在C中些語句#define ... 如:-DPI=3.14 就相當於在文件裏面寫語句#define PI 3.14

5、動態庫

(1)、生成:在鏈接時,用如下選項:-shared -fpic 如: gcc -fpic -shared -o libtest.so myalib.c

(2)、使用:有隱式使用和顯示使用,隱式使用就是共享方式,程序一開始運行就調進去。在鏈接時候用如下:
gcc -o main main.o -L./lib -ltest(像靜態庫的一樣)

顯示使用就是在程序中用語句把動態庫調進來,用系統調用:dlopen、dlsym、dlerror、dlclose函數,那樣在編譯鏈接時候,不用加上:-L./lib -ltest了。不過要使用dl*系列函數在編譯鏈接時要加上 -ldl

6、如果同一目錄下,既有靜態庫也有動態庫,比如libtest.a libtest.so都存在,那麽dl程序(等一下介紹)就把動態庫調進去,沒有動態的,就找靜態的。再沒有,就報錯。

7、動態庫的搜索路徑

dl對動態庫的搜索路徑如下(按順序如下)

a.編譯目標代碼時指定的動態庫搜索路徑;(如果要指定程序行時在./lib目錄下找庫文件libtest.so,命令如下:gcc -o main main.c -L./lib -ltest -Wl,-rpath ./lib) ,其中,-Wl的意思是,後面的選項直接交給ld程序處理,-rpath選項是說更改搜索路徑為後面的參數./lib

b.環境變量LD_LIBRARY_PATH指定的動態庫搜索路徑;

c.配置文件/etc/ld.so.conf中指定的動態庫搜索路徑;(修改完文件後,用ldconfig更新)

d.默認的動態庫搜索路徑/lib和/usr/lib;

8、一些常用的命令(與庫有關的)

(1)、ld 是gcc的鏈接程序。

(2)、ldd是查看可執行文件中所依賴的庫的程序,比如想查main程序用到了那些動態庫,可以直接
ldd main

(3)、ldconfig用來更新文件/etc/ld.so.conf的修改生效。

(4)、nm用來查看.so庫中的函數名字,標記是T的就是動態庫裏面生成的名字。如:nm /lib/libc*.so

linux下添加動態鏈接庫路徑、動態庫加載等方法