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

时间:2015-03-06 09:23:21

标签: c gcc linker arm

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

  

" C:/progra~2/gnutoo~1/4947e~1.920/bin /../ LIB / GCC /臂-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& #39;&#34 ;.

如果我从静态库中取出相同的函数,并将其放入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 -nartartfiles -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

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

  

-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库:

  

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 \通用-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

的位置

所以仍然存在一个问题:我想将中断向量表(一个变量)放入静态库中,但链接器会抛出该变量,因为没有源文件需要该变量。在链接器处理链接器文件中的输出节之前,是否存在保留该变量的机制?

1 个答案:

答案 0 :(得分:3)

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

因此,链接顺序很重要。通常,您将链接到您的应用程序对象文件(引用malloc),然后是标准库(提供malloc,然后引用_sbrk),然后是您的(应用程序)库提供_sbrk

所以链接应该看起来像

  

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

_sbrk功能由libapp提供。

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

<强>更新

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

  

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