和luster學習在Linux建立庫函式(4)(轉)

subid發表於2007-08-16
和luster學習在Linux建立庫函式(4)(轉)[@more@]3.4. 建立一個共享函式庫

現在我們開始學習如何建立一個共享函式庫。其實建立一個共享函式庫非常容易。首先建立object檔案,這個檔案將加入透過gcc –fPIC 引數命令加入到共享函式庫裡面。PIC的意思是“位置無關程式碼”(Position Independent Code)。下面是一個標準的格式:

gcc -shared -Wl,-soname,your_soname -o library_name file_list library_list

下面再給一個例子,它建立兩個object檔案(a.o和b.o),然後建立一個包含a.o和b.o的共享函式庫。例子中”-g”和“-Wall”引數不是必須的。

gcc -fPIC -g -c -Wall a.cgcc -fPIC -g -c -Wall b.cgcc -shared -Wl,-soname,liblusterstuff.so.1 -o liblusterstuff.so.1.0.1 a.o b.o -lc

下面是一些需要注意的地方:

· 不用使用-fomit-frame-pointer這個編譯引數除非你不得不這樣。雖然使用了這個引數獲得的函式庫仍然可以使用,但是這使得除錯程式幾乎沒有用,無法跟蹤除錯。

· 使用-fPIC來產生程式碼,而不是-fpic。

· 某些情況下,使用gcc 來生成object檔案,需要使用“-Wl,-export-dynamic”這個選項引數。通常,動態函式庫的符號表裡面包含了這些動態的物件的符號。這個選項在建立ELF格式的檔案時候,會將所有的符號加入到動態符號表中。可以參考ld的幫助獲得更詳細的說明。


3.5. 安裝和使用共享函式庫

一旦你了一個共享函式庫,你還需要安裝它。其實簡單的方法就是複製你的庫檔案到指定的標準的目錄(例如/usr/lib),然後執行ldconfig。
如果你沒有許可權去做這件事情,例如你不能修改/usr/lib目錄,那麼你就只好透過修改你的環境變數來實現這些函式庫的使用了。首先,你需要建立這些共享函式庫;然後,設定一些必須得符號連結,特別是從soname到真正的函式庫檔案的符號連結,簡單的方法就是執行ldconfig:

ldconfig -n directory_with_shared_libraries

然後你就可以設定你的LD_LIBRARY_PATH這個環境變數,它是一個以逗號分隔的路徑的集合,這個可以用來指明共享函式庫的搜尋路徑。例如,使用bash,就可以這樣來
啟動一個程式my_program:

LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH my_program

如果你需要的是過載部分函式,則你就需要建立一個包含需要過載的函式的object檔案,然後設定LD_PRELOAD環境變數。

通常你可以很方便的升級你的函式庫,如果某個API改變了,建立庫的程式會改變soname。然而,如果一個函式升級了某個函式庫而保持了原來的soname,你可以強行將老版本的函式庫複製到某個位置,然後重新命名這個檔案(例如使用原來的名字,然後後面加.orig字尾),然後建立一個小的“wrapper”指令碼來設定這個庫函式和相關的東西。例如下面的例子:

#!/bin/sh export LD_LIBRARY_PATH=/usr/local/my_lib:$LD_LIBRARY_PATH exec /usr/bin/my_program.orig $*

我們可以透過執行ldd來看某個程式使用的共享函式庫。例如你可以看ls這個實用工具使用的函式庫:

ldd /bin/ls
libtermcap.so.2 => /lib/libtermcap.so.2 (0x4001c000)
libc.so.6 => /lib/libc.so.6 (0x40020000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

通常我麼可以看到一個soname的列表,包括路徑。在所有的情況下,你都至少可以看到兩個庫:

· /lib/ld-linux.so.N(N是1或者更大,一般至少2)。這是這個用力載入其他所有的共享庫的庫。

· libc.so.N(N應該大於或者等於6)。這是C語言函式庫。


值得一提的是,不要在對你不信任的程式執行ldd命令。在ldd的manual裡面寫得很清楚,ldd是透過設定某些特殊的環境變數(例如,對於ELF物件,設定LD_TRACE_LOADED_OBJECTS),然後執行這個程式。這樣就有可能使得某地程式可能使得ldd來執行某些意想不到的程式碼,而產生不安全的隱患。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10796304/viewspace-962573/,如需轉載,請註明出處,否則將追究法律責任。

相關文章