华南虎视觉组主页华南虎视觉组主页
首页
项目
通用
教程
Gitea
首页
项目
通用
教程
Gitea
  • 现代 CMake 教程

    • 【01】安装与基本介绍
      • 1. CMake 是什么
      • 2. 为什么用 CMake
        • 2.1 语法统一
        • 2.2 功能强大
      • 3. 怎么用 CMake
        • 3.1 安装
        • 3.2 CMake 生成建构档的步骤
    • 【02】CMake 的文件分布
    • 【03】变量的设置与引用
    • 【04】运算符与条件、循环语句
    • 【05】目标构建
    • 【06】变量参与 C++ 程序的编译
    • 【07】宏与函数
    • 【08】find_package 详解
    • 【09】生成器表达式
    • 【10】项目的导出与安装
    • 【11】项目实战
    • 【12】CTest
    • 【13】CPack

【01】安装与基本介绍

在安装某些开源库的时候,如果涉及到源码编译,经常会使用 CMake 完成构建、安装,初次接触 CMake 时,我们先回答

  • CMake 是什么
  • 为什么用 CMake
  • 怎么用 CMake

这三个问题。在对 CMake 有个大概印象之后,我们就可以继续探索更高级、更现代的用法。

1. CMake 是什么

下文是一句来自百度百科的定义,我们简单做个分段,并暂时删除不必要的内容。

  • CMake 是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)
  • 他能够输出各种各样的 makefile 或者 project 文件
  • CMake 并不直接建构出最终的软件,而是产生标准的建构档(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建构方式使用

首先我们可以明确,CMake 是一个工具。简单的、狭隘的说,跨平台就是可以在 Windows、Linux 发行版乃至 MacOS 等操作系统上使用。

其次,CMake 使用与 Python 性质等同的脚本语言。Python 一般在执行某个 py 文件的时候,会使用

python3 main.py

这种语句,完成对 main.py 的逐行解析,CMake 同样,在运行

cmake .. # .. 就表示上一级文件夹

后,可以解析来自上一级文件夹中 CMakeLists.txt 里的内容,并将产物输出到当前文件夹。因此,CMake 解析的文件一般都是名为 CMakeLists.txt 的文件,当然还有其他类型的文件,在后文会详细介绍。

最后,需要强调一点,CMake 并不是一个编译器,它只是一个编译工具,正如百度百科所说,CMake 不直接建构出最终的软件,CMake 主要作用就是能够,这一文件我们称之为,用于生成建构档的统一语法的文件,即 CMakeLists.txt 文件,我们称之为。

2. 为什么用 CMake

2.1 语法统一

不同的平台编译器、系统环境、可执行文件格式都不相同,生成可执行程序的方式也不尽相同,例如,对于同样的一个 main.cpp

  • 在 Ubuntu 上,一般会使用 gcc/g++ 编译器完成 C/C++ 文件的编译,执行
    g++ main.cpp -o demo
    
    最终生成一个二进制的可执行程序 demo
  • 在 Windows 上,得益于 Visual Studio 强大的 IDE,我们可以直接使用在该 IDE 上集成好编译器(MSVC)完成源文件的编译,一般点击 Visual Studio 的,可以在项目的文件夹下生成一个 .exe 文件,这就是在 Windows 上最终生成的二进制可执行程序

但使用 CMake 我们可以使用统一的语句生成建构档。

  • 在 Ubuntu 上,生成能够被 Unix makefile 解析的 Makefile 文件,这一文件可以指导 gcc/g++ 编译器完成构建(编译)工作,Makefile 文件就是建构档。
  • 在 Windows 上,生成能够被 Visual Studio 解析的 *.sln 解决方案文件,这一文件可以指导 MSVC 编译器完成构建(编译)工作,*.sln 文件就是建构档。

2.2 功能强大

迄今为止,CMake 已经发布了 3.28 系列的版本,后续的介绍均以 3.16 为最小版本。通过 CMake 可以在生成建构档之前实现

  • 第三方依赖库的下载、包含
  • 文件解析、生成
  • C/C++ 宏的生成

3. 怎么用 CMake

3.1 安装

首先安装 CMake,这里给出两种安装方式

3.1.1 软件源安装

这种安装方式最快,但版本比较受限,在较新的 Linux 发行版上版本会新一点。这里以 Ubuntu 为例,可使用 APT 包管理工具进行安装

sudo apt install cmake cmake-qt-gui cmake-curses-gui

来安装 CMake 工具,在

  • 18.04 下,对应的版本为 3.10
  • 20.04 下,对应的版本为 3.16
  • 22.04 下,对应的版本为 3.22

3.1.2 下载二进制包

可直接在 Github 中打开 CMake Release,找到你想下载的版本,点击对应的压缩包,例如在 x64 环境下的 Linux 可选择 cmake-x.xx.x-linux-x86_64.tar.gz,下载后进行解压,就得到了所有 CMake 工具。此外,可自行安装到系统路径下,以 cmake-3.29.0-linux-x86_64.tar.gz 为例,可使用以下命令

tar xf cmake-3.29.0-linux-x86_64.tar.gz # 解压
cd cmake-3.29.0-linux-x86_64
sudo cp -r * /usr/local                 # 安装至 /usr/local

3.2 CMake 生成建构档的步骤

然后我们再对上文通过main.cpp生成建构档的过程做个介绍,了解 CMake 生成建构档的基本步骤。

首先在main.cpp同级目录下创建CMakeLists.txt文件,这就是 CMake 生成建构档所参考(解析)的文件,并在其中写入

# 指定 CMake 的最小版本号,低于此版本的 CMake 将终止建构档的生成过程
cmake_minimum_required(VERSION 3.16)

# 创建项目
project(
  Demo          # 设置项目名
  LANGUAGES CXX # 指定语言,未指定的语言将不参与构建,例如 test.c 文件
)

# 创建可执行文件
add_executable(
  demo     # 目标名
  main.cpp # 用到的源文件
)

创建好后,在项目下创建build文件夹,在该文件夹下打开终端(Windows 下可以是 PowerShell),输入

cmake ..

即可在当前文件夹下生成对应的建构档。

以上就是利用 CMake 生成建构档的基本流程,这里需要注意在add_executable中我们涉及到了一个新的名词:目标(target),目标是 CMake 抽象出来的一个概念,可以简单的理解为具有

  • 名称
  • 包含的文件夹
  • 其余编译属性
  • 依赖的其他目标

的一个类,可以使用C++的类来描述目标这一概念

// CMake 目标
struct Target
{
    string name;                        // 名称
    vector<string> include_directories; // 包含的文件夹
    vector<string> properties;          // 其余编译属性
    vector<Target *> targets;           // 依赖的其他目标
};

通过上文可以得知,目标具有依赖关系,因此目标不仅只有可执行文件这一形式,还具有别的形式,在【05】目标构建会详细给出目标包含的内容。

总结

CMake 生成建构档的过程可以简单概括成

  1. 创建项目
  2. 目标构建
  3. 导出配置(如果有安装的需求,则需要做)

详细的内容会在后文介绍。

Next
【02】CMake 的文件分布