2011-04-19 90 views
5

我的問題與this question不一樣。是否可以靜態鏈接到共享對象?

我正在使用獨立二進制文件進行項目,該文件沒有動態/外部鏈接,並且在* nix環境中運行。

我試圖移動到一個較新的工具集來構建,但一些舊工具集可用的靜態庫現在不可用 - 例如,提供了_start的crt庫aren在這個工具集中沒有提供。

我已經挖通過提供與供應商的工具包中的文件,發現與我從CRT庫所需的符號一些共享對象(例如,_start,_fini等),但我不確定是否有一個直接將一個共享對象靜態鏈接到一個二進制文件中,並且還可以執行該二進制文件。

簡版:非共享對象二進制文件可以靜態鏈接到共享對象而不會變成另一個共享對象嗎?

+0

您的原始獨立二進制文件是否已被靜態鏈接?你能否提供一些關於你實際擁有的細節,以及你需要達到什麼? – 2011-07-31 11:32:51

+0

在最初的項目中,使用舊的工具集時,有一些提供的(靜態)庫,鏈接時使它成爲獨立的可運行二進制文件。在較新的工具集中,其中一些東西缺少靜態庫,但有幾個共享對象提供這些符號。基本上我想知道的是,共享對象可以靜態鏈接到獨立的二進制文件中。 – 2011-08-01 17:51:50

+0

最後一個問題的確切答案是「不」。當您創建共享庫時,靜態鏈接所需的信息將不可挽回地丟失。 – 2011-08-01 18:07:10

回答

6

共享庫和靜態庫之間存在根本區別。首先,請搜索本網站以獲取以前的討論,並且也要求check out this question(以及其中的答案)。

基本上,靜態庫只是對象的集合,鏈接器將符號名稱解析爲固定地址 - 這是靜態鏈接所必需的。另一方面,共享庫更像是一個獨立的可執行文件,它由加載程序加載到內存中,並具有程序跳轉到的入口點地址。但是,當鏈接共享庫時,通常不會保留靜態庫所具有的重定位表,因此通常不可能從鏈接的共享庫中提取可鏈接的對象代碼。

2

是的,我知道這是一個6歲的問題。我被告知可以靜態鏈接一個共享對象庫,但我也發現它不是。

要真正地演示了靜態鏈接的共享對象庫是不可能的ldgcc的鏈接),請使用以下命令gcc

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so 

(當然,你必須編譯objectname.osourcename.c,並且你應該彌補自己的共享對象庫爲好。如果這樣做,使用-Wl,--library-path,.讓LD可以找到你的庫在本地目錄。)

實際的錯誤,你收到的是:

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so' 
collect2: error: ld returned 1 exit status 

顯然,試圖拉對象從共享對象庫的一些關於這ld在所不惜。

有一些建議here,但我對這個問題的興趣僅僅是學術。

希望有所幫助。