【问题标题】:Linking requires to link two static libs that depend on each other: undefined reference链接需要链接两个相互依赖的静态库:未定义的引用
【发布时间】:2013-12-21 19:45:47
【问题描述】:

我知道,这已经被问了一百万次了……不幸的是。

但是,我正在为 ARM Cortex M4 处理器进行金属构建。所以没有任何共享库,只有静态库。将我的程序与 gcc 链接时,会引发以下错误:

$ arm-none-eabi-gcc -Wall lots_of_code.o libFW.a
arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/fpu/libg.a(lib_a-exit.o):
In function `exit':
exit.c:(.text.exit+0x16): undefined reference to `_exit'
collect2: error: ld returned 1 exit status

libFW.a 是我创建的一个库,其中包含一个名为 syscalls.o 的文件,提供 _exit():

$ arm-none-eabi-nm -s libFW.a | grep _exit
_exit in syscalls.o
00000018 T _exit

在我看来,gcc 试图链接 libg.a 和lots_of_code.o,但还不知道 _exit()。但奇怪的是:直接链接到 syscalls.o 时它可以正常工作:

$ arm-none-eabi-gcc -Wall lots_of_code.o syscalls.o libFW.a

这是什么原因造成的?

【问题讨论】:

  • 你玩过-nostdlib-nostartfiles-ffreestanding等不同的标志吗?

标签: c gcc arm static-linking eabi


【解决方案1】:

当您通过在链接命令行中指定目标文件来强制链接目标文件时,它被内置到程序中,无论它是否提供任何需要的符号。当你从一个库链接它时,它只会被包含在程序中,如果它满足至少一个未定义的符号在读取库时

在静态库之间存在循环依赖是个坏主意。解决方法是链接库两次。将系统提供的函数(例如exit())替换为您自己的化身通常也是一个坏主意。看起来 C 库正在获取一个调用 _exit()exit(),但由于某种原因,之后链接的库中没有 _exit()。坦率地说,这有点奇怪。为什么你认为你的syscalls.o 比编译器(O/S)提供的设施更好?如果您需要强制链接您的系统调用,则需要在链接主 C 库(其中有很多此类调用)之前引用 syscalls.o 中定义的符号之一。

【讨论】:

  • 正如我所说,它是金属结构。所以没有操作系统,它的设计目的是自己实现_exit,以指定程序结束时的行为。通常这是由一个无限的 nop-loop 来完成的……这就是事情变得相当复杂的地方。目前,我正在使用-u _exit 开关避免这个问题,这样 gcc 就不再抱怨了,但这不是我正在寻找的解决方案。难道你不能给我一个我可以轻松尝试的命令行吗?
  • 好的;这解释了“金属构造”是什么;我不在嵌入式领域工作,而且这个词没有敲响任何警钟(但我想它应该这样做)。简而言之,你超出了我的经验范围。但这听起来像强行链接syscalls.o是最简单的方法。在没有迫切需要做一些不同的事情的情况下,这就是我要做的。否则,您需要查看(可能是您的 GCC 的 -v 选项)命令行是什么,并弄清楚如何自动包含您的 syscalls.o
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
  • 2013-09-02
相关资源
最近更新 更多