ijkplayer编译ffmpeg时加入libxml2库时出现: ERROR: libxml-2.0 not found using pkg-config, 解决方法及原因

1.前言

由于需要ijkplayer-android支持dash流媒体协议,而dash协议又依赖于libxml2库,所以需要将libxml2加入ffmpeg中。但是在加入libxml2后编译出现了很多问题,在此记录一下解决过程以及思路。

2.问题的出现

在ijkplayer/config中的module.sh加入以下两行以支持dash流媒体协议:

export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-demuxer=dash"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-libxml2"

然后进入ijkplayer/android/contrib,编译ffmpeg:

./compile-ffmpeg.sh armv7a

出现如下错误(其实这里已经提示,可以通过ffbuild/config.log文件来查看具体是哪里出错):
error

3.解决过程

3.1 网络查找解决方法

经过几个小时的搜索,包括百度,google,stackoverflow等,google倒是搜出来了两个一样的问题,但是没人回答,没办法,只能自己看下编译脚本为什么会出错了。

3.2 自己解决的过程

查看上图可以知道,在configurate ffmpeg阶段出现错误,打开compile-ffmpeg.sh发现最终调用了ijkplayer/android/contrib/tools/do-compile-ffmpeg.sh脚本,打开,搜索configurate ffmpeg,发现是在配置ffmpeg的时候出现错误,这里简单说一下ffmpeg的编译流程:

./cnofigure xxxxx
make
make install

configure会配置编译器,输出路径,编译哪些模块等,出现错误的地方如下图:
configure
打开ijkplayer/android/contrib/ffmpeg-armv7a/configure,搜索not found using pkg-config,如下图:
在这里插入图片描述
发现是在执行use_pkg_config时出现错误,这里发现有一行log require_pkg_config “$@”,通过echo得知,有一个log文件,记录了在configure时的log,该文件路径为:ijkplayer/android/contrib/ffmpeg-armv7a/ffbuild/config.log,打开之,最后几行如下:
在这里插入图片描述
在执行check_pkg_config函数时出错,找到该函数,如下:
在这里插入图片描述
在添加打印发现在check_cmd的时候未成功,直接return了,shell中return 0表示执行成功,||表示在前面的命令执行未成功时就执行||后面的语句,这里未成功,直接执行return了,打印pkg_config变量的值,发现其为空,这里是检查pkg_config这个命令是否存在,其值为空,当然不存在了,然后在网上搜索pkg_config,学习了一下,发现pkg-config是一个软件,可以通过它来查看一个库的头文件路径和库路径,在编译和链接的时候使用,比如我在ubuntu上需要使用libxml2,使用apt安装libxml2之后,执行:

pkg-config --cflags libxml-2.0

输出:

-I/usr/local/include/libxml2

同样的:

pkg-config --libs libxml-2.0

输出:

-L/usr/local/lib

上面的-I/usr/local/include/libxml2这些信息是哪里来的呢?pkg-config会通过libxml-2.0.pc文件来设置这些信息,它会从pkg-config --variable pc_path pkg-config命令输出的路径和环境变量PKG_CONFIG_PATH中查找libxml-2.0.pc文件(一般像apt这种命令安装或者configure编译出来的软件都会有一个pkgconfig文件夹,里面就是各种.pc文件)该文件内容如下:
在这里插入图片描述
在执行pkg-config --cflags libxml-2.0时,会输出Cflags后的内容,执行pkg-config --libs libxml-2.0时,会输出Libs后的内容,了解以上信息后,回到check_pkg_config函数,pkg_config变量值为空,这显然是不对的,需要将其设置为pkg-config,像configure这种文件应该会有个参数设置它的值,执行./configure --help,发现有一行:

--pkg-config=PKGCONFIG   use pkg-config tool PKGCONFIG [pkg-config]

