CMake

为什么要使用CMake

嗯,考虑到能看到这里的基本都会对CMake 有一定了解,所以先不讲这东西是啥,问题是为啥要用这东西。

我们这边有一些需求,目的是基础功能保持稳定性,又因为涉及到多个类型的客户端(IOS、Android、Windows、Mac),那么共用的内容C++使用就是一种必然,同时考虑到后期的可维护性,CMake 的使用就应该是一种必然。

因为是要做公共基础内容,最直接的思考是提供静态库给各方使用,这也就间接回答了CMake 的用途,用来把源码生成二进制文件。

按照正常的流程,先给一个开胃菜,提供一个Demo。

推荐一个软件 CLine

CLineDemo

刚好能够提供C++ 静态库和动态库。

因为我需要优先做Android 的内容,所以我一步到位直接使用了AndroidStudio。

AndroidCmake

上面是简单的创建工程,咱们接着往下面。

以CLine 为例子

ClineCMake

CMake 文本的写法就是 需要设置 CMake version 然后给出一个 project(name) name 为生成静态库名字 ,设置C11 ,然后就是给这个project 添加需要编译的CPP文件

1
2
3
4
├── CMakeLists.txt
├── build
├── library.cpp
└── library.h

文件结构大致是这样,需要有**source file ** 、 build 文件夹(我不太喜欢CLine 默认的 cmake-build-debug,自己更改了)、和必需品 CMakeLists.txt

不依赖工具,可以在终端进入到当前文件夹下面的build 文件夹 然后执行 cmake ..

执行cmake 命令之后,需要生成库文件需要在当前命令行再次执行 make , 等命令执行完毕,库文件就会出现在build 文件夹。

依靠CLine 就相对容易,直接点击右上角的debug 标志即可。

如果一切运行正常,在build 文件夹下面就会出现需要的 CmakeDemo 这个名字的二进制文件,因为我们需要的是静态库,那么到现在为止这个静态库可以被拿来使用了。

如何检验是否为自己需要的二进制静态库

我们想要提供出去稳定可靠的二进制库,那么自测是必须不可少的一环。讲一下我这边比较常用的方式,我会去创建一个适合的console 工程,或者如果使用xcode , 我会创建一个可视化的对应平台APP,把库文件暴露的接口交给新建demo 工程,按照正常使用的流程,载入编译出来的库文件。

那么开搞。

因为这里打算先提供一下简单的demo , 只演示一下如何使用CMake ,创建静态库和使用静态库,这里简单替换原来的打印名言Hello,world! 更改为 **”Hello, from static lib !” **

在进入build 文件夹执行过最后的 make 命令后,能够拿到库文件 libCmakeDemo.a

我们放入到consoleDemo 工程中 然后文件结构是

1
2
3
4
5
├── CMakeLists.txt
├── cmake-build-debug
├── libCmakeDemo.a
├── library.h
└── main.cpp

更改CMakeLists.txt 内容如下

1
2
3
4
5
6
7
8
9
10
11
12
#设置cmake version
cmake_minimum_required(VERSION 3.17)
#设置变量名字
set(APP_NAME ConsoleDemo)
# 国际惯例 project name
project(${APP_NAME})
#C11
set(CMAKE_CXX_STANDARD 11)
# 这里需要链接静态库
link_libraries(${CMAKE_CURRENT_SOURCE_DIR}/libCmakeDemo.a)
#正常编译需要的 添加source 文件
add_executable(${APP_NAME} main.cpp library.h)

我这边比较懒,就直接搬运了静态库中使用的头文件,因为属于函数定义,并且没有特殊要求,这里就直接可以拿来使用。

看下main函数中的修改

1
2
3
4
5
6
7
8
9
#include <iostream>
#include "library.h"

int main() {
hello();
std::cout << "Hello, World!" << std::endl;
return 0;
}

这里就很简单了,直接引入头文件,然后在合适的地方进行执行。

结果如下:

1
2
Hello, from static lib !
Hello, World!

如预期

先写到这里,下次可以讲一下全平台的一些东西,比如一些难点,如果从C++ 通过nodejs 异步回调给JavaScript(可不是正常设置进去一个回调然后等执行后就从C++那边执行到JavaScript ,这样就没有技术含量)使用libuv 可以多次从C++ 回调给JavaScript,下次讲讲如何实现。

惯例,使用的demo 地址 Demo 地址