неопределенные ссылки на функции в связанной библиотеке avrfix с использованием компилятора / компоновщика avr-gcc

Я пытаюсь использовать библиотека 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 при вызове компоновщика, но это, похоже, не помогло моей ситуации.

Пожалуйста, помогите, если кто-нибудь знает, что происходит! Не стесняйтесь спрашивать дополнительную информацию от меня.

С Уважением,

Павел

2

Решение

неопределенная ссылка на `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
4

Другие решения

Других решений пока нет …