2010-02-03 36 views
9

這個問題的標題是exact dupe,但在這個問題的答案不幫助我。將靜態庫轉換爲共享庫(從libsome.a創建libsome.so):我的符號在哪裏?

我有一堆裝在一個靜態庫的目標文件:

% g++ -std=c++98 -fpic -g -O1 -c -o foo.o foo.cpp 
% g++ -std=c++98 -fpic -g -O1 -c -o bar.o bar.cpp 
% ar -rc libsome.a foo.o bar.o 

我想從libsome.a,而不是目標文件libsome.so產生,但庫是真的準系統:

% g++ -std=c++98 -fpic -g -O1 -shared -o libsome.so libsome.a 
% nm -DC libsome.so 
0000xxxx A _DYNAMIC 
0000xxxx A _GLOBAL_OFFSET_TABLE_ 
     w _Jv_RegisterClasses 
0000xxxx A __bss_start 
     w __cxa_finalize 
0000xxxx A _edata 
0000xxxx A _end 
0000xxxx T _fini 
0000xxxx T _init 

靜態庫是好的,或者至少我完全能夠將它鏈接到一個可執行文件,並讓它運行所包含的功能。另外,如果我從foo.o和bar.o創建libsome.so,一切都很好。

回答

22

假設您使用的是GNU鏈接器,您需要指定--whole-archive選項,以便獲取靜態存檔的所有內容。由於這是一個連接選項,則需要輪候冊告訴GCC通過向它傳遞給鏈接器:

g++ -std=c++98 -fpic -g -O1 -shared -o libsome.so -Wl,--whole-archive libsome.a 

如果你在做你想要的所有圖書館的一些更復雜一些,但僅有庫的一部分通過libsome必要的支持,你想關閉整個檔案你用它在libsome後:

... -Wl,--whole-archive libsome.a -Wl,--no-whole-archive libsupport.a 

如果你不使用GNU鏈接,你需要看看你的鏈接器支持它和它叫什麼。在Sun鏈接器上,它被稱爲-z allextract-z defaultextract

+0

+1你走了。我嘗試了「man ld」並錯過了這一點。 – 2010-02-03 17:55:14

+0

謝謝,這就是它!我已經在ld頁面上下搜索,但不知何故錯過了這個選項。 – 2010-02-03 18:10:19

+0

現在,如果只有這個優秀的答案也表明如何用CMake項目來設置它!謝謝 – 2011-03-10 08:21:50

1

您的文件沒有被拉入.a文件,因爲沒有引用它們。你爲什麼首先創建一個.a文件?通過使用-r選項將它們鏈接起來,您可以更好地運行.o文件。

+0

當我從foo.o和bar.o構建libsome.so時,沒有任何內容引用這些符號,但它們最終會在庫中。並且'.a'文件只是將這兩個確切的'.o'文件放在一起,所以*應該*是一種(簡單的)方法來使用它來代替包含的目標文件,不是? – 2010-02-03 17:41:31

+0

因爲僅當引用了它們中的符號時纔將目標文件從.a文件中拉出。一個.o文件總是被鏈接,引用或不鏈接。 – 2010-02-03 17:43:31

+0

好的,忽略了我的具體情況:是否存在或沒有將靜態庫轉換爲共享庫的方法*就像使用了'.o'文件一樣? (折扣'ar -x') – 2010-02-03 17:48:17