使用 avr-gcc 编译器/链接器对链接的 avrfix 库中函数的未定义引用 [英] undefined references to functions in linked avrfix library using avr-gcc compiler/linker

查看:33
本文介绍了使用 avr-gcc 编译器/链接器对链接的 avrfix 库中函数的未定义引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在项目中使用 avrfix 库 ,使用 Eclipse (v4.2.2) 作为IDE 和 avr-gcc 作为编译器.头文件(avrfix.h)和库文件(libavrfix.a)都包含在同一个目录中,该目录在项目的搜索路径以及链接器的库搜索路径中.编译时出现以下错误:

D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:359:对`lsincoslk(long, long*)'的未定义引用D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:360:对`lsincoslk(long, long*)'的未定义引用D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:361:对`lmullkD(long, long)'的未定义引用D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:362:对`lmullkD(long, long)'的未定义引用D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:365:对`lmullkD(long, long)'的未定义引用D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:365:对`lmullkD(long, long)'的未定义引用D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:365:对`lmullkD(long, long)'的未定义引用./HMC5883/HMC5883.o:D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:367:更多未定义的对`lmullkD(long, long)'的引用如下./HMC5883/HMC5883.o:在函数‘HMC5883::Calc_Heading(long, long)’中:D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:369:未定义对`latan2lk(long, long)'的引用制作:*** [IMU_Kalman.elf] 错误 1

我理解这意味着链接器没有正确查找和链接相关函数(lsincoslk、lmullkD、latan2lk).这些函数应该位于 avrfix 库中.为了完整起见,这里是使用的链接器调用:

avr-gcc -Os -Wl,--gc-sections -Wl,-Map,"IMU_Kalman.map",--cref --export-all-symbols -L"D:\Documents\Arduino\IMU_Kalman\avrfix" -L"D:\Documents\Arduino\IMU_Kalman\Board_Support_Library" -mmcu=atmega328p -o"IMU_Kalman.elf" ./Wire/Wire.o ./Wire/twi.o ./SPI/SPI.o ./MPU6000/MPU6000.o ./Kalman_Filters/GyroKalman.o ./HMC5883/HMC5883.o ./GlobalVariables.o ./IMU_Kalman.o -lavrfix -lArduino_Duemilanove_w8_ATmega3

这里的重要部分是包含 -lavrfix 命令.我知道链接器能够找到那个库,因为如果我尝试拼错 avrfix,它会给出一个错误,表明它找不到库,而不是上面提到的库.还值得一提的是,我使用我认为相同的方法成功地包含了 libArduino_Duemilanove_w__ATmega328.a 库.

当我查看编译器生成的 .map 文件时,我确实看到了一些来自 Arduino_Duemilanove_w__ATmega328 库的函数,正如预期的那样(例如 malloc).但是,avrfix 库中的任何函数或对象似乎都没有进入映射.在 .map 文件中搜索avrfix"只会得到一行提到它的地方:

LOAD D:\Documents\Arduino\IMU_Kalman\avrfix\libavrfix.a

链接顺序可能有问题吗?我不知道这里可能出了什么问题.avrfix 库是否由于某种原因与我使用的 avr-gcc 编译器不兼容?我也有点不熟悉二进制解析器(或者它们甚至与我的问题有任何关系),但我尝试在 C/C++ Build->Settings-> 中选择多个不同的解析器(包括 GNU Elf Parser)项目属性中的二进制解析器选项卡.有关更多信息,我在 github here.我尝试在其他线程中寻求帮助,但似乎无法在我的应用程序中找到许多特定于 avrfix 库的信息.在另一个线程中,我找到了在链接器调用中使用 --export-all-symbols 选项的建议,但这似乎对我的情况没有帮助.

如果有人知道发生了什么,请帮忙!不要犹豫,向我询问更多信息.

问候,

保罗

解决方案

