Android NDK 开发之 CMake 必知必会

本文介绍了CMake在AndroidStudio中的使用,包括如何通过CMakeLists.txt配置文件编译动态库和可执行文件,展示了基本操作步骤,如添加库、指定文件和版本,以及高级语法如变量管理、数学和字符串操作,以及平台相关常量的使用。
摘要由CSDN通过智能技术生成

这意味就不需要再编写 .mk 文件来编译 so 动态库了。

CMake 是一个跨平台构建系统,在 Android Studio 引入 CMake 之前,它就已经被广泛运用了。

Google 官方网站上有对 CMake 的使用示范,可以参考 官方指南

总结官网对 CMake 的使用,其实也就如下的步骤:

  1. add_library 指定要编译的库,并将所有的 .c.cpp 文件包含指定。
  2. include_directories 将头文件添加到搜索路径中
  3. set_target_properties 设置库的一些属性
  4. target_link_libraries 将库与其他库相关联

如果你对上面的步骤还是不了解,那么接下来就更深入了解 CMake 相关内容吧~~~

CMake 的基本操作

Clion 作为工具来讲解 CMake 的基本使用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CMake 编译可执行文件

一个打印 hello world 的 cpp 文件,通过 CMake 将它编译成可执行文件。

在 cpp 的同一目录下创建 CMakeLists.txt 文件,内容如下:

指定 CMake 使用版本

cmake_minimum_required(VERSION 3.9)

工程名

project(HelloCMake)

编译可执行文件

add_executable(HelloCMake main.cpp )

其中,通过 cmake_minimum_required 方法指定 CMake 使用版本,通过 project 指定工程名。

add_executable 就是指定最后编译的可执行文件名称和需要编译的 cpp 文件,如果工程很大,有多个 cpp 文件,那么都要把它们添加进来。

定义了 CMake 文件之后,就可以开始编译构建了。

CMake 在构建工程时会生成许多临时文件,避免让这些临时文件污染代码,一般会把它们放到一个单独的目录中。

操作步骤如下:

在 cpp 目录下创建 build 目录

mkdir build

调用 cmake 命令生成 makefile 文件

cmake …

编译

make

在 build 目录中可以找到最终生成的可执行文件。

这就是 CMake 的一个简单操作,将 cpp 编译成可执行文件,但在 Android 中,大多数场景都是把 cpp 编译成库文件。

CMake 编译静态库和动态库

同样还是一个 cpp 文件和一个 CMake 文件,cpp 文件内容为打印字符串的函数:

#include
void print() {
std::cout << “hello lib” << std::endl;
}

同时,CMake 文件也要做相应更改:

cmake_minimum_required(VERSION 3.12)

指定编译的库和文件,SHARED 编译动态库

add_library(share_lib SHARED lib.cpp)

STATIC 编译静态库

add_library(share_lib STATIC lib.cpp)

通过 add_library 指定要编译的库的名称,以及动态库还是静态库,还有要编译的文件。

最后同样地执行构建,在 build 目录下可以看到生成的库文件。

到这里,就基本可以使用 CMake 来构建 C/C++ 工程了。

CMake 基本语法

熟悉了上面的基本操作之后,就必然会遇到以下的问题了:

  • 如果要参与编译的 C/C++ 文件很多,难道每个都要手动添加嘛?
  • 可以把编译好的可执行文件或者库自动放到指定位置嘛?
  • 可以把编译好的库指定版本号嘛?

带着这些问题,还是要继续深入学习 CMake 的相关语法,最好的学习材料就是 官网文档 了。

为了避免直接看官方文档时一头雾水,这里列举一些常用的语法命令。

注释与大小写

在前面就已经用到了 CMake 注释了,每一行的开头 # 代表注释。

另外,CMake 的所有语法指令是不区分大小写的。

变量定义与消息打印

通过 set 来定义变量:

变量名为 var,值为 hello

set(var hello)

当需要引用变量时,在变量名外面加上 ${} 符合来引用变量。

引用 var 变量

${var}

还可以通过 message 在命令行中输出打印内容。

set(var hello)
message(${var})

数学和字符串操作

数学操作

CMake 中通过 math 来实现数学操作。

math 使用,EXPR 为大小

math(EXPR )

math(EXPR var “1+1”)

输出结果为 2

message(${var})

math 支持 +, -, *, /, %, |, &, ^, ~, <<, >> 等操作,和 C 语言中大致相同。

字符串操作

CMake 通过 string 来实现字符串的操作,这波操作有很多,包括将字符串全部大写、全部小写、求字符串长度、查找与替换等操作。

具体查看 官方文档

set(var “this is string”)
set(sub “this”)
set(sub1 “that”)

