路径.png
内容如下:
arguments :
-H/Users/gebilaolitou/Desktop/codeLib/CMakeNDKDemo/app
-B/Users/gebilaolitou/Desktop/codeLib/CMakeNDKDemo/app/.externalNativeBuild/cmake/debug/x86
-DANDROID_ABI=x86
-DANDROID_PLATFORM=android-23
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Users/gebilaolitou/Desktop/codeLib/CMakeNDKDemo/app/build/intermediates/cmake/debug/obj/x86
-DCMAKE_BUILD_TYPE=Debug
-DANDROID_NDK=/Users/gebilaolitou/Library/Android/sdk/ndk-bundle
-DCMAKE_CXX_FLAGS=
-DCMAKE_TOOLCHAIN_FILE=/Users/gebilaolitou/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake
-DCMAKE_MAKE_PROGRAM=/Users/gebilaolitou/Library/Android/sdk/cmake/3.6.4111459/bin/ninja
-GAndroid Gradle - Ninja
jvmArgs :
更多的可以填写的命令参数和含义可以参见Android NDK-CMake文档
ok上面既然提到了CMakeLists.txt
,那我们就来看下CMakeLists.txt
(三) CMakeLists.txt
CMakeLists.txt
这个文件主要定义了哪些文件需要编译,以及和其他库的关系等,那让我们来看下我们项目中的CMakeLists.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} )
上面很多是注释,我们除去注释来个"精简干练版"的如下:
cmake_minimum_required(VERSION 3.4.1)
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 )
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 )
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
CMakeLists.txt
我们看到这里主要是分为四个部分,下面我们就依次来看下
- cmake_minimum_required(VERSION 3.4.1):指定CMake的最小版本
- add_library:创建一个静态或者动态库,并提供其关联的源文件路径,开发者可以定义多个库,CMake会自动去构建它们。Gradle可以自动将它们打包进APK中。
- 第一个参数——native-lib:是库的名称
- 第二个参数——SHARED:是库的类别,是
动态的
还是静态的
- 第三个参数——src/main/cpp/native-lib.cpp:是库的源文件的路径
- find_library:找到一个预编译的库,并作为一个变量保存起来。由于CMake在搜索库路径的时候会包含系统库,并且CMake会检查它自己之前编译的库的名字,所以开发者需要保证开发者自行添加的库的名字的独特性。
- 第一个参数——log-lib:设置路径变量的名称
- 第一个参数—— log:指定NDK库的名子,这样CMake就可以找到这个库
- target_link_libraries:指定CMake链接到目标库。开发者可以链接多个库,比如开发者可以在此定义库的构建脚本,并且预编译第三方库或者系统库。
- 第一个参数——native-lib:指定的目标库
- 第一个参数——${log-lib}:将目标库链接到NDK中的日志库,
这其实是一个最基础的CMakeLists.txt
,其实CMakeLists.txt
里面可以非常强大,比如自定义命令、查找文件、头文件包含、设置变量等等。这里推荐CMake的官网文档,不过是英文的,不好阅读,大家可以参考中文的CMake手册
上面分析完毕CMakeLists.txt
,我们就大致的知道了CMake整体的构建流程,那我们就来看下
(四) CMake的运转流程
- 1、Gradle 调用外部构建脚本
CMakeLists.txt
- 2、CMake 按照构建脚本的命令将 C++ 源文件
native-lib.cpp
编译到共享的对象库中,并命名为 libnative-lib.so
,Gradle 随后会将其打包到APK中 - 3、运行时,应用的
MainActivity
会使用System.loadLibrary()
加载原生库。应用就是可以使用库的原生函数stringFromJNI()
。
PS:这里注意一点就是:Instant Run
与使用原生的项目不兼容
如果想看Gradle是否将原生库打包到APK中,可以使用Analyze APK
来检测。
七、CMake的应用
我们在做日常需求的时候,往往会遇到一个问题,即在已有的项目中,添加C库,这样就不能通过上面的创建
流程,来使用CMake。那怎么办?
其实没关系的,CMake也提供这样的功能的,现在我们就回到上面的第一个demo中,删除和NDK的有关的所有代码,删除后其目录如下: