使用eclipse的C项目的链接器错误 [英] Linker error on a C project using eclipse

查看:259
本文介绍了使用eclipse的C项目的链接器错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



然后我安装了eclipse和 GNU for ARM嵌入式gcc交叉编译器。我不认为这是代码原料,我用它,因为它支持浮点数和代码草原没有。



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

  #include < stdlib.h中> 
#include< stdio.h>
int main(void)
{
printf(hellowolrd);
return 0;

}

我更改了项目属性中的line命令来替换gcc通过arm-none-eabi-gcc,然后尝试编译该项目。



我没有自己创建任何make文件,我使用eclipse中的自动创建。 p>

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

  make all 
'建立目标:test3'
'调用:跨GCC链接器'
arm-none-eabi-gcc -otest3./ main.o ./test3.o

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6.2 / .. /../../../arm-none-eabi/lib\libc.a(lib_a-exit.o):在函数`exit'中:
exit.c :(。text.exit + 0x2c):未定义的引用`_exit'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6.2 /。 ./../../../arm-none-eabi/lib\libc.a(lib_a-sbrkr.o):在函数`_sbrk_r'中:
sbrkr.c :(。文本._sbrk_r + 0x18):未定义的引用`_sbrk'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6。 2 /../../../../ arm-none-eabi / lib\libc.a(lib_a-writer.o):在函数`_write_r'中:
writer.c :(。 text._write_r + 0x20):未定义的引用`_write'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6 .2 /../../../../ arm-none-eabi / lib\libc.a(lib_a-nearest.o):在函数`_close_r'中:
clos.c :( .text._close_r + 0x18):未定义的引用`_close'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6.2 /../../../../ arm-none-eabi / lib\libc.a(lib_a-fstatr.o):在函数`_fstat_r'中:
fstatr.c: (.text._fstat_r + 0x1c):未定义的引用`_fstat'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi /4.6.2/../../../../arm-none-eabi/lib\libc.a(lib_a-isattyr.o):在函数`_isatty_r'中:
isa ttyr.c :( text._isatty_r + 0x18):未定义的引用`_isatty'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm -none-eabi / 4.6.2 /../../../../ arm-none-eabi / lib\libc.a(lib_a-lseekr.o):在函数`_lseek_r'中:
lseekr.c :(。text._lseek_r + 0x20):未定义的引用`_lseek'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6.2 /../../../../ arm-none-eabi / lib\libc.a(lib_a-readr.o):在函数`_read_r'中:
readr.c :( .text._read_r + 0x20):未定义的引用`_read'

collect2:ld返回1退出状态

make:*** [ test3] Erreur 1

我看着互联网,发现这可能是一个系统调用问题。但是我不知道如何将这个库添加到我的linux项目中。



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



编辑



,我尝试链接c运行时库。在eclipse上,我有两个解决方案:
首先在项目属性 - > C / C ++ build-> Settings-> Cross linker-> libraries我只是添加字母c,然后错误不会改变但在命令行末尾有-lc:

 使所有
'构建目标:test3'
'调用:跨GCC链接器
arm-none-eabi-gcc -otest3./main.o ./test3.o -lc

c:/程序文件/ 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):在函数`exit'中:
exit.c :( .text.exit + 0x2c):未定义的引用`_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):在函数`_sbrk_r'中:
sbrkr.c :( .text._sbrk_r + 0x18):未定义的引用`_sbrk'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6.2 /。在/ _ / / / + 0x20):未定义的引用`_write'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6.2 / ../../../../arm-none-eabi/lib\libc.a(lib_a-closer.o):在函数`_close_r'中:
clos.c :(。text。 _close_r + 0x18):未定义的引用`_close'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6.2 /../../../../arm-none-eabi/lib\libc.a(lib_a-fstatr.o):在函数`_fstat_r'中:
fstatr.c :(。文本._fstat_r + 0x1c):未定义的引用`_fstat'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6。 2 /../../../../ arm-none-eabi / lib\libc.a(lib_a-isattyr.o):在函数`_isatty_r'中:
isattyr.c :(。 text._isatty_r + 0x18):未定义的引用`_isatty'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm- no-eabi / 4.6.2 /../../../../ arm-none-eabi / lib\libc.a(lib_a-lseekr.o):在函数`_lseek_r'中:
lseekr.c :(。text._lseek_r + 0x20):未定义的引用`_lseek'

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm -none-eabi / 4.6.2 /../../../../ arm-none-eabi / lib\libc.a(lib_a-readr.o):在函数`_read_r'中:
readr.c :( .text._read_r + 0x20):未定义的引用`_read'

collect2:ld返回1退出状态
make:*** [test3] Erreur 1

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



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

  make all 
'构建目标:test3'
'调用:跨GCC链接器
arm-none-eabi-gcc -otest3./main.o ./test3.o -l​​C:/ Program\ Files / GNU\ Tools\ ARM \\ Embedded / 4.6\ 2012q4 / arm-none-eabi / lib / armv7-m / libc.a

c:/程序文件/ gnu工具arm embedded / 4.6 2012q4 / bin /../ lib / gcc / arm-none-eabi / 4.6.2 /../../../../ arm-none-eabi / bin / ld.exe:找不到-lC:/ Program\ Files / GNU \ Tools\ ARM\ Embedded / 4.6\ 2012q4 / arm-none-eabi / lib / armv7-m / libc.a

collect2:ld返回1退出状态
make :*** [test3] Erreur 1

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



哦和非常interresting的事实:
我只在调试模式下得到错误,如果我在发布模式一切都可以,我没有任何错误(如果我添加libc.a,execpt,那么我认为这不是好事)。
这是否意味着问题是.elf文件创建?

解决方案

我看过你链接的工具包,只是在 readme.txt 中阅读以下内容:


这个工具链是为Cortex-R / M裸机开发构建和优化。


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



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

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

这个链接在我的电脑上很好,但无论是你真正想要的还是另一个故事(你希望看到哪里你可以看到 printf()输出,反正?)。



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



另外,我建议环顾一下专门为STM32系列捆绑的工具链。正确配置所有这些基本的东西(C库,链接器脚本等)需要一点经验。



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



编辑2:另一种方式是使用标准库( newlib )没有 libgloss ,并为不需要的东西提供适当的存根。您可能需要遵循本教程,其中 _read _write 通过串行端口实现,其他所有东西都被保留。这很可能是你真正想要的。


I want create a project for an STM32F217IG microcontroller.

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 the code sourcery does not.

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:

#include <stdlib.h>
#include <stdio.h>
int main (void)
{
    printf("hellowolrd");
    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.

I did not create any make file myself, I used the automatic creation in 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.

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

edit

As someone suggested, I tried "linking" the c runtime library. On eclipse it seems I have two solutions to do it: first on the project properties->C/C++ build->Settings-> Cross linker->libraries I just add the letter c and then the error does not change but there is -lc at the end of the command line:

 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 what it means to add the C runtime library

Second I added the libc.a library in the project properties->C/C++ general->Path and symbols -> Libraries and here is what I get (completely different):

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 very interresting 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 (execpt if I add the libc.a then I think this is not the good thing to do). Does that means the problem is the .elf file creation?

解决方案

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

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

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.

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

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?).

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 libgloss documentation.

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.

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 -nostdlib to your gcc invocation. Of course, you'll no longer have things like printf() available.

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

这篇关于使用eclipse的C项目的链接器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