对`lsincoslk(long, long*)'的未定义引用

这是对 C++ 错误名称的引用.>

很可能 libavrfix.a 将该符号定义为 未修饰 C 名称.您可以通过运行来验证这一点

avr-readelf -Ws libavrfix.a |grep lsincoslk

如果你看到NNNN T _Z9lsincoslklPl,我的猜测是错误的.但是如果你看到NNNN T lsincoslk,那么我的猜测是正确的.

查看 保护.当您将此标头包含到 C++ 中时,您必须这样做:

extern "C" {#include "avrfix.h"}

如果 avrfix 开发人员关心 C++,您就不必这样做.您可以将补丁发送到 avrfix.h.补丁应该在开头添加:

#ifdef __cplusplus外部C"{#万一

最后是:

#ifdef __cplusplus}#万一

I am trying to use the avrfix library in a project, using Eclipse (v4.2.2) as the IDE and avr-gcc as the compiler. Both the header file (avrfix.h) and the library file (libavrfix.a) are included in the same directory, which is in the project's search path as well as the linker's library search path. When compiling, i get the following errors:

D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:359: undefined reference to `lsincoslk(long, long*)'
D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:360: undefined reference to `lsincoslk(long, long*)'
D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:361: undefined reference to `lmullkD(long, long)'
D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:362: undefined reference to `lmullkD(long, long)'
D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:365: undefined reference to `lmullkD(long, long)'
D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:365: undefined reference to `lmullkD(long, long)'
D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:365: undefined reference to `lmullkD(long, long)'
./HMC5883/HMC5883.o:D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:367: more undefined references to `lmullkD(long, long)' follow
./HMC5883/HMC5883.o: In function `HMC5883::Calc_Heading(long, long)':
D:\Documents\Arduino\IMU_Kalman\Release/../HMC5883/HMC5883.cpp:369: undefined reference to `latan2lk(long, long)'
make: *** [IMU_Kalman.elf] Error 1

I understand that this implies the linker is not properly finding and linking the functions in question (lsincoslk, lmullkD, latan2lk). Those functions should be located in the avrfix library. To be complete, here is the linker invocation used:

avr-gcc -Os -Wl,--gc-sections  -Wl,-Map,"IMU_Kalman.map",--cref --export-all-symbols -L"D:\Documents\Arduino\IMU_Kalman\avrfix" -L"D:\Documents\Arduino\IMU_Kalman\Board_Support_Library" -mmcu=atmega328p  -o"IMU_Kalman.elf"  ./Wire/Wire.o ./Wire/twi.o  ./SPI/SPI.o  ./MPU6000/MPU6000.o  ./Kalman_Filters/GyroKalman.o  ./HMC5883/HMC5883.o  ./GlobalVariables.o ./IMU_Kalman.o   -lavrfix -lArduino_Duemilanove_w__ATmega328 -lm

The important piece here is that the -lavrfix command is included. I know the linker is able to find that library, because if I try mispelling avrfix, it gives an error that it cannot find the library, instead of the ones mentioned above. It is also worth mentioning that I am including the libArduino_Duemilanove_w__ATmega328.a library succesfully, using what I think is same method.

When I take a look at the compiler's generated .map file, I do see several functions which come from the Arduino_Duemilanove_w__ATmega328 library, as expected (malloc, for instance). However, no functions or objects from the avrfix library seem to have made it into the map. Searching 'avrfix' in the .map file yields only one single line where it is mentioned:

LOAD D:\Documents\Arduino\IMU_Kalman\avrfix\libavrfix.a

Is it possible there is a problem with link order? I'm at a loss for what may be going wrong here. Is the avrfix library incompatible with the avr-gcc compiler I am using for some reason? I'm also a bit unfamiliar with binary parsers (or if they even have anything to do with my problem), but I have tried selecting multiple different parsers (including the GNU Elf Parser) in the C/C++ Build->Settings->Binary Parsers tab in the project properties. For more info, I have the entire project (although it's a work in progress, in early stages) on github here. I've tried looking for help in other threads, but can't seem to find much information specific to the avrfix library in my application. In one other thread, I found a recommendation to use the --export-all-symbols option in the linker evocation, but that didn't seem to help my situation.

Please help if anyone knows what's going on! Don't hesitate to ask for more information from me.

Regards,

Paul

解决方案

undefined reference to `lsincoslk(long, long*)'

This is a reference to C++ mangled name.

It is likely that the libavrfix.a defines that symbol as undecorated C name. You can verify this by running

avr-readelf -Ws libavrfix.a | grep lsincoslk

If you see NNNN T _Z9lsincoslklPl, my guess is incorrect. But if you see NNNN T lsincoslk, then my guess is correct.

Looking at this version of avrfix.h, I see that it lacks proper extern "C" guards. When you include this header into C++, you must do this:

extern "C" {
#include "avrfix.h"
}

You wouldn't have to do that if avrfix developers cared about C++. You can send them a patch to avrfix.h. The patch should add this at the beginning:

#ifdef __cplusplus
extern "C" {
#endif

and this at the end:

#ifdef __cplusplus
}
#endif

这篇关于使用 avr-gcc 编译器/链接器对链接的 avrfix 库中函数的未定义引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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