undefined references to functions in linked avrfix library using avr-gcc compiler/linker

ぃ、小莉子 提交于 2019-12-24 02:07:09

问题


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


回答1:


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


来源:https://stackoverflow.com/questions/18549526/undefined-references-to-functions-in-linked-avrfix-library-using-avr-gcc-compile

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!