编译环境及软件

1. ubuntu22 64bit desktop

2. android-ndk-r25c-linux.zip

3. ffmpeg-4.2.1

3. fdk-aac(via git)

4. x264(via git)

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目录下

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