2012-09-13 70 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。 –