android ndk编译so库,脚本编译ffmpeg5.0示例

今天收了份csdn小礼物,上来补篇博客。

环境配置

下载,安装什么的自己参考一下官网。
从 NDK r19 开始,NDK 默认安装的工具链可供使用。与任意构建系统进行交互时不再需要使用 make_standalone_toolchain.py 脚本。

简单示例(利用cmake)

demo工程图
demo结构
sum.h

#ifndef FFMPEGDEMO_SUM_H
#define FFMPEGDEMO_SUM_H

//一定要extern "C" 不然会链接错误
extern "C"
int sum(int val1,int val2);

#endif

sum.c

#include "sum.h"

int sum(int val1,int val2){
    
    
    return val1+val2;
}

CMakeLists.txt

#指定CMake最低的编译版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.14)

# 定义一个工程名
PROJECT(MAKE_SO)

#搜集src目录下的所有的 源文件
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src SRC_LIST) #找到src目录下所有源文件赋值给SRC_LIST
#另一种写法
#FILE(GLOB SRC_LIST "${PROJECT_SOURCE_DIR}/src/*.c" "${PROJECT_SOURCE_DIR}/src/*.cpp")

#指定头文件目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)

#指定 so的生成目录 lib
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

# 打印
MESSAGE(STATUS "srclist: " ${SRC_LIST})
#-- srclist: /home/ubuntu/learnC/learnCMakeList/make-so/src/main.c/home/ubuntu/learnC/learnCMakeList/make-so/src/sum.c

#生成动态库 默认生成静态库,SHARED指定动态库
ADD_LIBRARY(make_so SHARED ${SRC_LIST})

as_build.sh:

#!/bin/bash
rm -rf build
mkdir build
cd build
#设置交叉编译的参数
echo ${NDK_ROOT}
cmake \
-DANDROID_NDK=${NDK_ROOT} \
-DCMAKE_TOOLCHAIN_FILE=${NDK_ROOT}/build/cmake/android.toolchain.cmake \
-DANDROID_ABI="arm64-v8a" \
-DANDROID_NATIVE_API_LEVEL=19 \
..
make

第三方编译示例,ffmpeg5.0

ndk版本 :android-ndk-r23b
基础依赖参考:centos 安装 ffmpeg 并添加 libx264库 libfdk-aac库 openssl库
编译参考文章:使用Android Studio开发FFmpeg的正确姿势
适配后编译脚本

#!/bin/bash
# 用于编译android平台的脚本

# NDK所在目录,这里要自定义一下
NDK_PATH=$NDK_ROOT
HOST_PLATFORM=linux-x86_64
HOST_PLATFORM=$HOST_PLATFORM
# minSdkVersion 
API=23

TOOLCHAINS="$NDK_PATH/toolchains/llvm/prebuilt/$HOST_PLATFORM"
SYSROOT="$NDK_PATH/toolchains/llvm/prebuilt/$HOST_PLATFORM/sysroot"
# 生成 -fpic 与位置无关的代码
CFLAG="-D__ANDROID_API__=$API -Os -fPIC -DANDROID "
LDFLAG="-lc -lm -ldl -llog "

# 输出目录
PREFIX=`pwd`/android-build
# 日志输出目录
CONFIG_LOG_PATH=${
    
    PREFIX}/log
# 公共配置
COMMON_OPTIONS=
# 交叉配置
CONFIGURATION=

