在 Android NDK 开发中, CMake 是帮助我们来生成 makefle 文件的, 本文的示例是在 windows 中进行的, CMake 安装相关的可以参考本文 Windows10下配置CMake+Make+Cpp环境, 这里不做介绍
初识
使用 CMake 最重要的文件之一是 CMakeLists.txt 文件, 所以我们直接先创建好文件
|
|
其中 hello.cpp 的文件只有一个日志输出
|
|
文件目录结构如下, 然后我们使用 cmd 定位到该目录下, 开始进行编译
|
|
运行完成只有, 就会得到一个 makefile 文件
然后再执行 make, 其实就是执行 makefile 文件了
|
|
然后就会得到一个 hello.out 的输出文件
最后再运行, 输出如下
到这里, 我们通过 CMake 就构建生成了一个简单 C++ 项目, 步骤并不复杂, 最重要的是需要掌握 CMakeLists.txt 如何编写, 接下来看看它们都代表什么意思
常见 CMakeLists 语法
注:CMakeLists 对大小写没有限制
cmake_minimum_required 表示支持的 cmake 最小版本,这里是 3.16
1
cmake_minimum_required(VERSION 3.16)
PROJECT 表示项目名称,这里是 HELLO
1
PROJECT (HELLO)
MESSAGE 是用来打印输出信息的, 这里的 xxx_BINARY_DIR 前面都需要带上项目的名称, 其中 HELLO_SOURCE_DIR 和 PROJECT_SOURCE_DIR 是一样的, 代表的是 CMakeLists 文件所在的目录, BINARY_DIR 表示的是构建目录, 也就是 makefile 文件所在的目录, 一般情况下如果通过 cmake 指定在不同的文件中生成构建文件, 它们两路径就会不一致
1 2 3
MESSAGE(STATUS "this is BINARY dir "${HELLO_BINARY_DIR}) MESSAGE(STATUS "this is SOURCE dir "${HELLO_SOURCE_DIR}) MESSAGE(STATUS "this is PROJECT_SOURCE dir "${PROJECT_SOURCE_DIR})
set 用于指定变量 set(key value) ,这里表示 SRC_LIST 变量为 hello.cpp
1
SET(SRC_LIST hello.cpp)
add_executable 表示生成可执行文件,括号中第一个部分表示生成可执行文件的名称。后面跟着项目中所使用的源码文件, 这里 SRC_LIST 是一个变量, 他的值是 hello.cpp
1
ADD_EXECUTABLE(hello.out ${SRC_LIST})
构建生成 .so 动态库
说白了就是将我们 c 的源代码打包成一个 so 库, 给别人使用的, 现在我们打包成一个 libmath.so 库, 其中的源代码如下
|
|
|
|
|
|
|
|
|
|
他们的目录结构是这样的
部分头文件都不展示了, 都比较简单, 然后接下来编写我们的最重要的 CMakeLists.txt 文件,
|
|
这里主要的步骤就是
添加头文件
1
INCLUDE_DIRECTORIES (${PROJECT_SOURCE_DIR}/include)
添加源代码文件
1 2 3
# 指定 src 目录下的所有 .cpp 文件(源文件) # SRC_LIST 代表 src 目录下的所有源文件 AUX_SOURCE_DIRECTORY (${PROJECT_SOURCE_DIR}/src SRC_LIST)
指定生成动态库的输出目录
1
SET (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
构建 so 库, ADD_LIBRARY 关键字表示构建链接库,第一参是名称;第二参在 SHARED 表示构建 动态链接库, 不配置的话, 默认是 .a 的静态库 ;第三参是源文件列表
1
ADD_LIBRARY (math SHARED ${SRC_LIST})
ps 到了这里,出了一个小插曲,之前都是在 windows 下构建的, 这一步我们需要构建出 so 库, so 库只能在 Linux 的环境下构建, 所以被迫切换在 Linux 环境中, 我这里是用的是 windows 中的 WSL 子系统, 安装步骤如下
先去微软商店安装 Ubuntu 系统, 然后打开, 或者在 windows 中, 输入 wsl -u root 进入
然后安装 cmake 和 gcc , 输入如下命令
1 2
apt install cmake sudo apt-get install build-essential
安装好了, 输入如下命令, 可以看看有没有安装成功
|
|
接着使用 cd /mnt/windows的磁盘路径, 可以访问 windows 的磁盘目录, 然后就可以进行编译了
可以看到, 这样就成功编译了我们想要的 so 库了
链接外部动态库与头文件
在上一个步骤中, 我们已经成功编译出来了 so 库, 接下来, 我们来使用一下这个 so 库, 其实这步骤, 你可以想象成, 你编译了一个 ffmpeng 的 so 库, 现在你要在你的项目链接去是用它, 照例还是编写 CMakeLists
|
|
集成一个三方的动态链接库, 一共 3 件事
- include_directories 搜索引入头文件
- link_libraries 搜索对应的链接库
- target_link_libraries 对库进行链接,注意名称,这里的库名是 libmath.so ,指定的名称是 math, 如果有多个, 这里可以添加多个
其中, hello.cpp 的代码还是一致的, 可以发现我们这里只是引入了头文件, 源码的细节已经被我们隐藏在 so库, 照例还是 cmake make 等编译
可以看到,运行成功,so 库的使用没有问题,顺带说一句,这个 so 库只是在 Linux 中编译出来的,它只能在 Linux 中使用,如果想要在 Android 中使用,必须交叉编译了,关于如何交叉编译,敬请期待下一篇文章