我试图移植一个应用程序来驱动一个使用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
有关如何解决这个问题的指导原则?
自述文件提到了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
这样的地方。
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");
升级到Ubuntu 12.04。我使用Qt
发生了同样的事情,结果发现glibc库太旧了。谷歌搜索表明,试图升级glibc是一个非常危险的主张。
您可以下载并编译libc,并在/opt/lib/libcX/libc.so.6
下安装。然后,你可以有一个脚本:
LD_LIBRARY_PATH=/opt/lib/libcX:/lib/:/usr/lib:/usr/share/lib
./your_program
我不确定,但如果它是你正在使用的交叉编译器,你必须在某处安装基本库的兼容版本(不是在/usr/include
和/usr/lib
中),你必须确保编译器使用它们,而不是本机编译器的那些。并且您必须确保整个工具链与版本兼容。 (我知道这不是一个非常完整的答案,但我知道这一切。)