build() {
    
    
  APP_ABI=$1
  echo "======== > Start build $APP_ABI"
  case ${
    
    APP_ABI} in
  armeabi-v7a)
    ARCH="arm"
    CPU="armv7-a"
    MARCH="armv7-a"
    TARGET=armv7a-linux-androideabi
    CC="$TOOLCHAINS/bin/$TARGET$API-clang"
    CXX="$TOOLCHAINS/bin/$TARGET$API-clang++"
    LD="$TOOLCHAINS/bin/$TARGET$API-clang"
    # 交叉编译工具前缀
    CROSS_PREFIX="$TOOLCHAINS/bin/arm-linux-androideabi-"
    EXTRA_CFLAGS="$CFLAG -mfloat-abi=softfp -mfpu=vfp -marm -march=$MARCH "
    EXTRA_LDFLAGS="$LDFLAG"
    EXTRA_OPTIONS="--enable-neon --cpu=$CPU "
    ;;
  arm64-v8a)
    ARCH="aarch64"
    TARGET=$ARCH-linux-android
    CC="$TOOLCHAINS/bin/$TARGET$API-clang"
    CXX="$TOOLCHAINS/bin/$TARGET$API-clang++"
    LD="$TOOLCHAINS/bin/$TARGET$API-clang"
    CROSS_PREFIX="$TOOLCHAINS/bin/$TARGET-"
    EXTRA_CFLAGS="$CFLAG"
    EXTRA_LDFLAGS="$LDFLAG"
    EXTRA_OPTIONS=""
    ;;
  x86)
    ARCH="x86"
    CPU="i686"
    MARCH="i686"
    TARGET=i686-linux-android
    CC="$TOOLCHAINS/bin/$TARGET$API-clang"
    CXX="$TOOLCHAINS/bin/$TARGET$API-clang++"
    LD="$TOOLCHAINS/bin/$TARGET$API-clang"
    CROSS_PREFIX="$TOOLCHAINS/bin/$TARGET-"
    #EXTRA_CFLAGS="$CFLAG -march=$MARCH -mtune=intel -mssse3 -mfpmath=sse -m32"
    EXTRA_CFLAGS="$CFLAG -march=$MARCH  -mssse3 -mfpmath=sse -m32"
    EXTRA_LDFLAGS="$LDFLAG"
    EXTRA_OPTIONS="--cpu=$CPU "
    ;;
  x86_64)
    ARCH="x86_64"
    CPU="x86-64"
    MARCH="x86_64"
    TARGET=$ARCH-linux-android
    CC="$TOOLCHAINS/bin/$TARGET$API-clang"
    CXX="$TOOLCHAINS/bin/$TARGET$API-clang++"
    LD="$TOOLCHAINS/bin/$TARGET$API-clang"
    CROSS_PREFIX="$TOOLCHAINS/bin/$TARGET-"
    #EXTRA_CFLAGS="$CFLAG -march=$CPU -mtune=intel -msse4.2 -mpopcnt -m64"
    EXTRA_CFLAGS="$CFLAG -march=$CPU -msse4.2 -mpopcnt -m64"
    EXTRA_LDFLAGS="$LDFLAG"
    EXTRA_OPTIONS="--cpu=$CPU "
    ;;
  esac

  echo "-------- > Start clean workspace"
  make clean

  echo "-------- > Start build configuration"
  CONFIGURATION="$COMMON_OPTIONS"
  CONFIGURATION="$CONFIGURATION --logfile=$CONFIG_LOG_PATH/config_$APP_ABI.log"
  CONFIGURATION="$CONFIGURATION --prefix=$PREFIX"
  CONFIGURATION="$CONFIGURATION --libdir=$PREFIX/libs/$APP_ABI"
  CONFIGURATION="$CONFIGURATION --incdir=$PREFIX/includes/$APP_ABI"
  CONFIGURATION="$CONFIGURATION --pkgconfigdir=$PREFIX/pkgconfig/$APP_ABI"
  CONFIGURATION="$CONFIGURATION --cross-prefix=$CROSS_PREFIX"
  CONFIGURATION="$CONFIGURATION --arch=$ARCH"
  CONFIGURATION="$CONFIGURATION --sysroot=$SYSROOT"
  CONFIGURATION="$CONFIGURATION --cc=$CC"
  CONFIGURATION="$CONFIGURATION --cxx=$CXX"
  CONFIGURATION="$CONFIGURATION --ld=$LD"
  # nm 和 strip
  CONFIGURATION="$CONFIGURATION --nm=$TOOLCHAINS/bin/llvm-nm"
  CONFIGURATION="$CONFIGURATION --strip=$TOOLCHAINS/bin/llvm-strip"
  CONFIGURATION="$CONFIGURATION $EXTRA_OPTIONS"

  echo "-------- > Start config makefile with $CONFIGURATION --extra-cflags=${EXTRA_CFLAGS} --extra-ldflags=${EXTRA_LDFLAGS}"
  ./configure ${
    
    CONFIGURATION} \
  --extra-cflags="$EXTRA_CFLAGS" \
  --extra-ldflags="$EXTRA_LDFLAGS"

  echo "-------- > Start make $APP_ABI with -j1"
  make -j1

  echo "-------- > Start install $APP_ABI"
  make install
  echo "++++++++ > make and install $APP_ABI complete."

}

