NDK编译FFmpeg时找不到pkg-config命令的解决方案

问题描述

        不少朋友在使用NDK为Android平台下编译FFmpeg,在执行configure命令的时候会报出“ERROR: xxxx not found using pkg-config”的错误,出现这个错误的原因主要是在编译FFmpeg的时候有加入第三方的编解码库(比如opus、theora等),但是configure命令却又找不到第三方库导致的,出现这个问题有两个原因,第一就是你确实没有提供相应的第三方库导致pkg-config命令找不到,这种问题只需按照要求提供好第三方库再次configure就好。第二种的话这是由于configure命令在找不到pkg-config,从而报错。

以下是我机器上进行configure的命令,所有第三方的头文件和静态库都放在ffmpeg-3.3/third_libs/builds下,本以为通过 -I./ffmpeg-3.3/third_libs/builds/include” 和 -L./ffmpeg-3.3/third_libs/builds/libs/armeabi” 就可以指定头文件和链接库了,但是结果还是报错,“ERROR: opus not found using pkg-config”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/bin/bash
NDK=./Android/sdk/ndk-bundle
SYSROOT=$NDK/platforms/android-16/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
./configure \
--prefix=$PREFIX \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--enable-shared \
--enable-libopus \
--enable-libx265 \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-avdevice \
--disable-doc \
--disable-symver \
--enable-cross-compile \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--target-os=linux \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic -DANDROID $ADDI_CFLAGS \
-I./ffmpeg-3.3/third_libs/builds/include" \
--extra-cxxflags="$ADDI_CFLAGS \
-I./ffmpeg-3.3/third_libs/builds/include" \
--extra-ldflags="$ADDI_LDFLAGS \
-L./ffmpeg-3.3/third_libs/builds/libs/armeabi" \

第三方库

报错

定位问题

        该如何确定所遇到的问题是因为第三方库不存在呢还是因为pkg-config命令不存在呢?最好的方法就是打开当前目录下的config.log文件查看错误内容,如下图

则可以断定是因为pkg-config命令不存在导致的问题。

解决思路

        既然我们已经知道是由于Android的NDK编译链并没有提供pkg-config,而导致命令不存在的问题,因此解决方法也很简单,就是对configure进行欺骗。我们只需要模拟一个pkg-config并按照命令返回相应的值即可解决。

解决方法

  1. 进入FFmpeg所在目录下,新建文件fake_android_pkg_config.sh
  2. 复制并根据编译所需编写相应的处理脚本,本文假设我们的FFmpeg需要opus和libx265这两个第三方库,脚本编写如下并保存:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #!/bin/sh
    case $1 in
    --exists)
    if [ $2 = "x264" ]; then
    exit 0 #存在使用exit 0
    elif [ $2 = "opus" ]; then
    exit 0 #存在使用exit 0
    else
    exit 1 #不存在使用exit 1
    fi
    ;;
    --cflags)
    if [ $2 = "x264" ]; then
    echo "-I/你的路径/ffmpeg-3.3/third_libs/builds/include" #返回x264头文件所在目录
    elif [ $2 = "opus" ]; then
    echo "-I/你的路径/ffmpeg-3.3/third_libs/builds/include" #返回opus头文件所在目录
    fi
    ;;
    --libs)
    if [ $2 = "x264" ]; then
    echo "-L/你的路径/ffmpeg-3.3/third_libs/builds/libs/armeabi -lx265" #返回x264静态库所在目录
    elif [ $2 = "opus" ]; then
    echo "-L/你的路径/ffmpeg-3.3/third_libs/builds/libs/armeabi -lopus" #返回opus静态库所在目录
    fi
    ;;
    *)
    echo "fake pkg-config for Android NDK build!"
    ;;
    esac
  3. 对fake_android_pkg_config.sh赋予执行权限

    1
    chmod 777 ./fake_android_pkg_config.sh
  4. 用文本编辑器打开configure文件,在3710行左右添加一行pkg_config=./fake_android_pkg_config.sh,使得之后执行pkg_config命令直接执行我们的fake_android_pkg_config.sh脚本,如下图

  5. 至此我们的所有工作已经结束,再次执行上面的configure命令即可完成配置,然后再进行make和make install命令即可编译出相应的FFmpeg静态和动态库。

    注意:编译成功的前提是已经正确配置好头文件和库文件。