Я пытаюсь использовать библиотека avrfix в проекте, используя Eclipse (v4.2.2) в качестве IDE и avr-gcc в качестве компилятора. Файл заголовка (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, похоже, не попали в карту. Поиск ‘avrfix’ в файле .map дает только одну строку, где упоминается:
LOAD D:\Documents\Arduino\IMU_Kalman\avrfix\libavrfix.a
Возможно ли проблема с порядком ссылок? Я в недоумении из-за того, что здесь может пойти не так. Является ли библиотека avrfix несовместимой с компилятором avr-gcc, который я использую по какой-либо причине? Я также немного незнаком с бинарными парсерами (или если они вообще имеют какое-то отношение к моей проблеме), но я попытался выбрать несколько разных парсеров (включая парсер GNU Elf) в C / C ++ Build-> Settings-> Вкладка «Двоичные парсеры» в свойствах проекта. Для получения дополнительной информации у меня есть весь проект (хотя он находится в стадии разработки, на ранних стадиях) на github Вот. Я пытался искать помощь в других темах, но не могу найти много информации, специфичной для библиотеки avrfix, в моем приложении. В одном другом потоке я нашел рекомендацию использовать опцию —export-all-symbols при вызове компоновщика, но это, похоже, не помогло моей ситуации.
Пожалуйста, помогите, если кто-нибудь знает, что происходит! Не стесняйтесь спрашивать дополнительную информацию от меня.
С Уважением,
Павел
неопределенная ссылка на `lsincoslk (long, long *) ‘
Это ссылка на C++
искаженное имя.
Вполне вероятно, что 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
Других решений пока нет …