1. 程式人生 > >動態庫使用的幾個注意點

動態庫使用的幾個注意點

一、“--export-dynamic”引數的使用

GCC編譯可執行檔案時可以使用-Wl,--export-dynamic引數,此時連結器產生可執行檔案時會將所有全域性符號匯出到動態符號表。

gcc -Wl,--export-dynamic -o p1 p1.c -L. -l0

如果在建立動態連結的可執行檔案不加-Wl,--export-dynamic選項,則它所export的動態符號僅僅包括在連結時動態物件所用到的。因為dlopen是自行載入動態庫,並不存在與可執行檔案動態符號解析的過程,所以如果dlopen載入的動態庫使用了主模組中定義的函式,則會出現找不到符號的情況。

預設連結器在產生可執行檔案時,只會將那些連結時被其他共享模組引用到的符號放到動態符號表中,這樣可以減少動態

符號表的大小,也就是說,在共享模組中反向引用主模組中的符號時,只有那些在連結時被共享模組引用到的符號才會被匯出。(主模組的符號表中依賴的共享模組主模組才會去連結,否則不會去連結,不被連結的模組引用了主模組的符號就不會被匯出到動態符號表中,導致執行時報錯)。

但是使用--export-dynamic引數後由於將所有的全域性符號匯出到動態符號表中導致可執行程式會變大。

二、strip清除符號資訊

正常情況下編譯出來的共享庫和可執行檔案中都帶有符號資訊和除錯資訊,但是釋出版本一般不需要這些資訊。且這些資訊會導致可執行檔案大一倍多,所以可以使用strip命令去掉除錯資訊:strip liba.so

ld的“-S”和“-s”也能使連結器輸出的可執行檔案不產生除錯資訊,“-S”消除除錯符號資訊,“-s”消除所有符號資訊。

gcc -WI,-s a.out或gcc -WI,-S a.out

三、共享庫的安裝部署

1、設定環境變數LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/home/work/deal/dynamic

export LD_LIBRARY_PATH=$(pwd)

2、使用連結器的“-rpath”選項,可以指定連結器產生的目標檔案的共享庫查詢路徑。

ld -rpath /home/lib -o a.out a.o -lc

這樣引數的a.out首先會在/home/lib目錄下查詢共享庫,可以使用“-L”,“-l”分別指定共享庫的搜尋目錄和共享庫的名稱。

3、將共享庫複製到共享目錄中/lib /usr/lib然後執行ldconfig即可。需要root才能有許可權往lib下拷貝檔案和執行ldconfig

4、建立相應的SO-NAME軟連結

GCC可以使用“-WI,-soname,my_soname”引數將my_soname傳遞給連結器,用來指定輸出共享庫的SO-NAME,如:

gcc -shared -WI,-soname,my_soname -o a.so a.c -lc

如果不使用-soname指定共享庫的SO-NAME,那麼預設共享庫就沒有SO-NAME,即使用ldconfig更新SO-NAME的軟連結時,對該庫也沒有效果。

使用ldconfig更新SO-NAME的軟連結命令:

ldconfig -n /home/lib