2

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

但是,我正在为 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

什么可能导致这种情况?

4

1 回答 1

1

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

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

于 2013-12-21T21:01:59.987 回答