放置在静态库中时找不到 _sbrk 函数 [英] _sbrk function not found when placed in a static library

查看:44
本文介绍了放置在静态库中时找不到 _sbrk 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为具有 ARM Cortex M4 内核的 stm32f407 微控制器创建一个裸机应用程序.因此,我自己提供了诸如 _sbrk 之类的函数的实现.我现在发现当我尝试创建一个包含 _sbrk 的静态库,并将它与我的 main.c 链接到一个应用程序中时,链接器说

I'm creating a bare-metal application for the stm32f407 microcontroller, which has an ARM Cortex M4 core. As such, I'm delivering the implementation of functions like _sbrk myself. I now find that when I try to create a static library containing _sbrk, and link it with my main.c into an application, the linker says

"c:/progra~2/gnutoo~1/4947e~1.920/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/softfp\libg_nano.a(lib_a-sbrkr.o):在函数 _sbrk_r 中:sbrkr.c:(.text._sbrk_r+0xc):未定义对`_sbrk'的引用".

"c:/progra~2/gnutoo~1/4947e~1.920/bin/../lib/gcc/arm-none-eabi/4.9.3/../../../../arm-none-eabi/lib/armv7e-m/softfp\libg_nano.a(lib_a-sbrkr.o): In function _sbrk_r: sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'".

如果我从静态库中取出相同的函数,并将其放入 main.c,那么一切都可以编译/链接/运行.

If I take that same function out of the static library, and put it into main.c, everything compiles/links/runs just fine.

我几乎可以肯定,这与链接器在所有库中读取的顺序有关,并且在读取我自己的静态库时,还不需要定义 _sbrk,并因此被抛出,只是在稍后链接标准库之一时发现无论如何都需要它.但是,我自己没有指定任何标准库,因此无法更改链接这些库的顺序.我也尝试将 _sbrk 函数声明为 __attribute __ ((__ used__ )) ,认为链接器不会丢弃该函数,但唉,这还没有解决我的问题.

I am almost certain that this has something to do with the order in which the linker reads in all libraries, and that when my own static library is read, no definition of _sbrk is required yet, and is therefore thrown out, only to find that it was needed anyway when later one of the standard libraries is linked in. However, I do not specify any standard libraries myself, and can therefore not change the order of linking those libraries. I also tried to declare the _sbrk function as __attribute __ ((__ used__ )), thinking that the linker would not throw away that function, but alas, this has not solved my problem.

所以我的问题是,如何将 _sbrk 放入静态库中,而不会遇到未解析的引用?

So my question is, how can I put _sbrk into a static library, without running into unresolved references?

更新:链接最终应用程序的命令是:

Update: The command to link the final application is:

C:\PROGRA~2\GNUTOO~1\4947E~1.920\bin\AR10B2~1.EXE -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -ffunction-sections -fno-rtti -fno-exceptions -std=c++11 -fno-use-cxa-atexit -fno-threadsafe-statics -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -Wl,--gc-sections -nostartfiles -Wl,-T"C:/Users/Richard Peters/Documents/Projects/Embedded/http_server/ldscripts/mem.ld" -Wl,-T"C:/Users/Richard Peters/Documents/Projects/Embedded/http_server/ldscripts/sections.ld" "CMakeFiles\http_server.http_server.dir\src\main.cpp.obj" "CMakeFiles\http_server.http_server.dir\src\vector_stm32f4xx.c.obj" "CMakeFiles\http_server.http_server.dir\http_server.http_server_linker_script_dummy.c.obj" -o "c:\Users\Richard Peters\Documents\Projects\Embedded-install\targets\http_server.http_server\Generic-stm32f4xx\bin\http_server.http_server.elf" "c:\Users\Richard Peters\Documents\Projects\Embedded-install\targets\cmsis_stm.cmsis_stm\Generic-stm32f4xx\lib\libcmsis_stm.cmsis_stm.a"

