1

我设计了一个用于我的 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在系统库中搜索这个符号。与他的情况不同,这里的符号即使在应该找到它的 avr 系统库中也__mulhi3显示为(未定义)(对于他来自 AVR-GCC 4.7.2 的库 - 我的是 4.8.0),所以我猜是根本没有定义(!?)。我希望它应该在系统库(/usr/avr/lib 和子目录中的文件)中显示为(在该部分中定义)。有小费吗?作为旁注,我使用 CMake 作为构建系统。Ulibgcc.a__mulhi3Ttext.a

编辑:

就像这里和下面的答案中建议的那样,将数学库添加到链接的末尾应该可以解决问题,但是 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
4

2 回答 2

1

您的 CMake target_link_libraries 参数是什么样的?

我的猜测是你需要添加“m”(小写 m)来拉入数学库。

于 2014-02-12T17:57:01.117 回答
1

该符号__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")

to 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 
于 2014-02-14T18:27:01.090 回答