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

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

问题描述

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

I want create a project for the STM32F217IG microcontroller.

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

So 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.

一旦我这样做了,我尝试创建一个只有两个源文件的非常小的项目:test.c 和 main.c,并且只用它们编写了以下代码:

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

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

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

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

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

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

I did not create any makefile 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

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

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

这真的是问题吗?如果是,我该如何解决?如果不是,错误来自哪里?

Is that really the problem? If yes, how do I fix it? And if not, where is the error coming from?

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

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

首先上项目属性 → C/C++Build设置Cross linker图书馆.我只是添加字母 c 然后错误没有改变,但是命令行末尾有 -lc :

First on the project properties → C/C++BuildSettingsCross linkerlibraries. 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

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

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

其次,我在项目属性中添加了libc.a库→C/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):

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:

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

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 best thing to do). Does that mean the problem is the .elf file creation?

推荐答案

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

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

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

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

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

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.

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

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

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

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

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

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.

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

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.

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

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.

编辑 2: 另一种方法是使用标准库(newlib,我的意思是)而不使用 libgloss 并为您所做的事情提供适当的存根不需要.您可能想关注 本教程,其中_read_write是通过串口实现的,一切否则被存根.这很可能是您真正想要的.

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天全站免登陆