linux 下 奇怪的 動態庫 依賴問題

2021-09-06 13:05:34 字數 2569 閱讀 6348

**

總結如下:

1)當你在編譯生成靜態庫的時候, 只需要相應的依賴庫庫的標頭檔案即可. 只有在你想生成so,或可執行檔案 時, 才需要lib庫.

對於你沒有用到的lib, 但是不包含又編譯失敗, 那麼只包含其標頭檔案即可.

2)如果你同時使用了多個庫,而庫之間又相互依賴,那麼在鏈結是,把最底層的依賴庫放在最右側.否則可能會鏈結失敗

3)如果我已經把最底層的庫放在最後邊了,還是鏈結失敗怎麼辦?

請檢查是否依賴了同名的其他的庫. 自己檢視鏈結庫的路徑

對1)的說明

如果你不用該so, 那麼你就不要將他的lib放在你的makefile裡面! 否則執行時會依賴該so的.

案例:

我的cgi, cp到正式環境, 居然開始依賴 mysql的so, 奇怪, 我的專案中並無用到mysql. 然後,makefile中去掉mysql相關的 標頭檔案, 以及lib, 卻發現 沒有mysql的標頭檔案還編譯不過去, 因為我用的另乙個庫tlib用到了mysql, ****, 怎麼辦?

答案: 只把mysql的標頭檔案 路徑等加到 makefile裡面, 這樣gcc有了標頭檔案至少可以編譯過去. 然後, 在連線的時候, 由於你的**並沒有真正用到mysql, 所以不會去連線mysql相關的東東. 所以, 直接鏈結通過.

分析: 雖然tlib用到了mysql, 但是由於tlib是乙個非常龐大的靜態庫, 其裡面依賴的內容非常多, 而我只用到了tlib裡面的一小部分功能(且不含mysql), 所以, 我只需把mysql標頭檔案加上即可. 鏈結時時不會真正用到mysql的沒有lib. 除非我用到tlib裡面的相關mysql介面.

如果你想生成靜態庫:

linux下, 如果你的專案(是個靜態庫)的依賴某個庫(不管動態庫還是靜態庫), 當你在編譯生成靜態庫的時候, 只需要相應的依賴庫庫的標頭檔案即可.

(因為, linux的.a本身就是一堆.o的集合, .o也就是一堆cpp檔案的編譯結果, 並沒有開始執行鏈結)

舉例:libcomm.a 就是這樣, 雖然依賴的很多的庫, 比如html_template, mysql, markupstl, 但只需他們的標頭檔案即可.

used = \

markupstl \

netclientex \

html_template \

tlib \

inc  = \

$(foreach i, $(used), $(inc_$(i)))

#看到沒, lib 為空!!!

lib  = 

如果你想生成so,或可執行檔案

1)那麼你必須包含上你需要的lib, 而且, 如果你 通過 -l***, 那麼gcc預設後首先嘗試鏈結 ***的動態庫lib***.so.1(lib***.so.1是lib***.so的符號鏈結檔案, 並不是真正的lib***.so, 但是會指向lib***.so), 如果找不到lib***.so.1,然後尋找***的靜態庫lib***.a.

2)同時, 如果你沒有用到某個lib的話, 一定不要包含其lib, 如果編譯不通過, 最多隻需包含其標頭檔案即可.

就像我上面的案例一樣, 沒有用到mysql, 卻包含而來mysql的lib, 導致在執行機上找不到 mysql.so 而執行失敗, 去掉mysql的lib, 只保留mysql的 標頭檔案, 可以鏈結過去, 並且可以正常執行.

2)如果你同時使用了多個庫,而庫之間又相互依賴,那麼在鏈結是,把最底層的依賴庫放在最右側.否則可能會鏈結失敗

g++ -o $(target) liba libb libc

如果liba 依賴libb, libb依賴libc, 那麼請把libc放在最後面.

如果 g++ -o $(target) liba libc libb會導致libb的鏈結失敗. 

有一種情況離開,liba也依賴libc,並且依賴關係和libb對libc的依賴的介面一樣, 那麼把libc放在中間不會報錯,但最好不要這麼做.

3)如果我已經把最底層的庫放在最後邊了,還是鏈結失敗怎麼辦?

檢查是否連線到了相同名字的其他的庫.  我又一次就是如此,系統系統中存在多個network的庫, 雖然我把正確的network庫放在了最後面,但是由於其他庫包含路徑下也有老的同名的network庫,導致我鏈結失敗.

使用ldd命令來檢視執行檔案依賴於哪些庫。

該命令用於判斷某個可執行的 binary 檔案含有什麼動態函式庫。

[root@test root]# ldd [-vdr] [filename]

引數說明:

--version  列印ldd的版本號

-v --verbose  列印所有資訊,例如包括符號的版本資訊

-d --data-relocs  執行符號重部署,並報告缺少的目標物件(只對elf格式適用)

-r --function-relocs  對目標物件和函式執行重新部署,並報告缺少的目標物件和函式(只對elf格式適用)

--help 用法資訊。

如果命令列中給定的庫名字包含'/',這個程式的libc5版本將使用它作為庫名字;否則它將在標準位置搜尋庫。執行乙個當前目錄下的共享庫,加字首"./"。

linux下動態庫編譯的依賴問題

這裡主要是想試驗一下,對乙個具有多層巢狀的動態庫進行編譯時,是否要把最底層的庫也包含進來的問題,結論是 只要直接依賴的庫名稱,不需要最底層庫名稱。一,目錄結構 zzz add add.cpp add.h calc calc.cpp calc.h main main.cpp pkg pkg.cpp p...

Linux 檢視動態庫依賴

檢視動態庫依賴3種方法 1 ldd bin grep linux gate.so.1 0xffffe000 libc.so.6 lib libc.so.6 0xb7eca000 lib ld linux.so.2 0xb801e000 2 ld trace loaded objects 1 bin ...

linux 下 奇怪的

最近在做乙個從hp ux移行到linux 上面的專案,遇到乙個命令 hp ux date y m d h m s read sys date sys time dev null 2 1 但是這個命令在linux 下,就達不到預期的結果 之後問了高手,才得到解決辦法 linux read sys da...