Introduction

CMake是一个跨平台的安装&编译工具,用其中的语句来描述所有平台的安装&编译过程,可以测试编译器所支持的C++的特性,类似Android Studio中的CMake

CMake并不能直接构建出最终的软件,而是使得熟悉某个集成开发环境(IDE)的开发者可以用标准的方式构建他的软件

CMake是一个旨在构建、测试以及打包软件的开源且跨平台的工具,通过简单的在编译器平台中独立的配置文件对软件编译过程进行控制管理

2021年5月份申请了一个大创项目,我们的项目内容是将ORB-SLAM2算法移植到安卓端,实现以ORB-SLAM2算法为核心的Android手机实时定位。我们选择了使用Android Studio进行开发,而ORB-SLAM2算法及其依赖库是由C++编写,要移植到安卓端,则需要学习JNICMake来实现在Java语言中调用C++的程序

CMakeLists

在安卓项目中,可以通过CMakeLists.txt实现CMake对于软件编译过程的管理,从而实现在Java环境下调用C++程序&函数

目前在Android Studio创建以Native C++为模板的安卓项目时,编译器会自动生成一个/src/main/cpp/路径下的CMakeLists.txt文件

项目会根据build.gradle等文件以及CMakeLists.txt文件进行构建,若要想熟练使用CMake,首先就要掌握其语法规则。不同的版本下CMake的语法规则可能会有所不同,具体可以参考官方文档进行学习

首先要知道CMake中是大小写不敏感的,用#来标记单行注释

下面来看创建项目后由Android Studio默认生成的CMakeLists.txt文件,如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 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.10.2)

# Declares and names the project.

project("cheeseburgerim")

# 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.

add_library( # Sets the name of the library.
native-lib

# Sets the library as a shared library.
SHARED

# Provides a relative path to your source file(s).
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.
log-lib

# Specifies the name of the NDK library that
# you want CMake to locate.
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} )

以下为CMake中常用指令的介绍

  • cmake_minimum_required()

该命令指明了对cmake的最低版本的要求,同时根据括号内的参数也可以控制最高版本

cmake_minimum_required(VERSION <min>[…<max>] [FATAL_ERROR])

其中中括号中的内容可以省略,即仅控制最低版本

1
2
3
4
# 限制cmake版本最低为3.10.2
cmake_minimum_required(VERSION 3.10.2)
# 限制cmake版本在3.10.2和3.12.0之间
cmake_minimum_required(VERSION 3.10.2 ... 3.12.0)
  • project()

用于指定工程名称,相当于给PROJECT_NAME变量赋值

project(<project_name> [<language_name>])

project(<PROJECT-NAME>
[VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
[DESCRIPTION <project-description-string>]
[HOMEPAGE_URL <url-string>]
[LANGUAGES <language-name>…])

1
2
3
4
5
6
7
8
9
10
# 指定工程名称(最常用)
project(cheeseburgerim)
# 指定工程名称及其版本号
project(cheeseburgerim 1.2.3.4)
# 指定工程名称及其描述
project(cheeseburgerim "This is Project CheeseburgerIM")
# 指定工程名称及其主页URL
project(cheeseburgerim HOMEPAGE_URL "https://cheeseburgerim.space")
# 指定工程名称及其编程语言
project(cheeseburgerim LANGUAGES "CXX")
  • add_library()

指定源文件,添加为库,编译成功后可在Java中调用库中的程序或函数

可以选择添加为静态库、动态库或者模块库,默认为静态库

add_library(<library_name> [STATIC|SHARED|MODULE] [source_file1] [source_file2] … )

1
2
3
4
5
6
7
8
9
# 添加包含两个文件的名为CheeseburgerIM动态库
add_library( # Sets the name of the library.
CheeseburgerIM

# Sets the library as a shared library.
SHARED

# Provides a relative path to your source file(s).
CheeseburgerIM.cpp CheeseburgerIM.h )
  • find_library()
  • target_link_libraries()