【Windows】使用 MinGW 编译 FFmpeg 踩坑记录

3 篇文章 0 订阅

最近需要将在 Linux 上开发的程序兼容到 Windows 平台上来,由于习惯了 Linux 开发,因此,希望在 Windows 上也使用命令行编译,于是尝试着使用命令行编译 FFmpeg。但是,不同于 Linux/MacOS 这两种 unix 操作系统,Windows 的操作系统在编译时无法直接使用很多 Linux 上的工具,出现了不少麻烦,因此记录一下。

–enable-nvdec 后报错 cuda requested, but not all dependencies are satisfied: ffnvcodec

在这里插入图片描述

–enable-x264 后报 WARNING: using libx264 without pkg-config

在这里插入图片描述

这两个错误的原因一致。

有几种情况,跟在 Linux 平台是一致的,比如可能是因为没有安装 cuda 驱动,也可能是因为没配置 ff_nvcodec_headers,可参考文章对照解决。

这里,并非这两种情况,毕竟在 Linux 上已经趟过的坑,在 Windows 上不应该重复。

在这里插入图片描述

但是,它就是没法正常 configure 成功。使用的 configure 选项如上图所示,无论是前面的 PKG_CONFIG_PATH,还是后面的 --pkg_config 选项,都是希望能把 ffnvcodec 的 pc 文件告知 configure。如果把 --enable-cuvid --enable-cuda --enable-nvdec 这三个选项去掉,就会报图二所示错误:WARNING: using libx264 without pkg-config

啊,现在再看这个问题,很明显,图二中的错误已经提示的很清楚了。pkg-config not found。但是,当时一直以为是 PKG_CONFIG_PATH 这个变量没有传递给 configure,因此试过修改 /etc/profile 文件中的 PKG_CONFIG_PATH 语句,试过将 $OUTDIR/lib/pkgconfig 目录中的 .pc 文件拷贝到 /etc/profile 文件中记录的 /mingw64/lib/pkgconfig 目录下,都无济于事。

而且,比较奇怪的是,使用 MSYS/MinGW64 终端环境,就能 configure 成功,而且能找到 ffnvcodec。查看两种环境 configure 之后产生的 configure 日志 ffbuilds/config.log 后发现,使用 gitbash 环境 configure 时,在 check_pkg_config ffnvcodec 的时候总是失败,而使用 MSYS/MinGW64 终端环境 configure 时,则一次成功。
在这里插入图片描述
很苦恼啊,为啥 MSYS/MinGW64 环境能成功,而 gitbash 环境却不能成功呢?这里,有人可能会问,为啥不在 MSYS 环境下编译呢?这是下个问题要说的。苦闷了很久,灵光一闪,尝试在 gitbash 中调用 pkg-config --version 查看一下 pkg-config 工具的版本号,或者说,怀疑,是不是在 gitbash 中没有 pkg-config 这个工具。

果不其然,gitbash 中没有这个工具。那么,该怎么安装呢?gitbash 中也没有 apt-get 这个工具啊。于是,想着能不能把 MSYS 的 pkg-config 工具拷贝过来试试,那,MSYS 的 pkg-config 工具在哪儿呢?在 MSYS MinGW64 终端中使用命令 whereis pkg-config 可以看到 pkg-config.exe 的位置。注意看下图中不同的命令的结果的区别,由于之前使用的是 whereis 命令,所以,只能先 cd /mingw64,然后使用 explorer bin 命令在 Windows 资源管理器中打开这个文件夹。
在这里插入图片描述
同样的,在 gitbash 目录下执行 where ar 看到 gitbash 的 bin 目录,将 MSYS 目录下的 pkg-config.exe 拷贝到 gitbash 的 bin 目录下再试。仍然不成功。

这里,本应该先在 gitbash 中执行一次 pkg-config --version,就可以看到,还缺一个动态库文件 libpkgconf-3.dll,把它也拷贝过去之后,就能在 gitbash 环境中 configure 成功啦!

ar libavfl: No such file or directory

在这里插入图片描述
在这里插入图片描述

configure 成功之后,就可以在 gitbash 终端调用 mingw32-make.exe -j 开始编译了,但是编译后期却又报出如上图所示的错误,看起来像是由于需要 ar 进静态库的 .o 文件太多,导致 ar 命令太长,以至于后面的部分内容只有一半。

