2014-09-05 62 views
1

我有一個共享庫,我用它來創建可執行二進制文件。我只能控制庫和可執行二進制文件的構建過程,而不是涉及的源文件。正如預期的那樣,可執行二進制文件中的源文件引用了庫中的許多函數。如何使用靜態庫(.a文件)而不是一組目標文件(.o)創建共享庫

當前共享庫是使用objectfiles(.o)直接構建的。

g++ -shared ${OBJECT_FILES} -o ${SHARED_LIBRARY} 

我想通過將它們分組在靜態庫(.a文件或存檔)中來發布目標文件。

爲了節省空間,我在創建存檔文件時刪除了所有的.o文件。所以現在,構建命令是

g++ -shared ${ACRCHIVE_FILE} -o ${SHARED_LIBRARY} 

該庫建立良好。
但是,當我嘗試通過鏈接到此共享庫來構建可執行二進制文件時,由二進制文件引用的符號未定義,並且無法鏈接。 (未定義的參考Context::Get()

根據我的理解,如果我們直接使用.o文件創建共享庫或包含所有.o文件的歸檔應該無關緊要,但顯然無論是不可能或者我可能遺漏了什麼。

+0

Mebbe試試這個? http://stackoverflow.com/questions/5685617/missing-symbols-from-static-library-in-linked-executable – IdeaHat 2014-09-05 15:57:05

+0

你嘗試用g ++創建共享-Wl, - no-undefined $ {OBJECT_FILES} -o $ {SHARED_LIBRARY}?另外通過添加-Wl,-soname,<您的共享obj.so. >? – DNT 2014-09-05 15:58:04

回答

2

共享庫libfoo.so應該包含PIC代碼和靜態庫libfoo.a包含普通的非PIC代碼。所以你不能從靜態的創建一個共享庫。

共享庫要位置無關的代碼因爲他們的部分(S)是mmap(2) -ed在幾乎任意的和可變的地址 - 沒有MAP_FIXED ......也ASLR見。

你原則上可以從PIC目標文件構建一個靜態庫,但實際上沒有人這樣做。

你可能(如果你真的堅持)製作一個由非PIC代碼構成的共享對象,但結果會有很差的性能;動態鏈接器會有很多relocations,所以大多數網段都是非共享的,動態鏈接會很慢。

要編譯foo.cc爲一個共享庫到PIC對象文件foo.pic.o

g++ -Wall -c -O foo.cc -fPIC -o foo.pic.o 

要編譯它用於靜態庫詮釋一個普通的非PIC對象文件foo.o

g++ -Wall -c -O foo.cc -o foo.o 

要製作共享庫foo.pic.obar.pic.o分成libfoobar.so鏈接一些libdep.so共享庫:

g++ -shared foo.pic.o bar.pic.o -ldep -o libfoobar.so 

在製作像上面這樣的共享庫時,您經常希望添加更多鏈接選項,例如, -Wl,-rpath, ...或-Wl,-soname, ....

順便說一句,這是不可能的鏈接存檔libfoobar.a(即使它是由PIC文件)到libfoobar.so因爲沒有名稱是不確定的,需要從libfoobar.a鏈接一些目標文件(也許你可以嘗試取消定義一些符號symb-u symb但我不建議這樣做)。

爲了使foo.obar.o靜態庫到libfoobar.a

ar cv libfoobar.a foo.o bar.o 

注意ranlib(創建歸檔的指數)是沒有更多必要的,因爲GNU ar它的工作。

讀也ld.so(8)ldd(1)ld(1)ar(1)objdump(1)readelf(1)dlopen(3)(通常,你需要將主程序與-rdynamic鏈接,如果它加載在運行時dlopen -ed插件,使插件找一些符號主程序)。

注:我只是建立一個共享庫,而不關心靜態鏈接。請注意,在某些系統上,PIC有輕微的成本(代碼稍大和/或更慢)。 AFAIK,PIC在x86-64上的開銷比在32位Linux x86上的代碼要便宜。在某些體系結構和ABI上,PIC可能具有可忽略的開銷(或者甚至可能比非獨立於代碼的代碼更有效)。

參考文獻:Drepper's paper: How to Write Shared Libraries & Levine's book: Linkers and Loaders & Program Library HowTo

+0

我一直認爲.a只不過是.o文件的存檔,與.tar.gz或.zip甚至目錄在原理上沒有什麼不同。我錯了嗎? – Arkadiy 2014-09-05 16:17:39

+0

'ar'命令也做'ranlib'用來做的事:做一些索引。 – 2014-09-05 16:22:07

+0

那麼.a庫如何與PIC相關? – Arkadiy 2014-09-05 16:33:02

相關問題