放置在静态库中时找不到 _sbrk 函数

Ric*_*ard 5 c linker gcc arm

我正在为 stm32f407 微控制器创建一个裸机应用程序,该微控制器具有 ARM Cortex M4 内核。因此,我正在交付像_sbrk我一样的功能的实现。我现在发现,当我尝试创建一个包含 的静态库_sbrk并将其与 my 链接main.c到应用程序中时,链接器说

“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' 的未定义引用”。

如果我从静态库中取出相同的函数并将其放入 ,main.c则一切都会编译/链接/运行得很好。

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

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

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

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:/用户/理查德·彼得斯/文档/项目/嵌入式/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

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

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

libcmsis_stm.cmsis_stm.a是使用以下命令构建的:

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

所以还有一个问题:我想将中断向量表(它是一个变量)放入静态库中,但链接器会丢弃该变量,因为没有源文件需要该变量。是否有一种机制可以保留该变量,直到链接器处理链接器文件中的输出部分?

Ber*_*ium 5

ld链接到库时,它只会选择当时需要的那些函数(因为引用了之前链接的翻译单元中的函数)。链接器将忘记所有其他函数(并且稍后不会考虑该库)。

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

所以链接应该看起来像

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

_sbrk功能由 提供libapp

因此要链接的对象的顺序很重要。

更新

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

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