【问题标题】:Undefined reference to `main' and _sbrk - startup code in own static library对“main”和_sbrk的未定义引用——在自己的静态库中启动代码
【发布时间】:2016-12-26 13:14:20
【问题描述】:

我正在使用 GNU ARM Embedded 工具链 (gcc-arm-none-eabi-5_4-2016q2) 开发 Cortex-M4(STM32F4-Discovery 板)。我的代码的硬件相关部分(HAL-lib、CMSIS、启动等)构建在一个静态库中,我尝试将其链接到我的应用程序代码。我的应用程序代码包含一个main 符号,我的库包含一个_sbrk 符号。这些是错误消息:

engine_control/source/os/release/libkosmos-arm-stm32f4-discovery.a(_startup.o): In function `_start': 
_startup.c:(.after_vectors+0x9a): undefined reference to `main'

和:

/opt/gcc-arm-none-eabi-5_4-2016q2/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/lib/armv7e-m/fpu/libc_nano.a(lib_a-sbrkr.o): In function `_sbrk_r': 
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'

我认为我的链接顺序有问题。这是我的链接命令:

arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -Os -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -fno-move-loop-invariants -Werror -Wunused -Wuninitialized -Wall -Wextra -Wmissing-declarations -Wconversion -Wpointer-arith -Wpadded -Wshadow -Wlogical-op -Waggregate-return -Wfloat-equal -T mem.ld -T libs.ld -T sections.ld -nostartfiles -Xlinker --gc-sections -L"config/linker" --specs=nano.specs -L/home/tkl/git/engine_control/source/os/release -Wl,-Map,"/home/tkl/git/engine_control/release/map/arm/release/.map" -lkosmos-arm-stm32f4-discovery -o "/home/tkl/git/engine_control/release/execute/arm/release/.elf" 

我做错了什么?

【问题讨论】:

  • 您实际链接的是什么? main 应该在哪里?该链接命令似乎只包含一个库,没有目标文件...
  • 谢谢,是的,你是对的。我错过了链接我的主要对象(因为不幸的是,我使用不同的变量名来定义对象和在我的 makefile 中使用对象;)。

标签: c gcc linker arm undefined-reference


【解决方案1】:

请注意,如果您将启动代码放入库中,链接器可能没有充分的理由将其拉入 - 没有人要求它,因为通常没有其他代码部分调用它 - 不惜一切代价在图像中想要的东西就像启动代码在链接期间需要在目标文件中。并且该目标文件可能应该首先出现在您的链接行上(因为它通常调用main 和所有其他类型的符号,并且这些符号需要在链接顺序中它之后才能正确解析符号)。

另一个是sbrk_r 抱怨没有引用sbrk - 我假设这两个都在你的库中。这可以通过通过ranlib 运行您的库以创建适当的索引来解决。

【讨论】:

  • 真正的好奇心:假设实际上有一个链接器脚本作为输入文件之一传递,是否会在其中显式引用符号(即放置可能在该启动中的入口点、异常向量等代码)从“搜索库”的角度不算作参考?
  • 如果你告诉链接器你想要一个特定地址的特定符号,那么是的。但是 OP 没有(向我们展示)。如果在链接描述文件中只有段名和您想要的地址(当您尝试使用通用名称时完全有效,并且我通常会这样做),那么没有。
  • 如果启动代码由多个对象组成,我发现部分链接非常方便。
猜你喜欢
  • 2011-08-11
  • 2015-12-03
  • 2015-02-25
  • 1970-01-01
  • 2014-05-04
  • 2014-02-06
  • 2016-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多