使用arm-none-eabi-gcc编译hello world程序时出现编译错误

4

我正在尝试在Linux 64位机器上编译一个C语言的hello world程序。我使用ARM交叉编译器将我的应用程序加载到ARM处理器上。然而,当我使用arm-none-eabi-gcc -o hello hello.c编译代码时,我遇到了一系列错误:

/home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o):在函数exit'中: exit.c:(.text.exit+0x2c):对_exit'的引用未定义 /home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-sbrkr.o):在函数_sbrk_r'中: sbrkr.c:(.text._sbrk_r+0x18):对_sbrk'的引用未定义 /home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-writer.o):在函数_write_r'中: writer.c:(.text._write_r+0x20):对_write'的引用未定义 /home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-closer.o):在函数_close_r'中: closer.c:(.text._close_r+0x18):对_close'的引用未定义 /home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-fstatr.o):在函数_fstat_r'中: fstatr.c:(.text._fstat_r+0x1c):对_fstat'的引用未定义 /home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-isattyr.o):在函数_isatty_r'中: isattyr.c:(.text._isatty_r+0x18):对_isatty'的引用未定义 /home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-lseekr.o):在函数_lseek_r'中: lseekr.c:(.text._lseek_r+0x20):对_lseek'的引用未定义 /home/dico/gcc-arm-none-eabi-4_7-2013q3/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/libc.a(lib_a-readr.o):在函数_read_r'中: readr.c:(.text._read_r+0x20):对_read'的引用未定义 collect2: 错误:ld 返回 1
当我尝试通过以下方式进行编译时:arm-none-eabi-gcc -c hello.c,它会创建一个目标代码hello.o,这说明编译器正常运行。但是,为什么我的编译返回这样的错误呢?请有经验的人告诉我原因。
更新:我现在意识到C运行库未包含在编译中。是否有任何选项需要在编译中包括,或者如何链接库以使用标准函数,例如printf?

请查看 http://embdev.net/topic/129753 - Jayesh Bhoi
1
这可能会对你有所帮助:https://dev59.com/reo6XIcBkEYKwwoYOR4q - Rahul R Dhobi
它缺少libc低级函数。它是平台相关的,因此arm-none-eabi-gcc工具链将不会包含它。通常由芯片制造商提供。目标平台是什么?如果您停止使用libc函数(printf、malloc、open等),则可以编译您的程序。 - Felipe Lavratti
1
感谢您的回复。@fanl,我的目标平台是带有ATMEL AT91SAM9G20处理器的FOX G20 V。我需要编译“Hello World”程序(因此需要使用printf、return等),但这只是为了测试编译。稍后,我将在我的源代码中使用标准库(uIP)。您知道我如何编译“Hello World”程序吗? - Adam
1
编译时我需要在命令行中添加选项或任何选项吗? - Adam
@JohnSmith 不,基本上你应该有一个.c文件(通常称为retarget.c或syscalls.c),定义libc应该如何处理printf输出。Printf构建一个字符串,在MCU芯片内部应该将这个字符串放在哪里,因为没有控制台。现在你明白了吗?通常,retarget.c将printf输出发送到串行线路。 - Felipe Lavratti
1个回答

2
MCU芯片在没有控制台的情况下应该如何处理printf字符串?这就是正在发生的事情。libc需要平台相关的低级函数,不应包含在libc中。
您需要一个retarget.c或syscalls.c文件,定义所有这些缺失的符号,并正确将printf输出重新定向到从芯片外部访问的串行线路。
我强烈建议您使用yagarto工具包,他们提供了一个syscall.c文件,其中包含构建项目所需的内容,当链接libc时,就像您正在做的那样。
如果您想尝试简短的路径,请将syscall.c文件包含到您的项目中,并重新编程其函数内部以适应您的需求。
在微控制器世界中将裸gcc工具链与libc链接起来并非初学者之事。我的建议始终是按照yagarto的教程一步一步地进行。

1
感谢您的帮助!这个Hello World程序以及使用print函数只是为了测试工具链,以便在我的项目中稍后使用。一旦我能够希望它能够正常工作,我将不再使用这些标准函数,而是使用标准库(uIP)。尽管如此,您提供的syscall.c链接无法使用。 - Adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接