关于交叉编译出现的undefined reference to `fcntl64@GLIBC_2.28'错误

我是用arm-linux-gnueabi-gcc在Ubuntu上交叉编译RabbitMQ-C
目的是得到动态库,然后放到我自己的开发环境上使用

基本环境:
ubuntu18.04 虚拟机
gcc-arm-8.3-2019.02-x86_64-arm-linux-gnueabi 环境变量已经导入
RabbitMQ-C GIT源代码 修改了相应的CMakeList文件
CMake工具

目前我的虚拟机上将libc升级到了2.28版本

安装README的文档,将RabbitMQ-C进行编译,并得到了.SO动态库

随后我将动态库放到我的开发工具eclipse里,进行我的代码编译

在编译后,出现了......../lib/librabbitmq.so: undefined reference to `fcntl@GLIBC_2.28'

目前毫无头绪,希望有懂交叉编译的帮忙分析一下,谢谢

这种你要么用静态库librabbitmq.a,基本上能解决问题.
如果你用动态库,我建议你要把跨平台的相关依赖库都放到你的工程里,因为虚拟机ubuntu下的glibc版本不一致,要么就是arm-linux-gnueabihf 版本不一致

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
这个错误提示表明在编译你的代码时找不到 fcntl64@GLIBC_2.28 这个函数的定义。这个函数是在 GLIBC 2.28 版本中引入的,因此你需要确保你的编译器和链接器使用的是 GLIBC 2.28 或更高版本。你可以尝试以下几个方法解决这个问题:

  1. 检查编译器和链接器的版本

确保你的编译器和链接器使用的是 GLIBC 2.28 或更高版本。你可以使用以下命令检查你的编译器和链接器的版本:

arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-ld --version

如果它们的版本低于 GLIBC 2.28,请更新它们或升级你的操作系统。

  1. 指定 GLIBC 版本

你可以在编译和链接时指定 GLIBC 版本,以确保使用正确的库。例如,在编译时,可以使用以下命令:

arm-linux-gnueabi-gcc -march=armv7-a -mfloat-abi=hard -mfpu=neon-vfpv4 -Wl,--rpath-link=/path/to/glibc-2.28/lib -Wl,--dynamic-linker=/path/to/glibc-2.28/lib/ld-linux-armhf.so.2 -L/path/to/glibc-2.28/lib -I/path/to/glibc-2.28/include -o your_program your_program.c -lglibc-2.28

其中,-Wl,--dynamic-linker 用于指定动态链接器的路径,-L 用于指定库的路径,-I 用于指定头文件的路径,-lglibc-2.28 用于链接 GLIBC 2.28 库。

  1. 升级 GLIBC 版本

如果你的编译器和链接器都已经是 GLIBC 2.28 或更高版本,但仍然出现这个错误,可能是因为你的系统上安装了多个版本的 GLIBC,而你的编译器和链接器默认使用了低版本的 GLIBC。你可以尝试升级你的系统上的 GLIBC 版本,或者使用 LD_PRELOAD 环境变量指定使用高版本的 GLIBC。例如:

LD_PRELOAD=/path/to/higher-version/libc.so your_program

其中,/path/to/higher-version/libc.so 指定了高版本的 GLIBC 库的路径。

希望以上方法对你有所帮助,如果问题仍然存在,请提供更多信息,以便更好地帮助你解决问题。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

以下内容引用CHATGPT、有用望采纳:

这个错误提示是因为你的动态库链接到了libc.so.6版本为2.28的函数fcntl64,但是你的开发环境中的libc.so.6版本不是2.28,导致链接失败。解决方法是将开发环境中的libc.so.6版本升级到2.28。

你可以使用以下命令查看你的开发环境中的libc.so.6版本:

ldd --version

如果libc.so.6版本不是2.28,你可以尝试升级它。具体升级方法因系统而异,你可以在网上找到相关的教程。升级后重新编译你的代码,链接时就会链接到正确的函数,不会出现链接错误了。

该回答引用ChatGPT
这个错误发生在链接librabbitmq.so时,说明在使用fcntl函数时出现了问题。具体来说,这个错误是因为在编译librabbitmq.so时链接的libc.so.6版本过高,而在使用时连接的libc.so.6版本过低导致的。简单来说就是编译时使用的GLIBC版本和运行时使用的GLIBC版本不一致。

在你的情况下,你在编译librabbitmq.so时使用的libc版本号为2.28。但是你的开发环境中,使用的编译器是针对GLIBC 2.27及更低版本的,因此在编译你的程序时使用的是GLIBC 2.27及更低版本的libc.so.6。由于fcntl函数在GLIBC 2.28中改变了函数的原型,所以在链接时找不到函数,出现了错误。

解决方法是将开发环境中的libc.so.6升级到2.28以上的版本,或者将交叉编译时的GLIBC版本改为2.27及以下的版本。但是需要注意的是,升级GLIBC版本可能会影响到其他的程序运行,所以需要谨慎操作。

调试方法可以通过使用“ldd + 库名”命令来查看库之间的依赖关系,从而找到问题出现的具体位置。具体可用命令为“ldd librabbitmq.so”

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个错误意味着在链接rabbitmq动态库时,找不到名为fcntl64的函数,需要通过链接更多的库来修复这个问题。

在动态库中找到名称为fcntl64和fcntl的符号:

$ arm-linux-gnueabi-readelf -s librabbitmq.so | grep fcntl64
$ arm-linux-gnueabi-readelf -s librabbitmq.so | grep fcntl

这将显示动态库中是否有符号表中的fcntl64函数,或者是否存在较早的fcntl函数。如果找到了这些符号,可以尝试将其链接到您的应用程序中。您可以在链接应用程序时使用以下选项:

-lc -pthread

-c选项表示需要链接C库,-pthread选项表示需要链接pthread库,这些库可能包含fcntl64函数的符号。尝试添加这些选项,重新编译并链接您的代码。

另外,确保在您的开发环境中安装了正确的libc版本。根据您的描述,您升级了libc到2.28版本。如果您的开发环境中使用的是旧版本的libc,请尝试将其升级到2.28或更高版本。

#include <fcntl.h>

如果以上步骤都没有解决问题,您可以检查您的代码,特别是任何使用fcntl函数的代码,并确保在其顶部包含fcntl头文件:
如果我的回答解决了您的问题,请采纳!

引用ChatGPT部分参考:
这个问题可能是因为你使用更新的libc库版本(2.28)编译的RabbitMQ-C库,而你的目标系统的GLIBC库版本低于2.28。

在GLIBC库2.28版本中, "fcntl"函数的底层实现发生了变化。因此,如果在较旧的版本的GLIBC库下使用这个库可能会导致错误。

要解决这个问题,您需要在目标系统上安装一些软件包,这些软件包依赖于更新的GLIBC版本。

另外,您可以尝试使用较旧版本的GLIBC库版本编译RabbitMQ-C库,或者重新编译您的目标系统,使用更新的GLIBC库版本。

建议使用一个较旧版本的GLIBC库重新编译 RabbitMQ-C 库,并确保您的目标系统上安装的GLIBC库版本高于或等于您使用的编译时版本。

您可以使用以下命令安装旧版本的GLIBC库:

sudo apt-get install libc6-dev=2.27-3ubuntu1