2012-09-13 69 views
5

在一個項目中,我的同事創建了一個靜態庫,例如liba.a,它與應用程序鏈接。如何將libc.a鏈接到arm-linux中的共享庫arm-none-linux-gnueabi-gcc

在liba.a中,他將libc malloc()覆蓋爲其所有者版本。

我創建了一個共享庫libs.so,它也與應用程序鏈接。

問題是當我的libs.so鏈接到應用程序時,在我的libs.so中使用的malloc()將成爲liba.a中的一個,而不是標準libc.so中的那個,這會導致問題。

然後,我想靜態鏈接libc.a到我的libs.so,我用gcc的-static -shared -fPIC標誌。

但我總是得到arm-2012.03/bin /../ lib/gcc/arm-none-linux-gnueabi/4.6.3 /../../../../ arm-none-linux -gnueabi/bin/ld:arm-2012.03/bin /../ arm-none-linux-gnueabi/libc/usr/lib/libc.a(dl-tsd.o)(.text + 0x14):R_ARM_TLS_LE32 relocation not允許共享對象。

有沒有人有想法呢?

向前感謝。

+0

我認爲-static -share不應該混合使用...... – Jeyaram

+0

下面的文本從codedgery的ld.pdf中拷貝下來:「-static不要鏈接到共享庫,這隻對共享的平臺 有意義庫支持** 選項可與'-shared'**一起使用,這意味着創建了共享庫 ,但是必須通過從靜態庫中提取條目來解析庫的所有外部參考文件必須解析爲 「。 –

+0

@DavidChyi:這只是說靜態和共享可以混合使用,但並不是說這是個好主意。一般而言,編譯器有許多選項,這些選項對於普通應用程序來說不是一個好主意。它們對編譯內核,引導程序,微控制器代碼等特殊情況非常重要。 –

回答

2

您不能,因爲共享庫中的代碼必須編譯爲-fPIC而靜態庫中的代碼不是。如果你設法做到這一點,那麼最終的可執行文件最終會與libc多次鏈接,無論如何它會非常脆弱,並且可能遲早會崩潰,所以你不應該這樣做。因此:

不要。動態庫必須動態鏈接到系統庫,並且任何鏈接到任何動態庫的可執行文件都必須動態鏈接系統庫。

我還想提醒你,靜態鏈接GNU libc與非GPL應用程序是非法的,因爲LGPL只能動態鏈接代碼。這是爲了允許在不重新編譯源代碼可用的可執行文件的情況下修正該庫。在Linux中使用錯誤版本升級共享庫而不重新編譯相關可執行文件相當普遍; libc開發人員知道如何做到這一點。

+0

@Hudec:謝謝你的提醒。我的同事已經將他的庫改爲在libc.so中使用標準的malloc()。但爲了好奇,爲什麼以下示例在PC gcc中工作,但在ARM gcc中失敗:$ cat libtest.c '#include void foo(){printf(「%d \ n」,42); }' $ cat main。c# '#include extern void foo(); int main(){puts(「答案是:」); FOO(); }' 'gcc -shared -fPIC libtest.c -o libtest.so -static-libgcc -Wl,-Bstatic -lc && gcc -c main.c -o main.o && gcc main.o -o test。 /libtest.so && LD_PRELOAD =。/ libtest.so。/ test' ====> 42,有效。 –

+0

@Hudec:我在哪裏可以找到這些信息? _別。動態庫必須動態鏈接到系統庫,任何鏈接到任何動態庫的可執行文件都必須動態鏈接系統庫._ libc.a用於什麼? –

+0

@DavidChyi:它取決於你正在嘗試使用它的特定系統上的libc.a實際包含的內容。它可能在一個特定的安裝而不是另一個安裝。許多安裝甚至沒有安裝靜態libc。 –