共享庫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.o
和bar.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.o
和bar.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
Mebbe試試這個? http://stackoverflow.com/questions/5685617/missing-symbols-from-static-library-in-linked-executable – IdeaHat 2014-09-05 15:57:05
你嘗試用g ++創建共享-Wl, - no-undefined $ {OBJECT_FILES} -o $ {SHARED_LIBRARY}?另外通過添加-Wl,-soname,<您的共享obj.so.>? –
DNT
2014-09-05 15:58:04