在Linux上编译时未定义的引用mempcy@GLIBC_2.14

问题描述 投票:7回答:5

我试图移植一个应用程序来驱动一个使用ftdi2332h芯片的设备从Windows到Linux。我在ubuntu 10.04系统per these instructions上安装了libftd2xx库。

当我尝试编译任何示例程序时,我收到以下错误:

/usr/local/lib/libftd2xx.so: undefined reference to `memcpy@GLIBC_2.14'
collect2: ld returned 1 exit status

有关如何解决这个问题的指导原则?

c++ porting undefined-reference ftdi
5个回答
4
投票

自述文件提到了Ubuntu 12.04,它带有glibc 2.15。您使用的是Ubuntu 10.04,它带有glibc 2.11.1。你看到的错误信息告诉你一些二进制文件(这里很可能是libftd2xx.so)你依赖于一个比你链接更新的glibc,这是合乎逻辑的,考虑到前面的事实。

从源代码重新编译libftd2xx.so与系统的glibc版本(可能不是一个选项,因为它只是二进制),或者更新你的操作系统。 Ubuntu 10.04很老了。

作为最后的手段(如果你喜欢,只是尝试这样做,euhm,用大锤击打你的手指),你可以为你的系统编译一个更新的glibc,并安装在像/opt这样的地方。


2
投票

mempcy@GLIBC_2.14被称为版本符号。 Glibc使用它们,而其他运行时库如musl do not

mempcy@GLIBC_2.14在Linux上编译时的重要性是由于Glibc改变了memcpy在2012年的工作方式.memcpy用于复制字节{begin→end}(低内存地址到高内存地址)。 Glibc 2.13提供了一个优化的memcpy,它在某些平台上复制了{end→begin}。我相信“一些平台”包括带有SSE4.1的英特尔机器。然后,Glibc 2.14提供了一个恢复{begin→end}行为的memcpy

有些程序依赖于{begin→end}副本。当程序使用重叠缓冲区时,memcpy会产生未定义的行为。在这种情况下,一个程序应该使用memmove,但由于发生了{begin→end}的副本,它们已经过了。另请参阅Strange sound on mp3 flash website(由于Adobe Flash),Glibc change exposing bugs(在LWN上),The memcpy vs memmove saga和朋友。

要修复它,您似乎可以将以下内容添加到源代码中:

__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");

也许类似以下内容。然后在项目中包含额外的源文件。

$ cat version.c

__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");

0
投票

升级到Ubuntu 12.04。我使用Qt发生了同样的事情,结果发现glibc库太旧了。谷歌搜索表明,试图升级glibc是一个非常危险的主张。


0
投票

您可以下载并编译libc,并在/opt/lib/libcX/libc.so.6下安装。然后,你可以有一个脚本:

LD_LIBRARY_PATH=/opt/lib/libcX:/lib/:/usr/lib:/usr/share/lib
./your_program

0
投票

我不确定,但如果它是你正在使用的交叉编译器,你必须在某处安装基本库的兼容版本(不是在/usr/include/usr/lib中),你必须确保编译器使用它们,而不是本机编译器的那些。并且您必须确保整个工具链与版本兼容。 (我知道这不是一个非常完整的答案,但我知道这一切。)

© www.soinside.com 2019 - 2024. All rights reserved.