C _在静态库中未找到sbrk函数
我正在为stm32f407微控制器创建一个裸机应用程序,它有一个ARM Cortex M4内核。因此,我自己也在实现类似于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
\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”
Thlibcmsis_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)放入单独的静态库中,但由于它仅由链接器脚本本身使用,而不由任何代码使用,因此它没有链接