2

IDE として Eclipse (v4.2.2) を使用し、コンパイラとして avr-gcc を使用して、プロジェクトでavrfix ライブラリを使用しようとしています。ヘッダー ファイル (avrfix.h) とライブラリ ファイル (libavrfix.a) の両方が同じディレクトリに含まれています。このディレクトリは、プロジェクトの検索パスとリンカーのライブラリ検索パスにあります。コンパイル時に、次のエラーが発生します。

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 ライブラリの関数やオブジェクトはマップに含まれていないようです。.map ファイルで「avrfix」を検索すると、それが言及されている 1 行のみが生成されます。

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

リンクの順序に問題がある可能性はありますか? ここで何がうまくいかないのか途方に暮れています。avrfix ライブラリは、何らかの理由で使用している avr-gcc コンパイラと互換性がありませんか? 私はバイナリパーサーにも少し慣れていません (または、それらが私の問題と関係がある場合)、C/C++ Build->Settings-> で複数の異なるパーサー (GNU Elf Parser を含む) を選択しようとしましたプロジェクト プロパティの [バイナリ パーサー] タブ。詳細については、プロジェクト全体を githubで公開しています(初期段階では進行中ですが)。. 他のスレッドでヘルプを探してみましたが、アプリケーションの avrfix ライブラリに固有の情報があまり見つかりません。別のスレッドで、リンカーの呼び出しで --export-all-symbols オプションを使用することを推奨しているのを見つけましたが、それは私の状況には役立たないようです。

事情を知っている方は助けてください!私からの詳細情報を求めることを躊躇しないでください。

よろしく、

ポール

4

1 に答える 1

4

`lsincoslk(long, long*)' への未定義の参照

これはC++ マングルされた nameへの参照です。

libavrfix.aは、そのシンボルを装飾 されていない名前として定義している可能性がありますC。実行することでこれを確認できます

avr-readelf -Ws libavrfix.a | grep lsincoslk

が表示されている場合NNNN T _Z9lsincoslklPl、私の推測は正しくありません。しかし、あなたが見るならNNNN T lsincoslk、私の推測は正しいです.

このバージョンのを見ると、適切なガードavrfix.hが欠けていることがわかります。extern "C"このヘッダーを に含める場合はC++、次のようにする必要があります。

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

avrfix開発者がC++. にパッチを送ることができますavrfix.h。パッチはこれを最初に追加する必要があります。

#ifdef __cplusplus
extern "C" {
#endif

そして最後にこれ:

#ifdef __cplusplus
}
#endif
于 2013-08-31T23:15:26.523 に答える