C:\PROGRA~2\GNUTOO~1\4947E~1.920\bin\AR10B2~1.EXE -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -ffunction-sections -fno-rtti -fno-exceptions -std=c++11 -fno-use-cxa-atexit -fno-threadsafe-statics -g -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -mthumb -Wl,--gc-sections -nostartfiles -Wl,-T"C:/Users/Richard Peters/Documents/Projects/Embedded/http_server/ldscripts/mem.ld" -Wl,-T"C:/Users/Richard Peters/Documents/Projects/Embedded/http_server/ldscripts/sections.ld" "CMakeFiles\http_server.http_server.dir\src\main.cpp.obj" "CMakeFiles\http_server.http_server.dir\src\vectors_stm32f4xx.c.obj" "CMakeFiles\http_server.http_server.dir\http_server.http_server_linker_script_dummy.c.obj" -o "c:\Users\Richard Peters\Documents\Projects\Embedded-install\targets\http_server.http_server\Generic-stm32f4xx\bin\http_server.http_server.elf" "c:\Users\Richard Peters\Documents\Projects\Embedded-install\targets\cmsis_stm.cmsis_stm\Generic-stm32f4xx\lib\libcmsis_stm.cmsis_stm.a"

其中 AR10B2~.EXE 解析为 arm-none-eabi-g++.exe.

添加以下内容使事物链接:

Adding the following makes the thing link:

-lc -lg "c:\Users\Richard Peters\Documents\Projects\Embedded-install\targets\cmsis_stm.cmsis_stm\Generic-stm32f4xx\lib\libcmsis_stm.cmsis_stm.a"

-lc -lg "c:\Users\Richard Peters\Documents\Projects\Embedded-install\targets\cmsis_stm.cmsis_stm\Generic-stm32f4xx\lib\libcmsis_stm.cmsis_stm.a"

Th libcmsis_stm.cmsis_stm.a 库使用以下命令构建:

Th libcmsis_stm.cmsis_stm.a library is built with the following command:

C:\PROGRA~2\GNUTOO~1\4947E~1.920\bin\ARM-NO~2.EXE cq "c:\Users\Richard Peters\Documents\Projects\Embedded-install\targets\cmsis_stm.cmsis_stm\Generic-stm32f4xx\lib\libcmsis_stm.cmsis_stm.a" CMakeFiles/cmsis_stm.cmsis_stm.dir/src/cmsis/system_stm32f4xx.c.obj

C:\PROGRA~2\GNUTOO~1\4947E~1.920\bin\ARM-NO~2.EXE cq "c:\Users\Richard Peters\Documents\Projects\Embedded-install\targets\cmsis_stm.cmsis_stm\Generic-stm32f4xx\lib\libcmsis_stm.cmsis_stm.a" CMakeFiles/cmsis_stm.cmsis_stm.dir/src/cmsis/system_stm32f4xx.c.obj

其中 ARM-NO~2.EXE 解析为 arm-none-eabi-ar.exe

所以一个问题仍然存在:我想将中断向量表,它是一个变量,放入静态库中,但链接器丢弃该变量,因为没有源文件需要该变量.是否有一种机制可以在链接器处理链接器文件中的输出部分之前保持该变量?

So one question remains: I would like to place the interrupt vector table, which is a variable, into the static library, but the linker throws that variable away because no source file needs that variable. Is there a mechanism to keep that variable until the linker processes the output sections in the linker file?

推荐答案

ld 链接到一个库时,它只会选择那些当时需要的函数(因为引用了在 before 中链接的翻译单元中的函数).链接器会忘记所有其他函数(以后不会考虑库).

When ld links against a library, it will only pick those functions which are required at that time (because of references to functions from translation units which have been linked in before). The linker will forget all other functions (and the library won't be considered later).

因此链接顺序很重要.通常你会链接你的应用程序对象文件(它引用 malloc),然后是标准库(它提供 malloc 并依次引用 _sbrk),然后是提供 _sbrk 的(应用程序)库.

Therefore the linking order does matter. Normally you would link in your application object file (which references malloc), then the standard library (which provides malloc and in turn references _sbrk), and then your (application) library which provides _sbrk.

所以链接应该看起来像

arm-none-eabi-gcc ... -o out.elf startup.o main.o -lc -lm -lapp

arm-none-eabi-gcc ... -o out.elf startup.o main.o -lc -lm -lapp

_sbrk 函数由 libapp 提供.

所以要链接的对象的顺序很重要.

So the order of the objects to be linked does matter.

更新

如其中一条评论所述:如果您在编译期间使用 -g 添加调试符号,那么您还必须链接 libg (-lg).

As stated in one of the comments: If you add debug symbols using -g during compilation, then you have to link against libg as well (-lg).

arm-none-eabi-gcc ... -o out.elf startup.o main.o -lc -g -lm -lapp

arm-none-eabi-gcc ... -o out.elf startup.o main.o -lc -g -lm -lapp

这篇关于放置在静态库中时找不到 _sbrk 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