2011-07-09 237 views
25

我有一個共享庫被另一個應用程序超出了我的控制範圍,它需要* .so對象。我的庫使用sqlite3需要靜態鏈接它(我絕對需要一個自包含的二進制文件)。C++靜態鏈接共享庫

當我嘗試編譯和鏈接我的圖書館:

-fpic -flto -pthread -m64 
-flto -static -shared 

我結束了以下錯誤:

/usr/bin/ld: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__' can not be used when making a shared object; recompile with -fPIC 
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: could not read symbols: Bad value 
collect2: ld returned 1 exit status 

什麼是重新編譯-fPIC有關?我的代碼或CRT?

我已經嘗試用-fPIC編譯我的對象,並得到相同的結果。

謝謝。

編輯:

似乎問題並不涉及到sqlite3的。

我寫了編譯和像這樣的鏈接一個簡單的線什麼都不做的庫:

g++ -c -fPIC -o bar.o bar.cpp 
g++ -shared -o bar.so bar.o 

,但不喜歡這樣的:

g++ -c -fPIC -o bar.o bar.cpp 
g++ -static -shared -o bar.so bar.o 

的問題似乎與CRT (crtbeginT.o)。我應該重新編譯GCC --with-pic或其他什麼?

+0

這有點令人困惑。你是否試圖將你的庫鏈接到一個靜態的sqlite庫,或者你是否還想做其他的事情? – nos

+0

PIC =共享庫所需的位置獨立代碼(在大多數體系結構上,我猜) – sehe

+0

@nos試圖將我的共享庫鏈接到sqlite3.a – Petr

回答

35

創建一個共享庫時,不應使用-static標誌,它是用於創建靜態鏈接的可執行文件。

如果您只有一個庫的靜態版本,您可以使用鏈接它。但是,如果同時存在動態版本(.so)和靜態版本,鏈接器將更喜歡動態版本。

要指示鏈接器選擇靜態鏈接器,請給鏈接器標記-Bstatic,並使其切換回其他東西(如libc和動態運行時支持)的動態鏈接,並使用-Bdynamic。也就是說,使用標誌:

-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic 

Alternativly,你可以指定某文件,例如完整路徑/usr/lib/libsqlite3.a而不是任何編譯器/鏈接器標誌。

使用GNU ld,您還可以使用-l:libsqlite3.a而不是。這將強制使用庫文件libsqlite3.a而不是libsqlite3.so,默認情況下鏈接器首選。

請記住確保.a文件已使用-fpic標誌進行編譯,否則通常無法將其嵌入到共享庫中。

+0

我在這裏有同樣的問題,不知道如何編譯共享庫,不會動態鏈接到像libc/libstdC++這樣的分發依賴的工作人員 - 「-Bstatic」確實提供動態鏈接的共享庫。奇妙的是,在Windows上使用MinGW,我可以正確鏈接.dll與'-static'(取決於windows dll,但不是mingw的)。有沒有辦法鏈接.so靜態? – Nick

+0

編號的unix共享庫與Windows DLL工作非常不同。 – nos

+0

-l:libsqlite3.a技巧也適用於eclipse cdt。在Properties-> C/C++ Build-> Settings-> GCC C Linker-> Libraries中輸入:libsqlite3.a,構建將靜態鏈接到庫。 – zztops

7

任何會以某種方式進入動態庫的代碼都應該是可重定位的。這意味着與.so鏈接的所有內容,無論是靜態的還是動態的,都應該使用-fPIC進行編譯。具體而言,靜態sqlite庫也應編譯爲-fPIC。什麼PIC手段

詳情請看這裏:http://en.wikipedia.org/wiki/Position-independent_code

+0

我重新編譯了sqlite3 --with-pic,但結果仍然相同... – Petr

+0

發佈您執行的完整鏈接命令,以便我們可以進一步分析) – vines

+0

查看原文。 – Petr

0

我有同樣的問題。顯然靜態不同於-Bstatic。我切換到-Bstatic,一切正常。