静态库中的 Newlib 存根

Newlib stubs in static library

我正在使用 Eclipse 开发裸机应用程序。我 link 反对 newlib,所以我提供了我自己的 _sbrk() 实现。此功能通常包含在我的项目中,并且一切正常。

现在我尝试将这个函数移动到我在过去几个月开发的静态库中。

在 linking 期间,我收到 undefined reference to _sbrk 错误。文件所在的路径已正确包含在 Eclipse 设置中(同一目录中的其他文件已正确 link 编辑)。

很明显 linker 通过我的代码的顺序有一些问题,这个函数被丢弃了。

我尝试使用 __attribute__((used)),但没有成功。

如何解决这个问题,通过 Eclipse 设置?(基于 Makefile 或命令行编译不是我需要的解决方案)。

重复库

要使其正常工作,您需要确保您的 "new" 静态库出现在链接器命令行中的 newlib(C 库)之后。 GCC 会在所有其他对象和库之后自动将 -lc 添加到链接器的命令行。但是,如果需要,您可以重复使用它们。

所以假设您的库名为 mylibrary 并且您的应用程序和主文件名为 SO,这样设置链接器选项将起作用:

gcc  -o SO ./src/SO.o -lc -lmylibrary

这在链接器上解析为(简化!):

ld -o SO ./src/SO.o -lc -lmylibrary -lc -lgcc

在设置中是这样的:

要获得正确的组合,您可能需要 adjust/add 重复一些操作。特别是如果 "mylibrary" 依赖于 newlib 的其他部分,而 newlib 又依赖于 mylibrary 的其他部分。

强制提前链接

另一种选择是确保 _sbrk 只是尽早链接。这可以通过多种方式完成:

  • 在链接描述文件中添加依赖项
  • 从直接传递给 GCC 的目标文件添加对 _sbrk 的使用。例如。:
    • 从本身未使用的外部(即未优化)函数调用 _sbrk
    • 在c文件中取_sbrk的地址
    • 添加 _sbrk 对程序集文件的引用,如果 space 紧

为什么?

您并没有问为什么会发生这种情况,但对于任何其他想知道的读者来说,这里有一个很好的问答:Why does the order in which libraries are linked sometimes cause errors in GCC? 了解有关顺序为何重要的更多详细信息。

我通过将以下代码添加到我的链接描述文件中解决了我的问题。

GROUP(
   libgcc.a
   libg.a
   libc.a
   libm.a
   libnosys.a
 )

这样就无需更改任何设置或发出的链接器命令。