C _在静态库中未找到sbrk函数

C _在静态库中未找到sbrk函数,c,gcc,linker,arm,C,Gcc,Linker,Arm,我正在为stm32f407微控制器创建一个裸机应用程序,它有一个ARM Cortex M4内核。因此,我自己也在实现类似于\u sbrk的功能。我现在发现,当我试图创建一个包含\u sbrk的静态库,并将它与我的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\li

我正在为stm32f407微控制器创建一个裸机应用程序,它有一个ARM Cortex M4内核。因此,我自己也在实现类似于
\u sbrk
的功能。我现在发现,当我试图创建一个包含
\u sbrk
的静态库,并将它与我的
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\u nano.a(lib\u a-sbrkr.o):函数中的sbrkr:sbrkr.c:(.text.\u-sbrkr+0xc):未定义的“sbrk”引用。”

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

我几乎可以肯定,这与链接器在所有库中读取的顺序有关,而且当读取我自己的静态库时,还不需要定义
\u sbrk
,因此被抛出,结果发现在稍后链接到一个标准库时仍然需要它。但是,我自己没有指定任何标准库,因此无法更改链接这些库的顺序。我还试图将
\u sbrk
函数声明为
\uuuuu属性((uuuu使用的)
,认为链接器不会丢弃该函数,但遗憾的是,这并没有解决我的问题

所以我的问题是,我如何将
\u sbrk
放入一个静态库中,而不会遇到未解析的引用

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

C:\PROGRA~2\gnuto~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使用cxa-atexit-fno线程安全静态-g-mcpu=cortex-m4-mfpu=fp-sp-d16-mfloat abi=softfp-mthumb-Wl-gc-sections-nopartfiles-Wl“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”“cmakfiles\http_server.dir\src\main.cpp.obj”“cmakfiles\http_server.http_server.dir\src\vectors\stm32f4xx.C.obj”CMakeFiles\http_server.http_server.dir\http_server.http_server\u linker\u script\u 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

添加以下内容将创建thing链接:

-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\gnuto~1\4947E~1.920\bin\ARM-NO~2.EXE cq“C:\Users\Richard Peters\Documents\Projects\Embedded install\targets\cmsis\cmsis.cmsis\u stm\Generic-stm32f4xx\lib\libcmsis\u stm.cmsis\u stm.a”CMakeFiles/cmsis\u stm.dir/src/cmsis/system\u stm32f4xx.C.obj

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


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

ld
lin对于库,它只会选择当时需要的函数(因为引用了以前链接过的翻译单元中的函数)。链接器会忘记所有其他函数(以后不会考虑库)

因此,链接顺序很重要。通常,您会在应用程序对象文件(引用
malloc
)中进行链接,然后是标准库(提供
malloc
,反过来又引用
\u sbrk
),然后是提供
\u sbrk
的(应用程序)库

所以链接应该是这样的

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

\u sbrk
功能由
libapp
提供

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

更新

如其中一条注释所述:如果在编译过程中使用
-g
添加调试符号,则还必须链接libg(
-lg

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


您不需要定义它。在主模块中从一个未使用的函数
dummy\u sbrk\u调用者
引用它就足够了,比如说,您用
\uuu属性((\uu used\uu))声明它
。您是否尝试过在标准C库之后在应用程序库中进行链接?例如
-o out main.o-lc-lm-lapp
?在链接阶段使用的命令行是什么样子的?库的顺序很重要。另外,我也尝试过,或者至少我尝试过main.o-lc。现在,我发现有问题的库是libg、 不是libc。在上面的句子中添加-lg确实解决了这个问题。这让我想知道,隐式链接库的总列表是什么?我可以稍微增加一点赌注吗?当重新排序库列表并复制其中的一些库时,链接器可以找到_sbrk,我与中断向量选项卡有一个相关的问题我也希望将该表(名为u isr_vectors)放入单独的静态库中,但由于它仅由链接器脚本本身使用,而不由任何代码使用,因此它没有链接