JNI学习---关于CMake

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/johnWcheung/article/details/81382785

CMakeList.txt 文件说明

  • add_library:就是你想要将这个c++程序变成什么名字的库,以及这些c++程序在哪里

  • cmake_minimum_required:最低支持的cmake版本,例如: cmake_minimum_required(VERSION 3.4.1)

  • target_link_libraries:有两个参数,第一个参数表明库的目标,即第一步生成的库的名字,第二个参数是要在项目中使用的库,这个库已经存在了

  • find_library:这个方法有两个参数,第一个参数是想引入的库的名字,第二个是想把这个库放在这个项目的什么地方

# 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.

# 配置so库信息
add_library( # Sets the name of the library.
            # 生成的so库名称,此处生成的so文件名称是libnative-lib.so
             native-lib

             # Sets the library as a shared library.
             # STATIC:静态库,是目标文件的归档文件,在链接其它目标的时候使用
             # SHARED:动态库,会被动态链接,在运行时被加载
             # MODULE:模块库,是不会被链接到其它目标中的插件,但是可能会在运行时使用dlopen-系列的函数动态链接
             SHARED

             # Provides a relative path to your source file(s).
             # 资源文件,可以多个,
             # 资源路径是相对路径,相对于本CMakeLists.txt所在目录
             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.
              # android系统每个类型的库会存放一个特定的位置,而log库存放在log-lib中
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              # android系统在c环境下打log到logcat的库
              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} )

Gradle配置CMake

由于 CMake 的命令集成在了 gradle - externalNativeBuild 中,所以在 gradle 中有2个地方配置 CMake。

defaultConfig外面的 externalNativeBuild - cmake,指明了 CMakeList.txt 的路径;
defaultConfig 里面的 externalNativeBuild - cmake,主要填写 CMake 的命令参数。即由 arguments 中的参数最后转化成一个可执行的 CMake 的命令,可以在 .externalNativeBuild/cmake/debug/{abi}/cmake_build_command.txt 中查到。

// android下
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt" // cmake配置文件路径
        }
    }
// defaultConfig下
            cmake {
                cppFlags ""
                // 生成多个版本的so文件
                abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
            }

Q1:怎么指定 C++标准?

在 build_gradle 中,配置 cppFlags -std

externalNativeBuild {
  cmake {
    cppFlags "-frtti -fexceptions -std=c++14"
    arguments '-DANDROID_STL=c++_shared'
  }
}

Q2:add_library 如何编译一个目录中所有源文件?

使用 aux_source_directory 方法将路径列表全部放到一个变量中。

# 查找所有源码 并拼接到路径列表
aux_source_directory(${CMAKE_HOME_DIRECTORY}/src/api SRC_LIST)
aux_source_directory(${CMAKE_HOME_DIRECTORY}/src/core CORE_SRC_LIST)
list(APPEND SRC_LIST ${CORE_SRC_LIST})
add_library(native-lib SHARED ${SRC_LIST})

Q3:怎么调试 CMakeLists.txt 中的代码?

使用 message 方法

cmake_minimum_required(VERSION 3.4.1)
message(STATUS "execute CMakeLists")
...

然后运行后在 .externalNativeBuild/cmake/debug/{abi}/cmake_build_output.txt 中查看 log。

Q4:什么时候 CMakeLists.txt 里面会执行?

  • 测试了下,好像在 sync 的时候会执行。执行一次后会生成 makefile 的文件缓存之类的东西放在 externalNativeBuild 中。所以如果 CMakeLists.txt 中没有修改的话再次同步好像是不会重新执行的。(或者删除 .externalNativeBuild 目录)

  • 真正编译的时候好像只是读取.externalNativeBuild 目录中已经解析好的 makefile 去编译。不会再去执行 CMakeLists.txt

猜你喜欢

转载自blog.csdn.net/johnWcheung/article/details/81382785