Сбой связывания приложения 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), чтобы получить в математической библиотеке.