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