Android NDK 跨平台构建工具 CMake 使用笔记

一、CMake 介绍

CMake是一个跨平台的安装/编译工具,通过CMake我们可以通过简单的语句来描述所有平台的安装/编译过程。它能输出各种makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。Cmake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用。这使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式建构他的软件。

CMake的所有语句都写在一个CMakeLists.txt文件中,CMakeLists.txt 文件编写完成后,直接使用CMake命令进行运行即可 ,但是需要这个命令需要指向CMakeLists.txt 所在的目录。在AndroidStudio中,IDE会帮我们执行命令,我们可以暂时不需要了解CMake和CmakeList.txt之间的关系,但是我们需要了解如何编写CmakeList.txt 来配置我们的项目,以保证相关的库能正常的加载和运行。

补充:在之前的Android NDK学习(二):编译脚本语法Android.mk和Application.mk里面我们讲述过makefile相关的内容,感兴趣的可以自行查看。

二、CMakeLists 指令

在讲CMakeLists相关指令之前,可以看一下常见的CMakeLists.txt文件的内容,下面是使用CameraX+Rtmp开发推流功能的时候,创建的CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.4.1)

set(rtmp_lib_src_DIR ${PROJECT_SOURCE_DIR}/src/main/cpp)

add_subdirectory(${rtmp_lib_src_DIR}/librtmp)

include_directories(
    ${CMAKE_SOURCE_DIR}/src/main/cpp/include
)

# build application's shared lib
# For Java Call, the file of C/C++ Use UpperCase Name Space
add_library(rtmp-push-lib SHARED
    ${CMAKE_SOURCE_DIR}/src/main/cpp/RtmpPushLib.cpp
    ...other cpps
) 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 ) set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -L${rtmp_lib_src_DIR}/libs/${ANDROID_ABI}") # Include libraries needed for MediaEditor lib target_link_libraries(rtmp-push-lib rtmp x264 android log ${log-lib} )

 下面我们根据上面的配置文件,来逐步讲解各个指令的使用方式和意义:

1. cmake_minimum_required(VERSION 3.4.1) 指令

此指令的作用就是规定cmake程序的最低版本,属于可选的指令,但是一般情况下都会添加这个指令。如果CMakeLists.txt中使用了一些高版本cmake特有的命令的时候,是必须要加上的,这样能够提醒使用者升级到该版本之后再执行camke。

2. set 指令

set指令用于显式的定义变量。使用方式为set(var [value] [cache type docstring] [force]). 其中定义时必须填写的参数为:var 和 value。

3. add_subdirectory 指令

用于添加需要编译的源文件的子目录;语法为:add_subdirectory(source_dir [binary_dir][exclude_from_dir])。其中source_dir:向当前工程添加存放源文件的子目录,[binary_dir]:指定目标文件存放的位置,[exclude_from_dir]:将该目录从编译过程中排除。

注意:子目录也需要有CmakeLists.txt文件,以保证子目录下的源文件能够正常编译。

4. add_library 指令

add_library():用于将一组源文件编译生成一个库文件,并保存为 libname.so (lib 前缀是生成文件时 CMake自动添加上去的)。可传入多个源文件,其语法为:add_library(libname [SHARED | STATIC | MODULE] [EXCLUDE_FROM_ALL] [source])。

其中生成的有三种库文件类型,不写的话,默认为 STATIC。下面我们简单的讲解一下生成的库文件类型:

  • SHARED:表示生成的为动态库,可以在Java代码中使用System.loadLibaray(name)进行动态调用。
  • STATIC:表示生成的为静态库,集成到代码的时候,会在编译时调用。
  • MODULE:只有在dyld的系统有效,如果不支持dyld,则会被当作SHARED对待。

5. find_library 指令

这个指令是Android NDK开发提供的特有的Cmake指令,用于添加NDK API。语法为:find_library(<VAR> name1 path1 path2 ...)。例如上面的CMakeList.txt文件中,我们就添加了日志支持的API。

6. target_link_libraries 指令

target_link_libraries 指令用来为 target 添加需要链接的共享库,同样也可以用于为自己编写的共享库添加共享库链接。语法为:target_link_libraries(target library <debug | optimized> library2…)

三、参考资料

Android NDK 开发:CMake 使用:https://www.jianshu.com/p/c71ec5d63f0d

CMakeLists入门学习笔记(一):https://blog.csdn.net/lisfaf/article/details/90639611

CMake 入门实战:https://www.hahack.com/codes/cmake/

CMake 使用教程:https://www.jianshu.com/p/3078a4a195df

CMake使用简介及CMakeList.txt编写:https://www.pianshen.com/article/4159316635/

posted @ 2020-09-05 16:02  灰色飘零  阅读(913)  评论(0编辑  收藏  举报