有一种解决方案是,在 ffmpeg/ffbuild/library.mak 文件第 37 行之后插入一行 $(info $(ARFLAGS) $^) 来查看 FFmpeg 的 ar 命令的具体写法。将所需的目标文件(.o)及 ar flag 打印出来,然后再手动执行该 ar 命令。
在这里插入图片描述
遇到报错之后,如上图修改、保存之后,再 mingw32-make.exe,则会有如下打印:
在这里插入图片描述
选中 rcD 之后的那些 .o 文件名,复制,然后在 gitbash 终端内输入 ar rcD libavcodec/libavcodec.a 然后粘贴,即可手动打包 libavcodec.a 静态库,同理,其他几个遇到同样问题的库也可以这么操作。
在这里插入图片描述

libavfilter undefined reference

经过手动 ar 之后,好不容易把所有静态库都打包完成,现在来到链接过程。在这里插入图片描述
然而很不幸,
在这里插入图片描述
又报出经典的 undefined reference 问题,仔细分析后发现,是 libavfilter.a 的存在问题,通过查看文件大小,发现好像比正常的 libavfilter.a 要小一些,进一步通过 ar -x libavfilter.a,将静态库解压后发现,上面打印出来的 ar 时的输入文件个数和解压出来的个数相差较远。
在这里插入图片描述
在这里插入图片描述
将 libavfilter/libavfilter.a 删除(或者移动到另一个目录)后,重新 mingw32-make.exe,即可重新打印 libavfilter.a 的 ar 参数,将上面 libavfilter 的 ar 命令输入文件复制粘贴到文本编辑器,将空格替换为换行回车之后,发现该文件有 line471,说明有 471 个目标文件要 ar 进静态库。
在这里插入图片描述
而通过命令 ar -x libavfilter.a 后得到的文件数量却只有 304 个,很显然,有一百多个目标文件没被压缩进静态库。具体为什么不清楚。

解决方法倒是有,可以将上面打印的 471 个文件分批压缩进静态库,可以先 ar rcD libavfilter/libavfilter.a [前100个obj文件],然后继续 ar rcD libavfilter/libavfilter.a [再100个obj文件]

也可以看一下 libavfilter 目录中,或者上面打印出来的 471 个文件,主要分布在 libavfilter、libavfilter/dnn、libavfilter/x86 这三个目录下,所以,也可以用命令 ar rcD libavfilter/libavfilter.a libavfilter/\*.o libavfilter/dnn/\*.o libavfilter/x86/\*.o 来打包静态库。

重新打包后再解压验证一下,发现,只有 434 个文件,还是怪怪的。但是,在 gitbash 中再次执行 mingw32-make.exe 时,就能正常链接成功 ffmpeg.exe 和 ffprobe.exe 了。

编译 ffmpeg.exe 和 ffprobe.exe 的意义

虽然,使用中我们用的是静态库,但是,在编译时编译出 ffmpeg.exe 和 ffprobe.exe 却是很有意义的,主要有:

  • 验证 configure 选项正确、成功应用到了编译过程
  • 验证编译出来的静态库是可用的(如上述 avfilter 静态库缺文件的问题就可以在链接 ffmpeg.exe 的过程中发现)
  • 验证静态库链接出来的可执行文件是可运行的
  • 可能会有使用这两个工具(其实偶尔也是需要 ffplay 的)

exec file format error

在 MSYS 环境中 configure 之后,再从 gitbash 环境编译,会在 cc (编译)阶段报错。
而如果在 MSYS 环境中 configure 之后,在 MSYS 环境下 make,则会出现 exec file format error 的错误,因此,也不能在 MSYS 环境下编译 FFmpeg,或者,除非把所有的依赖库和开发程序都放到 MSYS 环境中编译,或许可以。
使用 where 命令可以看到,MSYS 中的 make 使用的是 GNU Make,同时使用了很多 GNU 的头文件。虽然编译出来的 ffmpeg.exe 是可以执行使用的,但是将其编译出来的 libavutil.a 静态库集成到开发的 Linux 程序中,就会报错 exec format error。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深海Enoch

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值