基于Android O8.1的ffmpeg NDK 开发 - 3 - CMakeList.txt解析

上两篇文章中,只是讲了APP如何创建,他们都使用到了同一个CMakeList.txt文件,但是没有仔细分析这个文件的作用,现在就仔细分析一下.

首先什么是CMakeList.txt,它是一个构建工具CMake所使用的文件,CMake与Make工具类似,Make工具使用Makefile来确定编译规则,而CMake通过CMakeList来确定编译规则,这个CMakeList.txt就是CMake的构建脚本,Android Studio中默认使用CMake来构建C语言相关的文件。

在创建支持C++的工程时,如果勾选了 Include C++ Support复选框的话,Android Studio会为我们自动创建一个CMakeList.txt文件,这个文件中包含了很多注释,正是我们学习的好模板,如下所示:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

我们来一步一步分解讲解它

1. 首先:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

来确定所需CMake的最小版本号。

 

2. 添加库

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

通过add_library()来向CMake构建脚本中添加源文件或者库。add_library()的三个参数分别是:库名称,库属性(STATIC or SHARED),库路径。Android Studio在同步项目后会显示关联的头文件,不过,为了确保CMake在编译时能够找到头文件,还需要通过include_directories()命令添加到CMake构建脚本中,并指定头文件的路径。

add_library(...)

# Specifies a path to native header files.
include_directories(src/main/cpp/include/)

同时,CMake中使用的标准库文件的命名是:

lib库名称.so

例如,在构建脚本中指定"native-lib"作为共享库的名称,CMake将创建一个名称为 libnative-lib.so的文件。不过,在Java代码中加载此库时,将使用在CMake构建脚本中指定的名称。

static {
    System.loadLibrary(“native-lib”);
}

同时也可以使用多个add_library()命令来添加多个库。比如在ffmpeg分开编译成多个库的情况下,就可以使用多个add_library()命令把他们都添加进去,如下所示:

add_library(native-lib
            SHARED
            src/main/cpp/native-lib.cpp )

set(JNI_LIBS_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs)

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

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

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

add_library(avcodec
            SHARED
            IMPORTED )
set_target_properties(avcodec
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavcodec.so )

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

add_library(avfilter
            SHARED
            IMPORTED )
set_target_properties(avfilter
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavfilter.so )

add_library(avdevice
            SHARED
            IMPORTED )
set_target_properties(avdevice
                      PROPERTIES IMPORTED_LOCATION
                      ${JNI_LIBS_DIR}/${ANDROID_ABI}/libavdevice.so )

include_directories(${JNI_LIBS_DIR}/includes)

同时,也许你已经注意到了,在每一个add_library()后面,都有一个set_target_properties(),这是因为,ffmpeg的库为不同的CPU架构提供了不同的软件包,并将其组织到单独的目录中了,所以要向CMake的构建脚本中添加库的多个ABI版本,而不必为每个版本的库编写多个命令,可以使用 ANDROID_ABI路径变量,此变量可以使用NDK支持的一组默认ABI,从而让Gradle自动选择对应的ABI,那么这个NDK默认支持的ABI是在哪指定的呢?就是在app/src/build.gradle中,咱们添加的

ndk {
        abiFilters 'armeabi-v7a', 'arm64-v8a'
    }

3. 使用原生的NDK API和库:

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

通过find_library()函数可以从NDK中找到NDK中支持的日志库,并将其路径保存为一个变量,如上面所示,${log-lib}就是该函数返回的路径变量,这个变量可以在其他地方被使用,比如下面要讲的关联库。

4. 关联库:

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

为了确保原生库可以在log库中调用函数,需要使用target_link_libraries()命令来关联库,比如在之前的例子中,如下所示:

target_link_libraries(native-lib
                      android
                      ffmpeg
                      ${log-lib})

至此,这个CMakeList.txt就简单分析完毕了。

 

最后放一下官方的一个链接:https://developer.android.com/studio/projects/add-native-code?hl=zh-cn

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值