一. 背景
在Android Studio 2.2的时候,已经默认使用CMake的Native编译方案,直接使用Android Studio创建新工程即可。简单的流程可以参考
在 Android Studio 2.2 中愉快地使用 C/C++
这边文章主要讲解为什么要使用CMake,简要介绍CMake的一些配置,以及CMake和Gradle结合的方式。
二. CMake介绍
2.1 为什么要用CMake替换现有的ndk build方案
既然说到了CMake,很自然的就想到为什么要用CMake替代已有Application.mk+Android.mk的配置方案。
其实ndk build的配置方案和CMake的语法很类似,配置相同复杂度的项目所有的配置语句数量基本相同。但是CMake的优势在于跨平台,很多人疑惑这里说的是Android项目,为什么会提到跨平台呢?如果做过复杂Native项目的人都会知道,一般底层Native代码会有很大一部分要和iOS通用,甚至我做的项目要给Linux服务器共用,这就造成了需要写很多套的配置,因为ndk build的配置方案只适用于Android平台。并且很多linux程序员和iOS程序员都会对CMake比较熟悉,毕竟CMake一开始就是一款跨平台的编译工具,因此就算需要学习也比较有价值。
既然配置复杂度基本相同,但是CMake有跨平台的好处,更优秀的CMake显然是更好的选择。当然,如果项目本来就是ndk build的配置,其实选择迁移到CMake也不是很有必要(虽然工作量并不大),但是如果是一个新的native项目,建议最好使用CMake的配置方式。
2.2 语法简述
CMake的配置文件一般命名为CMakeLists.txt,只需要按照规定的构建语句既可以配置好动态库的各种编译属性,下面列举几个常用的构建语句,利用以下的语句应该就可以构建出大部分的项目了。
set(KEY VALUE)
用来设置某个变量的值,可以自定义变量,也可以设置某些配置项
例如:
#自定义UTILS_DIR为utils目录
set(UTILS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/utils)
#添加CXX_FLAGS标记"-Os",注意要在原来的基础上添加
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os")
include_directories(PATH1 PATH2)
设置包含的头文件目录
例如:
#在根目录utils目录下有一个crypt_utils.h以及engine目录下有个
#crypt_engine.h文件被引用,则需要如下配置
#可以结合上面提到的set方法简化配置
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/utils
${CMAKE_CURRENT_SOURCE_DIR}/engine
)
aux_source_directory(SRC_PATH_VALUE SRC_PATH_KEY)
将SRC_PATH_VALUE下的所有c\c++源文件赋值到SRC_PATH_KEY变量下
例如:
#在utils下有一个crypt_utils.cpp被使用,在engine目录下有个
crypt_engine.cpp被引用,则需要如下配置
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/utils SRC_PATH)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/engine SRC_PATH)
add_library(LIB_NAME SHARED|STATIC SRC_PATH)
声明动态库或者静态库,第一个参数是库的名字,第二个参数是声明为动态库或者静态
库,第三个参数是包含的源文件列表,通过aux_source_directory方法设置
例如:
add_library(demo SHARED ${SRC_PATH})
find_library(LIBRARY_ALIA_NAME LIBRARY_NAME)
target_link_libraries(LIB_NAME LIBRARY_ALIA_NAME)
添加链接库,如果需要用到安卓的log库,或者zip库,则可以通过上面两个方法
例如:
find_library(z_lib z)
target_link_libraries(demo ${z_lib})
三. Gradle集成CMake
3.1 如何在Gradle中集成CMake
在Gradle中集成CMake非常简单,只要在gradle中声明我们依据上述的语法创建的CMakeLists.txt文件即可:
android{
externalNativeBuild{
cmake{
path "CMakeLists.txt"
cFlags "-Wall"
cppFlags "-std=c++11"
}
ndk {
abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
'arm64-v8a'
}
}
}
除此之外还可以通过Gradle配置,例如上面的cFlags cppFlags等属性修改编译参数,当然,最好将这些修改统一写在CMakeLists.txt这个文件中,gradle只需要引入CMakeLists.txt就好,这样能让职责更加单一,方便维护。除此之外,扩展一下,如果需要支持不同的处理器,只需要添加修改ndk.abiFilters即可。
四. 总结
官方从Android Studio 2.2在新建项目时就默认使用CMake作为Native编译器了,作为一款跨平台的编译器,它语法简单,学习成本低,并且最重要的是得到了官方的支持。因此尽早拥抱CMake才是正确的选择。