Сбой связывания приложения C с "неопределенной ссылкой на __mulhi3"

Я разработал статическую библиотеку для использования в моих проектах AVR, но у меня возникают проблемы с ее привязкой к приложению. Он сообщает об этой ошибке:

libteleobjects/libteleobjects.a(telesignals.c.obj): In function `telesignal_get_event_data':                                                               
/home/claudio/git/ucp-usc64/libteleobjects/telesignals.c:559: undefined reference to `__mulhi3'
/home/claudio/git/ucp-usc64/libteleobjects/telesignals.c:561: undefined reference to `__mulhi3'
/home/claudio/git/ucp-usc64/libteleobjects/telesignals.c:561: undefined reference to `__mulhi3'
/home/claudio/git/ucp-usc64/libteleobjects/telesignals.c:561: undefined reference to `__mulhi3'

Я нашел интересное исследование той же проблемы здесь, но так как его решение полностью связано с ADA, я не знаю, как это исправить в моем случае, который является C приложение. Это дало мне хорошие советы, хотя, как с помощью avr-nm искать этот символ в системных библиотеках. В отличие от его случая, здесь символ __mulhi3 отображается как U (не определено) даже в библиотеках системы AVR, где он должен был быть найден (libgcc.a для его библиотек из AVR-GCC 4.7.2 - мой 4.8.0), так что я думаю, __mulhi3 не определяется вообще (!?). Я ожидаю, что это должно выглядеть как T (определяется в text раздел) в системе libs (.a файлы в /usr/avr/lib и subdirs). Какие-нибудь советы? В качестве идентификатора я использую CMake в качестве системы сборки.

РЕДАКТИРОВАТЬ:

Как предложено здесь и в ответе ниже, добавление математической библиотеки в конец связывания, возможно, решит проблему, но CMake уже делает это, и она пока не работает:

Linking C executable ucp-usc64.elf
/usr/bin/cmake -E cmake_link_script CMakeFiles/ucp-usc64.dir/link.txt --verbose=1
/usr/bin/avr-gcc  -g -Os       -mcall-prologues -ffunction-sections -fdata-sections -Os -DNDEBUG -w -mcall-prologues -ffunction-sections -fdata-sections  -Wl,--gc-sections -lm -Wl,--gc-sections -lm -mmcu=atmega644p  CMakeFiles/ucp-usc64.dir/main.c.obj CMakeFiles/ucp-usc64.dir/modutr_callbacks.c.obj  -o ucp-usc64.elf  -lc -lm avr-drivers/libavr_drivers.a modutr-slave/lib/libmodutr_slave.a libteleobjects/libteleobjects.a -lc -lm 
libteleobjects/libteleobjects.a(telesignals.c.obj): In function `telesignal_get_event_data':
/home/claudio/git/ucp-usc64/libteleobjects/telesignals.c:559: undefined reference to `__mulhi3'
/home/claudio/git/ucp-usc64/libteleobjects/telesignals.c:561: undefined reference to `__mulhi3'
/home/claudio/git/ucp-usc64/libteleobjects/telesignals.c:561: undefined reference to `__mulhi3'
/home/claudio/git/ucp-usc64/libteleobjects/telesignals.c:561: undefined reference to `__mulhi3'
collect2: error: ld returned 1 exit status

2 ответа

Решение

Символ __mulhi3 действительно определяется libgcc.a, как и ранее намекнул по этой ссылке. Проблема заключалась в том, что, когда переменная CMake CMAKE_BUILD_TYPE была установлена ​​в Release, используются следующие флаги (устанавливаемые через CMAKE_CXX_FLAGS_RELEASE):

-Os -DNDEBUG -mcall-prologues -ffunction-sections -fdata-sections -fno-exceptions

и оказывается использование оптимизации -Os вызывает внутреннюю функцию GCC __mulhi3 использоваться. В той ситуации как-то CMake не искал libgcc.a в том месте, где он находится в моей системе, которая /usr/lib/avr/gcc/4.8.0/libgcc.a,

Я уже знал заранее undefined reference ошибки всегда случаются, когда библиотека или объектный файл, определяющий символ, не связаны между собой, и все, кто мне помогал, тоже указывали в правильном направлении, но я был действительно введен в заблуждение тем фактом, что искал libgcc.a в неправильном месте, как это:

cd /usr/avr/lib
find -name "*.a" -exec avr-nm {} \; | grep "__mulhi3"

Это было просто возвращение множества __mulhi3 помечен как U, что означало, что это должно быть определено где-то еще. Просто после проверки содержимого моего пакета на avr-gcc я нашел libgcc.a был размещен в /usr/lib/gcc/avr/4.8.0,

Оказывается, в конце концов, вся проблема была больше связана с тем, что CMake не указал правильное место для поиска. libgcc.a, который я получил, добавив строку:

set(CMAKE_EXE_LINKER_FLAGS "-L /usr/lib/gcc/avr/4.8.0")

в CMakeLists.txt, который вызывает следующий и успешный вызов компоновщика:

/usr/bin/avr-gcc  -Wall -Os -DNDEBUG -w -mcall-prologues -ffunction-sections -fdata-sections  -L /usr/lib/gcc/avr/4.8.0 -Wl,--gc-sections -lm -mmcu=atmega644p  CMakeFiles/ucp-usc64.dir/main.c.obj CMakeFiles/ucp-usc64.dir/modutr_callbacks.c.obj  -o ucp-usc64.elf  -lc -lm avr-drivers/libavr_drivers.a libteleobjects/libteleobjects.a modutr-slave/lib/libmodutr_slave.a -lc -lm 

Как выглядит ваш аргумент CMake target_link_libraries?

Я предполагаю, что вам нужно добавить "m" (строчные буквы m), чтобы получить в математической библиотеке.

Другие вопросы по тегам