编译环境及软件
1. ubuntu22 64bit desktop
3. ffmpeg-4.2.1
5. mp3lame
目录结构
解压ffmpeg-4.2.1,然后将fdk-aac、x264、mp3这三个第三方库解压到ffmpeg-4.2.1目录中。最终的目录结构如下所示:
编译过程及脚本
下载ndk到机器上,然后解压到某个位置。
1)首先尝试编译fdk-aac,编译脚本为:
#!/bin/bash
NDK=这里是NDK的目录,替换成自己本机上的正确的目录
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
#ARCH=arm64
#OPTIMIZE_CFLAGS="-march=$ARCH"
ANDROID_LIB_PATH="$(pwd)/android"
#CPU=armv8-a
API=23
./autogen.sh
function build_android_arm
{
echo "build for android $CPU"
./configure \
--host=$HOST \
--disable-shared \
--enable-static \
--prefix="$ANDROID_LIB_PATH/$CPU"
make clean
make -j2
make install
echo "building for android $CPU completed"
}
CPU=armv8-a
HOST=aarch64-linux-android
export AR=$TOOLCHAIN/bin/llvm-ar
export AS=$TOOLCHAIN/bin/llvm-as
export LD=$TOOLCHAIN/bin/llvm-ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
export CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
export CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
export CFLAGS="-Os -fpic $OPTIMIZE_CFLAGS"
export CPPFLAGS="-Os -fpic $OPTIMIZE_CFLAGS"
echo $CC $CXX
build_android_arm
注意将上面NDK替换为自己本地的NDK目录。
编译过程中会出错,将出错的源代码的相应位置注释后再次编译。
2)然后编译x264库,脚本为:
#!/bin/bash
NDK=这里是NDK的目录,替换成自己本机上的正确的目录
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
#ARCH=arm64
#OPTIMIZE_CFLAGS="-march=$ARCH"
ANDROID_LIB_PATH="$(pwd)/android"
CPU=armv8-a
HOST=aarch64-linux-android
API=23
function build_android_arm
{
echo "build for android $CPU"
./configure \
--host=$HOST \
--disable-shared \
--enable-static \
--prefix="$ANDROID_LIB_PATH/$CPU" \
--enable-pic \
--enable-strip \
--disable-asm \
--extra-cflags="-fPIC"
echo "ECHO HOST below:"
echo $HOST
#make clean
#make -j2
#make install
echo "building for android $CPU completed"
}
export CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
export CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
build_android_arm
3)然后编译mp3库
#!/bin/bash
NDK=这里是NDK的目录,替换成自己本机上的正确的目录
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
#ARCH=arm64
#OPTIMIZE_CFLAGS="-march=$ARCH"
ANDROID_LIB_PATH="$(pwd)/android"
CPU=armv8-a
API=23
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
HOST=aarch64-linux-android
function build_android_arm
{
echo "build for android $CPU"
./configure \
--host=$HOST \
--disable-shared \
--enable-static \
--prefix="$ANDROID_LIB_PATH/$CPU"
echo "for test error."
echo $API
echo $CC
#make clean
#make -j2
#make install
echo "building for android $CPU completed"
}
# CPU=armv8-a
HOST=aarch64-linux-android
#export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
#export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
#export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
#export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
#export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
#CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
#CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
#export CFLAGS="-Os -fpic $OPTIMIZE_CFLAGS"
#export CPPFLAGS="-Os -fpic $OPTIMIZE_CFLAGS"
build_android_arm
4)切换到ffmpeg目录,尝试集成(集成fdk-aac、x264以及mp3库)编译ffmpeg库,脚本为:
#!/bin/bash
NDK=这里是NDK的目录,替换成自己本机上的正确的目录
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
#ANDROID_LIB_PATH="$(pwd)/android"
ARCH=arm64
CPU=armv8-a
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
PREFIX=$(pwd)/android/$CPU
CROSS_PREFIX=$TOOLCHAIN/bin/llvm-
#OPTIMIZE_CFLAGS="-march=$ARCH"
API=23
BASEPATH=$(cd `dirname $0`; pwd)
echo $BASEPATH
NM=$TOOLCHAIN/bin/llvm-nm
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
#FDK_INCLUDE=$BASEPATH/fdk-aac/android/$CPU/include
echo $CC
echo $CXX
FDK_INCLUDE=$BASEPATH/fdk-aac/android/$CPU/include
FDK_LIB=$BASEPATH/fdk-aac/android/$CPU/lib
X264_INCLUDE=$BASEPATH/x264/android/$CPU/include
X264_LIB=$BASEPATH/x264/android/$CPU/lib
MP3_INCLUDE=$BASEPATH/lame-3.100/android/$CPU/include
MP3_LIB=$BASEPATH/lame-3.100/android/$CPU/lib
function build_android_arm
{
echo "build ffmpeg for android $CPU"
./configure \
--prefix=$PREFIX \
--disable-neon \
--disable-hwaccels \
--disable-gpl \
--disable-postproc \
--enable-shared \
--enable-jni \
--disable-mediacodec \
--disable-decoder=h264_mediacodec \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
--extra-cflags="-Os -fpic" \
--enable-nonfree \
--enable-gpl \
--enable-libfdk-aac \
--enable-libx264 \
--enable-libmp3lame \
--enable-cross-compile \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--nm=$NM \
--cc=$CC \
--cxx=$CXX \
--sysroot=$SYSROOT
# make clean
make -j2
make install
echo "building ffmpeg for android $CPU completed"
}
build_android_arm
5)如果集成编译失败,尝试不集成第三方库来编译ffmpeg,编译脚本为:
#!/bin/bash
NDK=这里是NDK的目录,替换成自己本机上的正确的目录
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
#ANDROID_LIB_PATH="$(pwd)/android"
ARCH=arm64
CPU=armv8-a
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
PREFIX=$(pwd)/android/$CPU
CROSS_PREFIX=$TOOLCHAIN/bin/llvm-
#OPTIMIZE_CFLAGS="-march=$ARCH"
API=23
BASEPATH=$(cd `dirname $0`; pwd)
echo $BASEPATH
NM=$TOOLCHAIN/bin/llvm-nm
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
#FDK_INCLUDE=$BASEPATH/fdk-aac/android/$CPU/include
echo $CC
echo $CXX
FDK_INCLUDE=$BASEPATH/fdk-aac/android/$CPU/include
FDK_LIB=$BASEPATH/fdk-aac/android/$CPU/lib
X264_INCLUDE=$BASEPATH/x264/android/$CPU/include
X264_LIB=$BASEPATH/x264/android/$CPU/lib
MP3_INCLUDE=$BASEPATH/lame-3.100/android/$CPU/include
MP3_LIB=$BASEPATH/lame-3.100/android/$CPU/lib
function build_android_arm
{
echo "build ffmpeg for android $CPU"
./configure \
--prefix=$PREFIX \
--disable-neon \
--disable-hwaccels \
--disable-gpl \
--disable-postproc \
--enable-shared \
--enable-jni \
--disable-mediacodec \
--disable-decoder=h264_mediacodec \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
--extra-cflags="-Os -fpic" \
--enable-nonfree \
--enable-gpl \
--enable-cross-compile \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--nm=$NM \
--cc=$CC \
--cxx=$CXX \
--sysroot=$SYSROOT
# make clean
make -j2
make install
echo "building ffmpeg for android $CPU completed"
}
build_android_arm
当运行./configure出错时,查看ffbuild/config.log以查看具体的出错信息。
6)当你下载了ffmpeg-4.2.1的源码后,但不想编译任何第三方库,只是想编译ffmpeg,那么编译脚本为:
#!/bin/bash
NDK=这里是NDK的目录,替换成自己本机上的正确的目录
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
#ANDROID_LIB_PATH="$(pwd)/android"
ARCH=arm
CPU=arm-v7a
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
PREFIX=$(pwd)/android/$CPU
CROSS_PREFIX=$TOOLCHAIN/bin/llvm-
#OPTIMIZE_CFLAGS="-march=$ARCH"
API=23
BASEPATH=$(cd `dirname $0`; pwd)
echo $BASEPATH
NM=$TOOLCHAIN/bin/llvm-nm
CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
#FDK_INCLUDE=$BASEPATH/fdk-aac/android/$CPU/include
echo $CC
echo $CXX
function build_android_arm
{
echo "build ffmpeg for android $CPU"
./configure \
--prefix=$PREFIX \
--disable-gpl \
--disable-postproc \
--enable-shared \
--enable-jni \
--enable-neon \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-hwaccel=h264_mediacodec \
--disable-static \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-symver \
--disable-stripping \
--extra-cflags="-Os -fpic -mfpu=neon -mfloat-abi=softfp -marm" \
--enable-nonfree \
--enable-gpl \
--enable-cross-compile \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--nm=$NM \
--cc=$CC \
--cxx=$CXX \
--sysroot=$SYSROOT
#make clean
#make -j2
#make install
echo "configure ffmpeg for android $CPU completed"
}
export AR=$TOOLCHAIN/bin/llvm-ar
export AS=$TOOLCHAIN/bin/llvm-as
export LD=$TOOLCHAIN/bin/llvm-ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
build_android_arm
#make clean
#make && make install
上面只是configure的脚本,configure成功后不要忘了运行make && make install
上面所有库编译出来的文件都在当前目录下的android目录下。
有时候,虽然成功编译出库文件,但还编译出来的库文件可能不是我们希望的。因为我们希望编译出来的是armv8-a 64位的库。可以通过如下命令验证编译出来的库。
file + 共享库名
file libavcodec.so
libavcodec.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, stripped
file + 目标文件名
llvm-objdump + 静态库名
这里的llvm-objdump是在android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin目录下