fcntl,fcntl64均是系统的api提供的文件操作,fcntl64本来是用来解决操作大文件的问题,后面fcntl本身已经解决了这个问题,fcntl64就被舍弃了
系统环境信息:
ubuntu 18.04
root@# cat /etc/issue
Ubuntu 18.04.6 LTS \n \l
root@alg-dev04:~# uname -a
Linux alg-dev04 4.15.0-151-generic #157-Ubuntu SMP Fri Jul 9 23:07:57 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@alg-dev04:~# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 8
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 85
Model name: Intel(R) Xeon(R) Gold 6140 CPU @ 2.30GHz
Stepping: 4
CPU MHz: 2294.608
BogoMIPS: 4589.21
L1d cache: 32K
L1i cache: 32K
L2 cache: 1024K
L3 cache: 25344K
NUMA node0 CPU(s): 0-7
为了按照需要开启ffmpeg的特定功能,需要源码安装ffmpeg
源码下载地址:
Download FFmpeg
wget https://ffmpeg.org/releases/ffmpeg-6.0.1.tar.bz2
tar -xvf ffmpeg-6.0.1.tar.bz2
./configure && make -j32
报错信息如下:
AR libavcodec/libavcodec.a
LD ffmpeg_g
LD ffprobe_g
LD ffplay_g
libavdevice/libavdevice.a(oss.o): In function `ff_oss_audio_open':
/root/xingqiao/ffmpeg-6.0.1/libavdevice/oss.c:63: undefined reference to `fcntl64'
libavformat/libavformat.a(network.o): In function `ff_socket':
/root/xingqiao/ffmpeg-6.0.1/libavformat/network.c:195: undefined reference to `fcntl64'
libavformat/libavformat.a(os_support.o): In function `ff_socket_nonblock':
/root/xingqiao/ffmpeg-6.0.1/libavformat/os_support.c:221: undefined reference to `fcntl64'
/root/xingqiao/ffmpeg-6.0.1/libavformat/os_support.c:219: undefined reference to `fcntl64'
/root/xingqiao/ffmpeg-6.0.1/libavformat/os_support.c:221: undefined reference to `fcntl64'
libavformat/libavformat.a(file.o):/root/xingqiao/ffmpeg-6.0.1/libavformat/file.c:208: more undefined references to `fcntl64' follow
libavdevice/libavdevice.a(oss.o): In function `ff_oss_audio_open':
/root/xingqiao/ffmpeg-6.0.1/libavdevice/oss.c:63: undefined reference to `fcntl64'
libavformat/libavformat.a(network.o): In function `ff_socket':
/root/xingqiao/ffmpeg-6.0.1/libavformat/network.c:195: undefined reference to `fcntl64'
libavformat/libavformat.a(os_support.o): In function `ff_socket_nonblock':
/root/xingqiao/ffmpeg-6.0.1/libavformat/os_support.c:221: undefined reference to `fcntl64'
/root/xingqiao/ffmpeg-6.0.1/libavformat/os_support.c:219: undefined reference to `fcntl64'
/root/xingqiao/ffmpeg-6.0.1/libavformat/os_support.c:221: undefined reference to `fcntl64'
libavformat/libavformat.a(file.o):/root/xingqiao/ffmpeg-6.0.1/libavformat/file.c:208: more undefined references to `fcntl64' follow
libavdevice/libavdevice.a(oss.o): In function `ff_oss_audio_open':
/root/xingqiao/ffmpeg-6.0.1/libavdevice/oss.c:63: undefined reference to `fcntl64'
libavformat/libavformat.a(network.o): In function `ff_socket':
/root/xingqiao/ffmpeg-6.0.1/libavformat/network.c:195: undefined reference to `fcntl64'
libavformat/libavformat.a(os_support.o): In function `ff_socket_nonblock':
/root/xingqiao/ffmpeg-6.0.1/libavformat/os_support.c:221: undefined reference to `fcntl64'
/root/xingqiao/ffmpeg-6.0.1/libavformat/os_support.c:219: undefined reference to `fcntl64'
/root/xingqiao/ffmpeg-6.0.1/libavformat/os_support.c:221: undefined reference to `fcntl64'
libavformat/libavformat.a(file.o):/root/xingqiao/ffmpeg-6.0.1/libavformat/file.c:208: more undefined references to `fcntl64' follow
collect2: error: ld returned 1 exit status
Makefile:131: recipe for target 'ffmpeg_g' failed
make: *** [ffmpeg_g] Error 1
make: *** Waiting for unfinished jobs....
collect2: error: ld returned 1 exit status
Makefile:131: recipe for target 'ffprobe_g' failed
调整配置命令也是无效:调整为gcc8,无法解决问题
./configure --cc=gcc-8 --enable-static --disable-shared --extra-libs=-lc --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-asm --enable-pic --disable-x86asm --extra-ldflags="-Wl,--no-as-needed,-rpath=/usr/lib/gcc/x86_64-linux-gnu/8" --target-os=linux --arch=x86_64 --extra-cxxflags="-fPIC" --ignore-tests --enable-debug=3
root@alg-dev04:~# ldd --version
ldd (GNU libc) 2.29
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
root@alg-dev04:~#
理论上来说的话,glibc的库的这个版本应该是兼容fcntl64的
编译器版本:
root@alg-dev04:~# gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
查看源码 是否包含相应的fcntl64的代码调用:发现只有中间文件存在,源码并没有
root@alg-dev04:~/xingqiao/ffmpeg-6.0.1# grep -lr "fcntl64" ./
./libavformat/libavformat.a
./libavformat/network.o
./libavformat/os_support.o
./libavformat/file.o
./libavdevice/libavdevice.a
./libavdevice/oss.o
./libavutil/file_open.o
./libavutil/libavutil.a
猜测应该是ffmpeg的某些依赖库调用了fcntl64,如此的话,重点就是分析glibc的是否真的存在fcntl64
但是全局搜索发现存在多个glibc的库,不知道ldd默认调用的是哪个,查看默认路径下的
root@alg-dev04:~/xingqiao# nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep GLIBC
0000000000000000 A GLIBC_2.10
0000000000000000 A GLIBC_2.11
0000000000000000 A GLIBC_2.12
0000000000000000 A GLIBC_2.13
0000000000000000 A GLIBC_2.14
0000000000000000 A GLIBC_2.15
0000000000000000 A GLIBC_2.16
0000000000000000 A GLIBC_2.17
0000000000000000 A GLIBC_2.18
0000000000000000 A GLIBC_2.2.5
0000000000000000 A GLIBC_2.2.6
0000000000000000 A GLIBC_2.22
0000000000000000 A GLIBC_2.23
0000000000000000 A GLIBC_2.24
0000000000000000 A GLIBC_2.25
0000000000000000 A GLIBC_2.26
0000000000000000 A GLIBC_2.27
0000000000000000 A GLIBC_2.3
0000000000000000 A GLIBC_2.3.2
0000000000000000 A GLIBC_2.3.3
0000000000000000 A GLIBC_2.3.4
0000000000000000 A GLIBC_2.4
0000000000000000 A GLIBC_2.5
0000000000000000 A GLIBC_2.6
0000000000000000 A GLIBC_2.7
0000000000000000 A GLIBC_2.8
0000000000000000 A GLIBC_2.9
0000000000000000 A GLIBC_PRIVATE
root@alg-dev04:~/xingqiao# nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep fcntl
0000000000110550 W __fcntl
0000000000110550 W fcntl
可见版本和ldd匹配,而且此库中并没有实现fcntl64,所以考虑升级glibc的版本,但是由于系统ubuntu18.04和此内核版本官方源提供的匹配版本就是如上的版本,尝试源码编译glibc库31版本,然后手动源码安装成功,ffmpeg可以编译成功,并且不会报错,但是切换到此路径下的glibc库的话,系统很多的命令都会报段错误,所以,glibc并不能如此的在系统下升级
最后的处理方案:
1.升级操作系统到Ubuntu 20.04.3 LTS,如此可以解决问题
2.使用docker镜像隔离,选择docker ubuntu:latest最新的镜像,系统版本:
root@ubuntu-ffmpeg-cuda:/data# cat /etc/issue
Ubuntu 24.04 LTS \n \l
root@ubuntu-ffmpeg-cuda:/data# ldd --version
ldd (Ubuntu GLIBC 2.39-0ubuntu8.1) 2.39
遇到类似问题若有更好的方案请留言,非常感谢,而且并没有确认是哪个库引入的fcntl64,按照介绍64位新系统,大文件操作,fcntl已经OK了,并不需要调用fcntl64,但是GNU的库存在前向兼容问题
查看过:fcntl.h 通过调整ffmpeg编译的时候的宏定义并没有什么效果
vim /usr/local/include/fcntl.h