使用Eclipse的C项目上的链接器错误

dam*_*ien 25 eclipse linker gcc arm gnu

我想为STM32F217IG微控制器创建一个项目.

然后我安装了Eclipse和GNU for ARM嵌入式GCC交叉编译器.我不认为这是Code Sourcery.我使用它,因为它支持浮点,而Code Sourcery则不支持.

一旦我这样做,我尝试创建一个只有两个源文件的真正小项目:test.c和main.c,只写入两个:

#include <stdlib.h>
#include <stdio.h>

int main (void)
{
    printf("Hello, World!");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我更改了项目属性中的line命令,用arm-none-eabi-gcc替换GCC,然后尝试编译项目.

我自己没有创建任何make文件; 我在Eclipse中使用了自动创建.

这个建筑看起来很好,但是当谈到链接器时,我在控制台中遇到了以下错误:

make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'

collect2: ld returned 1 exit status

make: *** [test3] Erreur 1
Run Code Online (Sandbox Code Playgroud)

我在网上看了一下,发现这可能是一个系统调用问题.但是我不知道如何在Linux上将这个库添加到我的项目中.

真的吗?如果是,我该如何解决?如果没有,那会是从哪里来的?

正如有人建议的那样,我尝试"链接"C运行时库.在Eclipse上,我似乎有两个解决方案:

首先在项目属性→ C/C++构建设置交叉链接器.我只是添加了字母c,然后错误没有改变,但-lc在命令行的末尾有:

 make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o   -lc

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-exit.o): In function `exit':
exit.c:(.text.exit+0x2c): undefined reference to `_exit'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0x18): undefined reference to `_sbrk'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x20): undefined reference to `_write'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0x18): undefined reference to `_close'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0x1c): undefined reference to `_fstat'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0x18): undefined reference to `_isatty'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x20): undefined reference to `_lseek'

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x20): undefined reference to `_read'

collect2: ld returned 1 exit status
make: *** [test3] Erreur 1
Run Code Online (Sandbox Code Playgroud)

但我不知道它是否真的意味着添加C运行时库.

其次,我在项目属性→ C/C++通用路径和符号库中添加了libc.a库,这是我得到的(完全不同):

make all
'Building target: test3'
'Invoking: Cross GCC Linker'
arm-none-eabi-gcc  -o"test3"  ./main.o ./test3.o   -l"C:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a"

c:/program files/gnu tools arm embedded/4.6 2012q4/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/bin/ld.exe: cannot find -lC:/Program\ Files/GNU\ Tools\ ARM\ Embedded/4.6\ 2012q4/arm-none-eabi/lib/armv7-m/libc.a

collect2: ld returned 1 exit status
make: *** [test3] Erreur 1
Run Code Online (Sandbox Code Playgroud)

然后它仍然不起作用,但它是搜索的好方法吗?

哦,这是一个非常有趣的事实:

我只在调试模式下得到了错误.如果我处于发布模式,一切都没问题,我没有任何错误(除非我添加了libc.a然后我认为这不是好事).这是否意味着问题是.elf文件的创建?

Cod*_*ers 29

我查看了你链接的工具包,只是为了阅读以下内容readme.txt:

该工具链针对Cortex-R/M裸机开发而构建和优化.

换句话说,此工具链专门为嵌入式系统配置,可能根本没有运行操作系统.在这种情况下,没有系统提供例如标准输出printf()应该写入的地方,没有文件系统等等 - 如果你想使用它们,你必须链接到提供这些基本服务的某个库.

也就是说,您的工具包提供librdimon.a了提供所有这些基本服务的库.这个库实际上是libgloss编译的一部分.如果要链接它,请尝试以下命令:

arm-none-eabi-gcc --specs=rdimon.specs   -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group -o test test.c
Run Code Online (Sandbox Code Playgroud)

这在我的电脑上很好地链接,但是它是否是你真正想要的是另一个故事(你期望在哪里看到printf()输出?).

对于芯片,您应该寻找一个库,它将标准输出重定向到串行端口或通过JTAG提供调试输出.或者,您可以使用自定义功能,例如将调试输出发送到串行控制台而不是printf()- 由您决定.如果你决定使用printf()我建议阅读libgloss文档.

此外,我建议四处寻找专为STM32系列捆绑的工具链.正确配置所有这些基本内容(C库,链接器脚本等)需要一些经验.

编辑:许多嵌入式系统并不真正使用标准C库,从头开始.如果你想这样,你应该-nostdlib转到你的gcc调用.当然,你将不再拥有printf()可用的东西.

编辑2:另一种方法是使用标准库(newlib我的意思是),libgloss并为不需要的东西提供适当的存根.您可能希望遵循本教程,通过串行端口实现_read_write实现,其他所有内容都是存根的.这很可能是你真正想要的.


Sha*_*ane 9

我知道这是一个老问题,但是今天我试图构建STM32板时遇到了这个问题.我的项目有一些链接器脚本(特别是libs.ld).在libnosys.a中添加一个条目就满足了链接器,我能够继续.

libs.ld:

 GROUP(
   libgcc.a
   libg.a
   libc.a
   libm.a
   libnosys.a
 )
Run Code Online (Sandbox Code Playgroud)


Pet*_*eoh 6

将您的C程序保存为"myprint.c",我将其编译如下:

arm-none-eabi-gcc myprint.c -lc -specs = nosys.specs

没有错误和输出是好的.