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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12286460/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:07:37  来源:igfitidea点击:

Undefined reference to mempcy@GLIBC_2.14 when compiling on Linux

c++portingundefined-referenceftdi

提问by user1487551

I am trying to port an application to drive a device that uses an ftdi2332h chip from windows to linux. I installed the libftd2xx library on an ubuntu 10.04 system per these instructions.

我正在尝试移植一个应用程序来驱动一个使用 ftdi2332h 芯片的设备从 windows 到 linux。我按照这些说明在 ubuntu 10.04 系统上安装了 libftd2xx 库。

When I try to compile any of the sample programs I get the following error:

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

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

Any guidelines on how to fix this?

有关如何解决此问题的任何指南?

回答by jww

The mempcy@GLIBC_2.14is called a versioned symbol. Glibc uses them while other runtime libraries like musl do not.

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

The significance of mempcy@GLIBC_2.14when compiling on Linux is due to Glibc changing the way memcpyworked back in 2012. memcpyused to copy bytes {begin → end} (low memory address to high memory address). Glibc 2.13 provided an optimized memcpythat copied {end → begin} on some platforms. I believe "some platforms" included Intel machines with SSE4.1. Then, Glibc 2.14 provided a memcpythat restored the {begin → end} behavior.

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

Some programs depended upon the {begin → end} copy. When programs used overlapping buffers then memcpyproduced undefined behavior. In this case a program should have used memmove, but they were getting by due to a copy that occurred {begin → end}. Also see Strange sound on mp3 flash website(due to Adobe Flash), Glibc change exposing bugs(on LWN), The memcpy vs memmove sagaand friends.

一些程序依赖于 {begin → end} 副本。当程序使用重叠缓冲区时,会memcpy产生未定义的行为。在这种情况下,程序应该使用memmove,但由于发生了 {begin → end} 的副本,它们已经过去了。另请参阅mp3 flash 网站上的奇怪声音(由于 Adob​​e Flash)、Glibc 更改暴露错误(在 LWN 上)、memcpy vs memmove 传奇和朋友。

To fix it it looks like you can add the following to your source code:

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

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

Maybe something like the following. Then include the extra source file in your project.

也许像下面这样。然后在您的项目中包含额外的源文件。

$ cat version.c

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

回答by rubenvb

The readme mentions Ubuntu 12.04, which comes with glibc 2.15. You are using Ubuntu 10.04, which comes with glibc 2.11.1. The error message you are seeing is telling you some binary (here it is most likely libftd2xx.so) you linked to relies on a newer glibc than you are linking, which is logical, given the previous fact.

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

Either recompile libftd2xx.sofrom source against your system's glibc version (probably not an option, as it's binary only), or update your OS. Ubuntu 10.04 is quite old.

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

As a last resort (and only try to do this if you like, euhm, hitting your fingers with a sledgehammer), you can compile a newer glibc for your system, and install it somewhere like /opt.

作为最后的手段(并且只有在您愿意时才尝试这样做,呃,用大锤敲打您的手指),您可以为您的系统编译一个更新的 glibc,并将其安装在类似/opt.

回答by Gary Cates

This is an Oracle Bug with "opatchauto". See this Url, https://dba010.com/2019/06/24/19cgi-12crdbms-opatchauto-re-link-fails-on-target-procob/. WORK-AROUND: Manually use “opatch”, instead of “opatchauto” for each of the applicable DB Patches.

这是一个带有“opatchauto”的 Oracle 错误。请参阅此网址,https://dba010.com/2019/06/24/19cgi-12crdbms-opatchauto-re-link-fails-on-target-procob/。变通方法:为每个适用的数据库补丁手动使用“opatch”,而不是“opatchauto”。

回答by perreal

You can download and compile libc, and install under /opt/lib/libcX/libc.so.6. Then, you can have a script:

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

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

回答by James Kanze

I'm not sure, but if it is a cross-compiler you're using, you must have compatible versions of the basic libraries installed somewhere (notin /usr/includeand /usr/lib), and you must ensure that the compiler uses them, and not the ones for the native compiler. And you must ensure that the entire tool chain is version compatible. (And I know that this isn't a very complete answer, but it's all I know.)

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

回答by Matt Phillips

Upgrade to Ubuntu 12.04. I had the same thing happen using Qt, it turned out the glibc library was too old. Googling around indicated that trying to upgrade glibc on one's own is a very dangerous proposition.

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