build_all() {
    
    
  #配置开源协议声明
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-gpl"
  #目标android平台
  COMMON_OPTIONS="$COMMON_OPTIONS --target-os=android"
  #取消默认的静态库
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-static"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-shared"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-protocols"
  #开启交叉编译
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-cross-compile"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-optimizations"
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-debug"
  #尽可能小
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-small"
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-doc"
  #不要命令(执行文件)
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-programs"  # do not build command line programs
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-ffmpeg"    # disable ffmpeg build
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-ffplay"    # disable ffplay build
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-ffprobe"   # disable ffprobe build
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-symver"
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-network"
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-x86asm"
  COMMON_OPTIONS="$COMMON_OPTIONS --disable-asm"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-pthreads"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-mediacodec"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-jni"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-zlib"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-pic"
  #COMMON_OPTIONS="$COMMON_OPTIONS --enable-avresample"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=h264"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=mpeg4"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=mjpeg"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=png"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=vorbis"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=opus"
  COMMON_OPTIONS="$COMMON_OPTIONS --enable-decoder=flac"
  echo "COMMON_OPTIONS=$COMMON_OPTIONS"
  echo "PREFIX=$PREFIX"
  echo "CONFIG_LOG_PATH=$CONFIG_LOG_PATH"
  mkdir -p ${
    
    CONFIG_LOG_PATH}
  #    build $app_abi
  build "armeabi-v7a"
  build "arm64-v8a"
  build "x86"
  build "x86_64"
}

echo "-------- Start --------"

build_all

echo "-------- End --------"

安卓工程测试用CMakeLists.txt

cmake_minimum_required(VERSION 3.18.1)

project("ffmpeg5")

MESSAGE(STATUS "this is SOURCE dir " ${HELLO_SOURCE_DIR})

include_directories(${CMAKE_SOURCE_DIR}/include/${ANDROID_ABI})
include_directories(${CMAKE_SOURCE_DIR}/include)

#link_directories(${CMAKE_SOURCE_DIR}/jnilibs/${ANDROID_ABI})

AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src SRC_LIST)

add_library(ffmpeg5 SHARED ${SRC_LIST})

add_library(avcodec SHARED IMPORTED )
set_target_properties(
        avcodec
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/libavcodec.so
)
add_library(avdevice SHARED IMPORTED )
set_target_properties(
        avdevice
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/libavdevice.so
)
add_library(avfilter SHARED IMPORTED )
set_target_properties(
        avfilter
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/libavfilter.so
)

add_library(avformat SHARED IMPORTED )
set_target_properties(
        avformat
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/libavformat.so
)

add_library(avutil SHARED IMPORTED )
set_target_properties(
        avutil
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/libavutil.so
)

add_library(swresample SHARED IMPORTED )
set_target_properties(
        swresample
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/libswresample.so
)

add_library(swscale SHARED IMPORTED )
set_target_properties(
        swscale
        PROPERTIES IMPORTED_LOCATION
        ${CMAKE_SOURCE_DIR}/jniLibs/${ANDROID_ABI}/libswscale.so
)


find_library(log-lib log)

target_link_libraries(ffmpeg5
        # 编解码(最重要的库)
        avcodec
        # 设备信息
        avdevice
        # 滤镜特性处理库
        avfilter
        # 封装格式处理库
        avformat
        # 工具库(大部分库都需要这个库的支持)
        avutil
        # 音频采样数据格式转换库
        swresample
        # 视频像素数据格式转换
        swscale
        ${log-lib} )

测试代码ffmpeg5.cpp

#include <jni.h>
#include <string>

extern "C" {
    
    
#include "libavcodec/avcodec.h"
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_zhipuchina_ffmpeg5_NativeLib_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    
    

    char str[25];
    sprintf(str,"%d",avcodec_version());
    return env->NewStringUTF(str);
}

猜你喜欢

转载自blog.csdn.net/weixin_42404974/article/details/123961692