我设计了一个静态库供我的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'
我发现对同一个问题here进行了一次有趣的调查,但由于他的解决方案完全是关于ADA的,所以我不知道如何在我的情况下修复它,这是一个C
应用程序。它给了我很好的提示,比如使用avr-nm
在系统库中搜索这个符号。与他的情况不同,这里符号__mulhi3
显示为U
(未定义),即使在应该找到它的avr系统库中(libgcc.a
来自AVR-GCC 4.7的libs .2 - 我的是4.8.0),所以我猜__mulhi3
根本没有定义(!?)。我希望它在系统库中显示为T
(在text
部分中定义)(/ usr / avr / lib和subdirs中的.a
文件)。有小费吗?作为旁注,我使用CMake作为构建系统。
修改
与建议的here一样,在下面的答案中,将数学库添加到链接的末尾可能会解决问题,但是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
答案 0 :(得分:1)
您的CMake target_link_libraries参数是什么样的?
我的猜测是你需要添加“m”(小写m)来拉入数学库。
答案 1 :(得分:1)
符号__mulhi3
确实由libgcc.a
定义,就像先前由this link暗示的那样。问题是,当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
的{{1}}的加载,这意味着它应该在其他地方定义。在检查了avr-gcc的包裹内容之后,我发现U
位于libgcc.a
。
最终结果是整个问题与CMake没有被指向正确的地方寻找/usr/lib/gcc/avr/4.8.0
更相关,我通过添加这一行开始工作:
libgcc.a
到set(CMAKE_EXE_LINKER_FLAGS "-L /usr/lib/gcc/avr/4.8.0")
,这会导致以下成功的链接器调用:
CMakeLists.txt