2013-08-31 34 views
2

我想在項目中使用avrfix library,使用Eclipse(v4.2.2)作爲IDE,並使用avr-gcc作爲編譯器。頭文件(avrfix.h)和庫文件(libavrfix.a)都包含在相同的目錄中,該目錄位於項目的搜索路徑以及鏈接程序的庫搜索路徑中。編譯時,我得到了以下錯誤:使用avr-gcc編譯器/鏈接器鏈接avrfix庫中函數的未定義引用

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 

我明白,這意味着連接不正確查找和連接問題的功能(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_w__ATmega328 -lm 

這裏的重要部分是包含-lavrfix命令。我知道鏈接器能夠找到那個庫,因爲如果我嘗試錯誤地讀取avrfix,它會給出一個錯誤,它找不到庫,而不是上面提到的庫。還值得一提的是,我使用我認爲是相同的方法成功地包括libArduino_Duemilanove_w__ATmega328.a庫。

當我看看編譯器生成的.map文件時,我確實看到了一些來自Arduino_Duemilanove_w__ATmega328庫的函數,正如所料(例如malloc)。但是,avrfix庫中沒有函數或對象似乎已將它放入地圖中。搜索「avrfix」在.MAP文件的產量在那裏只提到了一個單行:

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選項,但這似乎無助於我的情況。

如果有人知道發生了什麼,請幫忙!不要猶豫,向我索要更多信息。

問候,

保羅

回答

4

未定義參考`lsincoslk(長,長*)」

這是爲了C++mangled name的參考。

libavrfix.a很有可能將該符號定義爲undecoratedC名稱。你可以通過運行來驗證這個

avr-readelf -Ws libavrfix.a | grep lsincoslk 

如果你看到NNNN T _Z9lsincoslklPl,我的猜測是不正確的。但如果你看到NNNN T lsincoslk,那麼我的猜測是正確的。

看着this versionavrfix.h,我看到它沒有合適的extern "C"衛兵。如果包括此頭爲C++,你必須這樣做:

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

你不必這樣做,如果avrfix開發商關心C++。你可以給他們發送一個補丁到avrfix.h。補丁應該從頭補充一點:

#ifdef __cplusplus 
extern "C" { 
#endif 

這結尾:

#ifdef __cplusplus 
} 
#endif 
+0

這做到了!非常感謝! :) – pmrancuret

+0

@pmrancuret如果答案提供瞭解決方案,那麼您應該接受它。 –

+0

明白了 - 回答接受,再次感謝。 – pmrancuret

相關問題