我知道,这已经被问到了一百万次......不幸的是。
但是,我正致力于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是我创建的lib,其中包含一个名为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
是什么导致这种情况?
答案 0 :(得分:1)
当您通过在链接命令行上指定目标文件来强制链接目标文件时,它会内置到程序中,无论它是否提供任何所需的符号。当您从库中链接它时,如果它在读取库时至少满足一个未定义的符号,它将只包含在程序中。
在静态库之间存在循环依赖关系是个坏主意。解决方法是两次链接库。将系统提供的函数(例如exit()
)替换为它自己的化身通常也是一个坏主意。看起来C库正在调用exit()
调用_exit()
,但由于某种原因,之后链接的库中没有_exit()
。坦率地说,这有点奇怪。为什么您认为您的syscalls.o
比编译器提供的功能(O / S)更好?如果您需要强制链接系统调用,则需要在链接主C库(有很多此类调用的地方)之前引用syscalls.o
中定义的符号之一。