【发布时间】:2019-08-16 15:02:06
【问题描述】:
我正在从事嵌入式项目。我已经在其中集成了开源子项目(即我没有编写的代码)。 编译很好,但我有链接错误:
gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libc.a(lib_a-abort.o):
In function `abort': abort.c:(.text.abort+0xa): undefined reference to `_exit'
gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libc.a(lib_a-signalr.o):
In function `_kill_r': signalr.c:(.text._kill_r+0x10): undefined reference to `_kill'
gcc-arm-none-eabi-7-2018-q2-update/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libc.a(lib_a-signalr.o):
In function `_getpid_r': signalr.c:(.text._getpid_r+0x0): undefined reference to `_getpid' collect2: error: ld returned 1 exit status
我也有关于未定义引用 _exit 的错误,但我通过搜索和替换对 exit(1) 的调用修复了这些错误。
我尝试搜索和替换对abort() 的调用,但仍然出现这些错误。
我发现通过添加链接器选项-specs=nosys.specs 解决了一些类似的问题,但这不是我想要的。
我想修改代码,这样我就可以优雅地处理错误,而不会粗暴地退出整个程序,为此我必须找到哪个代码依赖于这个链接。
【问题讨论】:
-
函数的文档应该包括定义它的头文件和实现/提供它的库。
-
我将
libc.a解释为(打算成为)C 标准库的静态版本。高度怀疑此类库中的函数会依赖于该库之外的任何内容,并且某些细节看起来更加可疑。我认为该库可能没有正确构建。 -
你不应该替换调用,你应该自己实现调用。如果你导入一个使用 getpid 和 kill 的库,那么你应该在你的目标系统上实现它们。您应该在目标上实现
_kill和_getpid和_exit函数并决定它们应该做什么。gcc-arm-none-eabi是“裸机”,没有操作系统。值得注意的是,gcc(默认情况下)使用newlib作为它的标准库实现。为什么nosys.specs会让你的程序“野蛮退出”? -
您导入的代码假设环境不存在,例如。您可以在进程上调用 getpid 。如果您的裸机目标没有实现 posix 回调,您必须实现它们才能使用 posix 兼容代码。
nosys.specs只是与“没有 posix 和 c 调用的系统实现”链接,即。大多数 posix 调用返回 -1 并将 errno 设置为 ENOSYS 或类似的。可以在here 找到实现。并非所有呼叫都被屏蔽。 -
I have integrated open source sub-projects- 哪些项目?I fixed these by searching & replacing calls to exit(1)- 你是如何修复它们的?你用什么代替了它们?-specs=nosys.specs but this is not what I want为什么 nosys.specs 会让你“粗暴地退出整个程序”?