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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13235748/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 21:24:27  来源:igfitidea点击:

Linker error on a C project using Eclipse

eclipsegcclinkerarmgnu

提问by damien

I want create a project for the STM32F217IG microcontroller.

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

Then I installed Eclipse and the GNU for ARM embedded GCC cross compiler. I don't think it is the Code Sourcery one. I used it, because it supports floating point and Code Sourcery does not.

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

Once I did it I tried creating a really small project with only two sources files: test.c and main.c with only written in both of them:

完成后,我尝试创建一个只有两个源文件的非常小的项目:test.c 和 main.c,并且只用它们编写:

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

int main (void)
{
    printf("Hello, World!");
    return 0;
}

I changed the line command in the project property to replace GCC by arm-none-eabi-gcc and then tried to compile the project.

我更改了项目属性中的行命令,将 GCC 替换为 arm-none-eabi-gcc,然后尝试编译项目。

I did not create any make file myself; I used the automatic creation in Eclipse.

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

The building seems to be fine, but when it comes to the linker I got the following errors in the console:

建筑物似乎很好,但是当涉及到链接器时,我在控制台中收到以下错误:

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

I looked on the Internet, and I found that it may be a syscall problem. But I don't know how do I add this library to my project on Linux.

上网查了一下,发现可能是syscall的问题。但我不知道如何将这个库添加到我在 Linux 上的项目中。

Is it really it? If yes, how do I fix it? And if not, where do that come from?

真的是这样吗?如果是,我该如何解决?如果不是,那是从哪里来的?

As someone suggested, I tried "linking" the C runtime library. On Eclipse it seems I have two solutions to do it:

正如有人建议的那样,我尝试“链接”C 运行时库。在 Eclipse 上,我似乎有两种解决方案可以做到:

First on the project properties → C/C++BuildSettingsCross linkerlibraries. I just add the letter cand then the error does not change, but there is -lcat the end of the command line:

首先在项目属性 → C/C++BuildSettingsCross linkerlibraries。我只是添加了字母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

But I don't know if it is really means to add the C runtime library.

但是不知道是不是真的要加C运行库。

Second, I added the libc.a library in the project properties → C/C++ generalPath and symbolsLibraries, and here is what I get (completely different):

其次,我在项目属性 → 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

Then it still does not work, but is it the good way to search on?

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

Oh and a very interesting fact:

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

I got the errors only in debug mode. If I am in release mode everything is okay, and I don't have any errors (except if I add the libc.a then I think this is not the good thing to do). Does that mean the problem is the .elf file creation?

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

回答by Code Painters

I've looked at the toolkit you linked, just to read the following in the readme.txt:

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

This toolchain is built and optimized for Cortex-R/M bare metal development.

该工具链专为 Cortex-R/M 裸机开发而构建和优化。

In other words, this toolchain is specifically configured for embedded systems, perhaps with no operating system running at all. In such case, there's no system to provide e.g. standard output where printf()is supposed to write, there's no file system, etc. - you have to link against some library providing these basic services, if you want to use them.

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

That said, your toolkit provides librdimon.alibrary which provides all those basic services. This library is actually a part of libglosscompilation. If you want to link against it, try the following command:

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

arm-none-eabi-gcc --specs=rdimon.specs   -Wl,--start-group -lgcc -lc -lm -lrdimon -Wl,--end-group -o test test.c

This links fine on my PC, but whether it's what you really want is another story (where do you expect to see printf()output, anyway?).

这在我的 PC 上链接良好,但它是否是您真正想要的则是另一回事(printf()无论如何,您希望在哪里看到输出?)。

For you chip you should probably look for a library which redirects the standard output to serial port or provides debug output over JTAG. Alternatively, you can use your custom function e.g. sending debug output to serial console instead of printf()- it's up to you. If you decide on using printf()I suggest reading libglossdocumentation.

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

Also, I suggest looking around for a toolchain which is specifically bundled for STM32 family. Properly configuring all this basic stuff (C library, linker script, etc.) requires a bit of experience.

另外,我建议四处寻找专门为 STM32 系列捆绑的工具链。正确配置所有这些基本内容(C 库、链接描述文件等)需要一些经验。

Edit:Many embedded systems doesn't really use standard C library, starting pretty much from scratch. If you want to go this way, you should pass -nostdlibto your gccinvocation. Of course, you'll no longer have things like printf()available.

编辑:许多嵌入式系统并没有真正使用标准的 C 库,几乎都是从头开始。如果你想走这条路,你应该传递-nostdlib给你的gcc调用。当然,您将不再有printf()可用的东西。

Edit 2:Another way is to use standard library (newlib, I mean) without libglossand provide appropriate stubs for things you do not need. You might want to follow this tutorial, where _readand _writeis implemented over the serial port, and everything else is stubbed. This is most likely what you really want.

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

回答by Shane

I know this is an old question, but I ran into this today when trying to build for an STM32 board. The project I have has some linker scripts (specifically libs.ld). Adding an entry for libnosys.a in this satisfied the linker and I was able to continue.

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

libs.ld:

libs.ld:

 GROUP(
   libgcc.a
   libg.a
   libc.a
   libm.a
   libnosys.a
 )

回答by Peter Teoh

Saving your C program as "myprint.c", I compile it as follows:

将你的 C 程序保存为“myprint.c”,我编译它如下:

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

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

No errors and output is fine.

没有错误,输出很好。

回答by Sergey Starovoitov

There also was such a problem with malloc()and free()function calls in the Eclipse project. I have written firmware for an STM32 microcontroller using Eclipse + GNU for ARM embedded GCC cross compiler + STM32CubeMX for microcontroller periphery initialization and linker script making.

Eclipse 项目中malloc()free()函数调用也存在这样的问题。我已经使用 Eclipse + GNU 为 ARM 嵌入式 GCC 交叉编译器 + STM32CubeMX 为 STM32 微控制器编写了固件,用于微控制器外围初始化和链接器脚本制作。

When I have added missing strings libg.a( * ) and libnosys.a( * ) in the DISCARDsection of .ldscript, my project was build successfully.

当我在脚本的DISCARD部分添加了缺失的字符串libg.a( * ) 和libnosys.a( * ) 时,我的项目构建成功。.ld

回答by Laguna Thangarajah

I had created an RTOS project using CubeMX and added a printf and had the same issue on linking, while debugging using OpenOCD.

我使用 CubeMX 创建了一个 RTOS 项目并添加了一个 printf 并且在使用 OpenOCD 调试时在链接上遇到了同样的问题。

I replaced the printf("Hello ARM World!") with trace_puts("Hello ARM World!"); and had the messages appear in the debug console.

我用 trace_puts("Hello ARM World!") 替换了 printf("Hello ARM World!"); 并让消息出现在调试控制台中。