字符串的查找,结果保存在 result 变量中

string(FIND ${var} ${sub1} result )

找到了输出 0 ,否则为 -1

message(${result})

将字符串全部大写

string(TOUPPER v a r r e s u l t ) m e s s a g e ( {var} result) message( varresult)message({result})

求字符串的长度

string(LENGTH v a r n u m ) m e s s a g e ( {var} num) message( varnum)message({num})

另外,通过空白或者分隔符号可以表示字符串序列。

set(foo this is a list) // 实际内容为字符串序列
message(${foo})

当字符串中需要用到空白或者分隔符时,再用双括号""表示为同一个字符串内容。

set(foo “this is a list”) // 实际内容为一个字符串
message(${foo})

文件操作

CMake 中通过 file 来实现文件操作,包括文件读写、下载文件、文件重命名等。

具体查看 官方文档

文件重命名

file(RENAME “test.txt” “new.txt”)

文件下载

把文件 URL 设定为变量

set(var “http://img.zcool.cn/community/0117e2571b8b246ac72538120dd8a4.jpg”)

使用 DOWNLOAD 下载

file(DOWNLOAD ${var} “/Users/glumes/CLionProjects/HelloCMake/image.jpg”)

在文件的操作中,还有两个很重要的指令 GLOBGLOB_RECURSE

GLOB 的使用

file(GLOB ROOT_SOURCE *.cpp)

GLOB_RECURSE 的使用

file(GLOB_RECURSE CORE_SOURCE ./detail/*.cpp)

其中,GLOB 指令会将所有匹配 *.cpp 表达式的文件组成一个列表,并保存在 ROOT_SOURCE 变量中。

GLOB_RECURSE 指令和 GLOB 类似,但是它会遍历匹配目录的所有文件以及子目录下面的文件。

使用 GLOBGLOB_RECURSE 有好处,就是当添加需要编译的文件时,不用再一个一个手动添加了,同一目录下的内容都被包含在对应变量中了,但也有弊端,就是新建了文件,但是 CMake 并没有改变,导致在编译时也会重新产生构建文件,要解决这个问题,就是动一动 CMake,让编译器检测到它有改变就好了。

预定义的常量

在 CMake 中有许多预定义的常量,使用好这些常量能起到事半功倍的效果。

  • CMAKE_CURRENT_SOURCE_DIR
  • 指当前 CMake 文件所在的文件夹路径
  • CMAKE_SOURCE_DIR
  • 指当前工程的 CMake 文件所在路径
  • CMAKE_CURRENT_LIST_FILE
  • 指当前 CMake 文件的完整路径
  • PROJECT_SOURCE_DIR
  • 指当前工程的路径

比如,在 add_library 中需要指定 cpp 文件的路径,以 CMAKE_CURRENT_SOURCE_DIR 为基准,指定 cpp 相对它的路径就好了。

利用预定义的常量来指定文件路径

add_library( # Sets the name of the library.
openglutil

Sets the library as a shared library.

SHARED

Provides a relative path to your source file(s).

${CMAKE_CURRENT_SOURCE_DIR}/opengl_util.cpp
)

平台相关的常量

CMake 能够用来在 Window、Linux、Mac 平台下进行编译,在它的内部也定义了和这些平台相关的变量。

具体查看 官方文档

列举一些常见的:

  • WIN32
  • 如果编译的目标系统是 Window,那么 WIN32 为 True 。
  • UNIX
  • 如果编译的目标系统是 Unix 或者类 Unix 也就是 Linux ,那么 UNIX 为 True 。
  • MSVC
  • 如果编译器是 Window 上的 Visual C++ 之类的,那么 MSVC 为 True 。
  • ANDROID
  • 如果目标系统是 Android ,那么 ANDROID 为 1 。
  • APPLE
  • 如果目标系统是 APPLE ,那么 APPLE 为 1 。

有了这些常量做区分,就可以在一份 CMake 文件中编写不同平台的编译选项。

if(WIN32){

do something

}elseif(UNIX){

do something

}

函数、宏、流程控制和选项 等命令

具体参考cmake-commands ,这里面包括了很多重要且常见的指令。

简单示例 CMake 中的函数操作:

function(add a b)
message(“this is function call”)
math(EXPR num “${a} + ${b}” )
message(“result is ${aa}”)
endfunction()

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

《507页Android开发相关源码解析》

因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

sikT8zF-1712613966064)]

《379页Android开发面试宝典》

[外链图片转存中…(img-mnNKFlLy-1712613966064)]

《507页Android开发相关源码解析》

[外链图片转存中…(img-NmOs8ABY-1712613966065)]

因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值