在./configure时添加–pkg-config=pkg-config,果然,pkg_config变量变成了pkg-config,但是还是输出ERROR: libxml-2.0 not found using pkg-config,再次查看config.log文件:
在这里插入图片描述
发现pkg-config命令已经有了,但是没有libxml-2.0,执行一下pkg-config --cflags libxml-2.0,果然没有,也是,arm架构的libxml-2.0都没编译,libxml-2.0.pc文件也没有,肯定没有,在网络上下载libxml2-git-snapshot.tar.gz
解压并配置:

./configure --host=arm-linux --build=i386-linux --target=arm --prefix=/media/libxml2-2.9.10/install CC=arm-linux-androideabi-gcc  --without-zlib  --without-python

–prefix设置make install时安装路径,CC设置编译器,编译器为自己需要的架构的版本,然后执行:

make
make install

完成后在install目录下会输出include,lib,lib/pkgconfig等,设置PKG_CONFIG_PATH环境变量为pkgconfig路径,然后再次编译ffmpeg:

export PKG_CONFIG_PATH=/media/libxml2-2.9.10/install/lib/pkgconfig
./compile-ffmpeg.sh armv7a

还是出现ERROR: libxml-2.0 not found using pkg-config,执行pkg-config --cflags libxml-2.0已经有输出了,很奇怪啊,查看config.log:
在这里插入图片描述
这里发现错误信息和上次已经不一样了,这里是编译某个test.c文件(查看configure脚本发现这个文件是通过configure自动生成的,目的应该是测试libxml2库是否可以使用,如果编译通过则说明可以使用),这里错误是xmlversion头文件找不到,执行pkg-config --cflags libxml-2.0输出如下:

-I/media/libxml2-2.9.10/install/include/libxml2

查看一下该目录:

ls /media/libxml2-2.9.10/install/include/libxml2
libxml

发现有libxml目录,看上图错误是libxml2/libxml/xmlversion.h找不到,注意,这里目录是libxml2开头,查看/media/libxml2-2.9.10/install/include目录,该目录结构如下:
libxml2/libxml/
编译时,这里就很明显了,libxml2/libxml/xmlversion.h这个文件应该从目录/media/libxml2-2.9.10/install/include查找而不是/media/libxml2-2.9.10/install/include/libxml2查找,当然找不到了,修改/media/libxml2-2.9.10/install/lib/pkgconfig/libxml-2.0.pc文件,在Cflags后添加-I${includedir}:
在这里插入图片描述
再次编译ffmpeg,configure成功,没有出现ERROR: libxml-2.0 not found using pkg-config错误,链接时加入libxml库路径和头文件路径,但是在链接阶段出现xml函数未定义错误:
在这里插入图片描述

修改ijkplayer/android/contrib/tools/do-compile-ffmpeg.sh,如下;
在这里插入图片描述
红框中为新添加的内容,将/media/libxml2-2.9.10/install文件夹复制为ijkplayer/android/contrib/libxml-armv7a,export动态设置PKG_CONFIG_PATH环境变量,sed -i用于动态设置libxml-2.0.pc文件第一行库的路径,FF_CFLAGS和FF_DEP_LIBS设置在链接时的库路径和头文件路径,再次编译:

./compile-ffmpeg.sh armv7a

在链接出现错误:
在这里插入图片描述
这里已经是ffmpeg的链接错误了,出现未定义函数,使用sourceinsight打开ffmpeg源码并分析函数调用关系,发现ff_dash_fill_tmpl_params函数定义在libavformat/dash.c中,查看libavformat文件夹下,发现并没有dash.o,打开libavformat/Makefile,搜索DASH,发现dash_demuxer并没有依赖dash.o:
在这里插入图片描述
在该处加上dash.o:
在这里插入图片描述
再次编译,成功。

3.2 ffmpeg3.4中编译dash的bug

本人使用的ijkplayer中ffmpeg的版本为3.4,发现在ffmpeg4.0中该行已经加入dash.o,而且此次修改log为fix build wihout dashenc:
在这里插入图片描述
问题解决完成,并且分析了解决问题的过程以及问题产生的原因。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值