【问题标题】:How can I link libc.a into a shared library in arm-linux use arm-none-linux-gnueabi-gcc如何将 libc.a 链接到 arm-linux 中的共享库中使用 arm-none-linux-gnueabi-gcc
【发布时间】:2012-09-06 06:01:18
【问题描述】:

在一个项目中,我的同事创建了一个静态库,例如 liba.a,它与应用程序链接。

在 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 不允许重定位在共享对象中。

有人知道吗?

谢谢转发。

【问题讨论】:

  • 我认为-static -share不应该混用....
  • 以下文本是从codesurgery 的ld.pdf 复制而来的:“-static 不要链接到共享库。这仅在支持共享库的平台上有意义。此选项可以是与“-shared”一起使用。这样做意味着正在创建一个共享库,但必须通过从静态库中拉入条目来解析该库的所有外部引用。”
  • @DavidChyi:这只是说 -static 和 -shared 可以混合使用,但并不是一个好主意。一般来说,编译器有很多选项对于普通应用程序来说不是一个好主意。它们对于编译内核、引导加载程序、微控制器代码等特殊情况很重要。

标签: linux linker arm shared-libraries libc


【解决方案1】:

您不能,因为共享库中的代码必须使用-fPIC 编译,而静态库中的代码则不需要。如果你设法做到了,生成的可执行文件最终将与 libc 多次链接,无论如何这将非常脆弱,并且可能迟早会崩溃,所以无论如何你都不应该这样做。因此:

不要。动态库必须动态链接到系统库,任何链接到任何动态库的可执行文件也必须动态链接系统库。

我还想提醒您,将 GNU libc 与非 GPL 应用程序静态链接是非法的,因为 LGPL 只排除动态链接的代码。这是为了允许在不重新编译源可能不可用的可执行文件的情况下修复库的错误。在 Linux 中,在不重新编译依赖的可执行文件的情况下升级带有错误修复版本的共享库是很常见的; libc 开发人员知道如何做到这一点。

【讨论】:

  • @Hudec:感谢您的善意提醒。我的同事已经将他的库更改为在 libc.so 中使用标准 malloc()。但只是出于好奇,为什么以下示例在 PC gcc 中有效,但在 ARM gcc 中失败:$ cat libtest.c #include <stdio.h> void foo() { printf("%d\n", 42); } $ cat main.c #include <stdio.h> extern void foo(); int main() { puts("The answer is:"); 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,有效。跨度>
  • @Hudec:我在哪里可以找到这些信息? 不要。动态库必须动态链接系统库,任何链接到任何动态库的可执行文件也必须动态链接系统库。 libc.a 用于什么?
  • @DavidChyi:这取决于您尝试使用的特定系统上的 libc.a 实际包含的内容。它可能适用于一个特定的安装,而不适用于另一个。许多安装甚至没有安装静态 libc。
  • @DavidChyi:ELF,大多数 Unices 上使用的二进制格式,在支持单一定义规则方面还有很长的路要走。如果您通过单独的动态对象静态链接同一对象,它将使用两者中的副本之一。因此,只要版本兼容且与位置无关,它通常会起作用。但是像 Windows 这样的其他系统会很乐意使用它包含在每个对象中的副本,如果你混合调用,它真的会发疯。
  • @DavidChyi:随着时间的推移,我学到了很多关于动态链接如何工作的知识,但我真的不记得任何一个全面的信息来源。通常经验法则是使用默认值(在 Linux 上总是意味着动态链接),除非您有充分的理由更改它并理解其含义。
猜你喜欢
  • 1970-01-01
  • 2012-11-27
  • 1970-01-01
  • 2016-12-21
  • 2014-05-09
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多