Linux下如何解決動態庫的鏈接問題

    關於動態庫和靜態庫,這裏不多解釋,如何創建屬於自己的動態庫和靜態庫,之前有提過,詳細內容戳鏈接


    靜態庫是一種以空間換取時間和移植性的做法,一些情況下確實有着一定的意義,但是一些情況下,我們自己編寫的簡單項目,在絕大多數的機器上不存在移植性問題,是沒有必要採用靜態編譯的。而且,在一些大型項目中,我們很難避免去使用到開源庫,舉個例子,如果我們只是單純引用了mysql數據庫的幾個接口,有必要將整個mysql源文件全部編譯嗎?代價未免太大。通常的做法,是將mysql的include

和lib目錄打包之後,一起進行發佈,來增強可移植性,也就是今天這裏說的動態編譯。


    但是,動態編譯默認情況下,只會去系統默認指定的目錄下進行查找lib***.so文件,甚至我們在Makefile中使用-L選項指明瞭LIB目錄,編譯不會出錯,但在運行的時候,會出現下面這種報錯:

    

./cgi_select: error while loading shared libraries: libmysqlclient.so.18: 
    cannot open shared object file: No such file or directory


    解決這個問題,網上給出的方法挺多,這裏不會全部列出,給出最常用的方法:

1、環境變量。使用export導入環境變量LD_LIBRARY_PATH,指明搜索路徑。這個環境變量是臨時指定動態庫的搜索路徑,是綁定終端的,至於什麼原因,瞭解過Linux的同學應該知道,這裏不多解釋,爲了說明問題,這裏截圖給出,具體用法如下:

wKiom1kg-smzgGqsAABZaxT8YqE573.png


    再次說明,這種做法只是臨時生效,在測試的時候爲了方便可以使用,但是真正的項目發佈,一般不會使用這種做法,因爲需要在客戶機器上創建環境變量之後纔可以運行,我嘗試了多種做法,想把命令放到腳本當中自動化去執行,但限於個人能力,尚未跨越子shell這一關。


2、第二種做法就顯得更加有效。在/etc/ld.so.conf文件中,指明瞭動態庫的搜索路徑,一般請款下,文件內容爲

include ld.so.conf.d/*.conf

表明,/etc/ld.so.conf.d目錄下的所有*.conf文件中保存的都是動態庫的搜索路徑。這麼說可能不太好理解,進入目錄,隨意打開一個文件,你就會明白,每個文件中只有一條或幾條路徑,如下

[root@bogon ld.so.conf.d]# cat qt-i386.conf 
/usr/lib/qt-3.3/lib
[root@bogon ld.so.conf.d]# cat mysql-i386.conf
/usr/lib/mysql

    每一個工具的動態庫,都有着自己的動態庫路徑,因此,我們可以在該目錄下創建自己的*.conf文件,文件中保存自己指定的動態庫路徑即可,個人絕對,Linux對動態庫搜索路徑的封裝做的真心不錯。

    當然更改其他*.conf文件或創建自己的動態庫連接目錄配置文件後,需要使用ldconfig命令使之生效。

[root@bogon ld.so.conf.d]# ldconfig 


3、其他的做法就是一些很非主流的做法了,將你所需要的動態庫文件直接放入系統默認路徑,坦白講,這樣做法沒有問題,但是這是在給自己埋地雷,遲早有一天會出大問題。


4、另外還有一種比較生僻的做法,但是開源工程中會用到。使用gcc的選項確實可以實現,-Wl -rpath指定路徑,個人來說,很少使用這種做法,gcc/g++是一款很強大的編譯工具,提供了上百個選項,有一大部分可能一輩子用不到,用到去查就可以了,沒有必要太過深究。



    -----muhuizz整理








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章