linux下新增動態庫鏈結的方法

2021-08-17 03:22:08 字數 2983 閱讀 4985

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、動態庫

(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下鏈結動態庫靜態庫的理解

linux程式gcc編譯基本過程 乙個程式從原始碼到可執行檔案 或共享庫檔案 一般都要經過預處理 編譯 彙編和鏈結這四個步驟。編譯過程掃瞄標頭檔案的搜尋路徑順序 gcc 在編譯時如何去尋找所需要的標頭檔案 所以header file的搜尋會從 i開始 然後找gcc的環境變數 c include pa...

Linux 編譯靜態鏈結庫與動態鏈結庫的方法

hello.c include int main int argc,char argv 1 編譯生成可執行檔案 gcc o test hello.c 2 編譯生成目標檔案 gcc c o test.o hello.c string.c define endstring 0 int strlen ch...

linux下的動態鏈結庫 DLL

一 公約 1.庫的命名習慣 乙個linux dll 有三個不同名字的檔案組成 soname 檔案 lib 鏈結庫名字 so 版本號 每當鏈結庫介面改變時都遞增版本號。soname 檔案其實只是乙個符號鏈結而已,指向他的real name 檔案。real name 檔案 lib 鏈結庫名字 so 版本...