[英]C++ Statically linked shared library
我有一個共享庫,由我無法控制的另一個應用程序使用,它需要 *.so 對象。 我的庫使用了需要與其靜態鏈接的 sqlite3(我絕對需要一個自包含的二進制文件)。
當我嘗試編譯和鏈接我的庫時:
-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 編譯我的 object,結果相同。
謝謝。
編輯:
該問題似乎與 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 還是什么?
創建共享庫時不應使用-static
標志,它用於創建靜態鏈接的可執行文件。
如果您只有 static 版本的庫,則可以使用-lsqlite3
將其鏈接。 但如果同時存在動態版本 (.so) 和 static 版本,則 linker 將更喜歡動態版本。
要指示 linker 選擇 static 之一,請給-Bdynamic
-Bstatic
標志,並使其切換回動態鏈接支持與 lib 動態鏈接和其他動態內容(例如)。 也就是說,您使用以下標志:
-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic
或者,您可以只指定.a 文件的完整路徑,例如/usr/lib/libsqlite3.a
,而不是任何編譯器/鏈接器標志。
使用 GNU ld,您還可以使用-l:libsqlite3.a
代替-lsqlite3
。 這將強制使用庫文件libsqlite3.a
而不是libsqlite3.so
,這是 linker 默認喜歡的。
請記住確保使用-fpic
標志編譯了 .a 文件,否則您通常無法將其嵌入到共享庫中。
任何以某種方式進入動態庫的代碼都應該是可重定位的。 這意味着與 your.so 鏈接的所有內容,無論是靜態的還是動態的,都應該使用-fPIC
進行編譯。 具體來說,static sqlite
庫也應該使用-fPIC
編譯。
PIC 含義的詳細信息在這里: http://en.wikipedia.org/wiki/Position-independent_code
我有同樣的問題。 顯然 -static 與 -Bstatic 不同。 我切換到 -Bstatic 並且一切正常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.