FFmpeg编译错误分析方法示例

同事问了一个FFmpeg编译错误问题,几乎100%复现:

1. Windows msys + mingw工具链环境

2. 编译动态库

报错信息:

FFmpeg编译错误分析方法示例

以这个问题为例,我们看下编译错误如何分析。

首先可以看到

1. 错误出现在avformat链接过程

2. 报的错误是一个符号找不到

分析编译错误,一定要搞清楚错误出现在哪个阶段:预处理阶段、编译阶段、还是链接阶段。

找不到的符号是哪里实现的呢?我们可以搜下代码。这里做个提示,avformat依赖avcodec,去avcodec里搜索,可以缩小范围。或者ctags clangd工具找定义,直接定位到。

avpriv_split_xiph_headers定义在avcodec/xiph.c中。avpriv前缀含义是给FFmpeg内其他库使用的函数,不是给用户用的。

接下来我们看下libavcodec/Makefile。xiph.o是始终编译链接到avcodec的,不受config影响。其他的这些编解码器会受config enable disable的影响,disable时不编译。

可以看看dll lib文件,确实没有avpriv_split_xiph_headers。

问题变得奇怪了,为什么一个avcodec始终编译的object,avformat会找不到它的定义呢?

没有眉目的时候,我们可以看下编译过程:

1. rm libavcodec/avcodec*

2. make -n libavcodec/avcodec.dll

我们先rm删除一些target,方便测试。再执行make -n,用dryrun观察dll生成过程。

可以看到,生成dll前,先用compat下的makedef工具,生成了一个.def文件。这个.def是一个导出符号列表,只有在这个列表中的符号才会导出。最终生成的dll少了一个符号,是因为这个符号不在def文件中。

接下来看看makedef的实现,其基本步骤可概括如下:

1. 先用所有.o object文件生成一个静态lib文件

2. 用nm -g –defined-only foo.lib列出所有的外部可见符号

3. 根据libavcodec下的规则文件,筛选出所有av_和avpriv_前缀的符号,这就是写入def文件的符号列表。

好了,我们可以手动执行nm

nm -g libavcodev/xiph.o,发现没那个符号。

再用nm libavcodec/xiph.o试试,发现找到了,并且符号类型为T,代表是外部可见函数符号!

nm工具出问题了,-g显示的函数符号不全。

抱着侥幸心理,试试其他nm工具。which -a nm
/mingw64/bin/nm
/usr/bin/nm
/bin/nm

现在用的是mingw64的nm,我们可以试试第二个。结果显示,/usr/bin/nm正常!

我又查看了一下两个nm工具的版本号,版本是一样的。但因为未知原因,导致了mingw版本nm -g丢符号。

我的分析到此为止,不打算再往下追了。感兴趣的同学可以继续往下查。

解决方案简单,换下nm即可,具体怎么做留给读者思考。

作者:quink
来源:Fun With FFmpeg
原文:https://mp.weixin.qq.com/s/yapxIpalzRbZvt4FRtsn_Q

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论