不知道怎么学 CMake ?这份精炼的学习路线拯救你!

一、为什么学习 CMake?

CMake、CTest、CPack和CDash已经成为源码构建的主要工具集,在使用和流行性方面超过了许多类似工具,例如备受推崇的GNU自动工具(Automake)和最新的基于Python的SCons构建系统。
在这里插入图片描述

上面的折线图展示 CMake、Automake 和 SCons 在 Google Trends 上的搜索热度随时间推移的演变。从图表可以看出:

  1. CMake 的搜索热度逐渐增加,且在过去几年中明显高于其他两个工具。这证实了它在现代 C++ 构建工具中的主导地位。
  2. Automake 的搜索热度显示出逐渐下降的趋势,体现出使用范围逐渐缩小的现实。
  3. SCons 的搜索热度相对较低,而且没有明显的增长或下降趋势,说明其使用人群相对稳定,但没有显著扩张。

在当今复杂多变的软件开发环境中,高效可靠的构建流程至关重要。CMake 及其配套工具 CTest、CPack 和 CDash,已经成为事实上的标准,它们组成了一套强大的生态系统,用于管理软件项目的整个生命周期,包括配置、构建、测试和部署。

相比于其他构建系统,例如曾经风靡一时的 GNU Autotools (如 Automake) 以及新兴的 Python 构建工具 SCons,CMake 系列工具在实用性和流行度上都占据了显著优势。这主要归功于 CMake 的特点:

  • 跨平台支持: CMake 的核心理念之一就是跨平台,它支持 Windows、macOS、Linux 以及其他众多操作系统,并能生成特定平台的原生构建系统(例如 Makefile、Visual Studio 项目文件、Xcode 项目文件等),从而大大降低了跨平台构建的复杂度。
  • 灵活的构建配置: CMake 提供了一种简洁、声明式的语言,用于定义项目的构建规则和依赖关系。可以轻松地配置构建过程,例如选择编译器、优化级别、库依赖,而无需深入了解底层构建系统的细节。
  • 模块化和可扩展性: CMake 鼓励模块化的项目组织方式,并提供了丰富的模块来支持常见的构建任务,如处理第三方库、生成文档等。此外,CMake 还支持自定义模块和命令,允许根据自己的需求进行扩展。
  • 集成测试: CTest 是 CMake 集成的测试工具,可以方便地执行各种测试,并生成详细的测试报告。这能够及早发现和修复缺陷,从而提高软件质量。
  • 打包和部署: CPack 创建可分发的软件包,例如安装包、二进制压缩包等,并支持多种打包格式。这简化了软件的发布和部署流程。
  • 持续集成: CDash 是一个基于 Web 的平台,用于收集和显示构建和测试结果,方便进行持续集成和质量监控。

CMake 项目始于 1999 年,其初衷是为了解决当时构建系统碎片化的问题。最初由 Kitware 公司开发,旨在为他们的开源项目提供一个通用的、跨平台的构建解决方案。随着时间的推移,CMake 逐渐发展成为一个功能强大、用途广泛的构建工具。

CMake 的核心目标可以概括为:提供一组工具,可以在不同平台上以一致的方式配置、构建、测试和部署项目。 换句话说,CMake 希望开发者专注于代码的逻辑,而不是纠结于不同平台构建系统的差异,从而提高软件开发的效率和质量。

二、如何学习 CMake?

学习CMake并非一蹴而就,而是一个循序渐进的过程。可以从了解CMake的基本概念开始,包括它的作用、核心组件以及基本命令。学习如何编写第一个CMakeLists.txt文件,并了解构建流程。解构模块化、依赖管理、条件编译等更复杂的知识。学习一些高级技巧,例如自定义命令、打包等。

CMake 学习路线
第一阶段:基础入门
第二阶段:中级进阶
第三阶段:高级技巧
学习方法建议
了解 CMake 的基本概念
安装 CMake
编写第一个 CMakeLists.txt
理解 CMake 变量和命令
掌握基本构建流程
模块化和代码组织
查找依赖项
条件编译和平台特定代码
生成器表达式和目标属性
单元测试
自定义命令和脚本
打包和安装
代码覆盖率分析
CMake 最佳实践
实践为王
由浅入深
多做笔记
坚持不懈
什么是 CMake
为什么需要 CMake
CMake 的核心组件
cmake_minimum_required
project
add_executable
cmake . (生成构建文件)
make 或 ninja (编译)
设置和使用 CMake 变量
常用 CMake 命令
配置 (configure)
构建 (build)
安装 (install)
构建目录和源目录
构建类型 (Debug, Release)
add_subdirectory
target_include_directories
target_link_libraries
创建和使用静态/动态库
find_package
FindModules
处理找不到依赖项的情况
pkg-config
if 语句和条件变量
平台检测变量 (CMAKE_SYSTEM_NAME, CMAKE_CXX_COMPILER_ID)
编写平台特定的代码
生成器表达式 $<...>
目标属性 (OUTPUT_NAME, VERSION, CXX_STANDARD)
add_custom_command
add_custom_target
CMake 脚本语言
CPack
打包格式 (ZIP, DEB, RPM)

本系列强调实践,通过实际项目来应用所学知识。本系列的 CMake 路线图:
在这里插入图片描述

第一阶段:基础入门

  1. 了解 CMake 的基本概念:什么是 CMake?为什么需要 CMake?以及如何下载安装 CMake。
  2. 编写第一个 CMakeLists.txt:学习如何使用 cmake 命令生成构建文件,学习如何使用生成的构建文件进行编译。
  3. 理解 CMake 变量和命令:学习如何设置和使用 CMake 变量,学习常用的 CMake 命令。
  4. 掌握基本构建流程:了解配置 (configure)、构建 (build) 和安装 (install) 的概念。了解 CMake 的构建目录和源目录的区别。理解构建类型(Debug, Release)。

第二阶段:中级进阶。

  1. 模块化和代码组织:学习如何使用 add_subdirectory 命令将项目分解为多个模块。学习如何管理模块之间的依赖关系。以及了解如何创建和使用静态/动态库。
  2. 查找依赖项:深入理解 find_package 命令,以及如何查找外部库。学习如何处理找不到依赖项的情况。了解 pkg-config 等工具。
  3. 条件编译和平台特定代码:学习如何使用 if 语句和条件变量来控制构建过程。了解 CMake 提供的平台检测变量。学习如何编写平台特定的代码。
  4. 生成器表达式和目标属性:了解并使用生成器表达式 $<...>,实现更灵活的构建配置。掌握常用的目标属性,例如 OUTPUT_NAMEVERSIONCXX_STANDARD
  5. 单元测试:学习如何使用 CTest 来进行单元测试。了解如何集成测试框架。

第三阶段:高级技巧。

  1. 自定义命令和脚本:学习如何使用 add_custom_commandadd_custom_target 添加自定义构建步骤。了解如何使用 CMake 脚本语言编写自定义逻辑。
  2. 打包和安装:学习如何使用 CPack 创建安装包。了解不同的打包格式 (例如 ZIP, DEB, RPM)。
  3. 了解如何集成代码覆盖率分析工具,并生成报告。了解一些 CMake 最佳实践。学习如何设计一个好的 CMake 项目结构。
  4. CMake 在不断发展,保持学习的心态,关注随时了解 CMake 的新特性。

三、预备知识

学习 CMake 虽然是从头开始,但也不能完全是“小白”!

虽然我们说学习 CMake 是从零开始,但它也不是完全不需要任何基础的。如果你想学得轻松、学得明白,最好还是先熟悉一些开发圈里的“基本操作”,这样学习起来会更顺畅。最好具备下面这些技能:

  • 对命令行操作要有点感觉: 需要知道如何在终端或者命令提示符里输入命令,比如切换目录、执行文件等。这是开发过程中经常要用到的,也是 CMake 工作的基础。如果你对命令行很陌生,建议先花点时间熟悉一下。
  • 对开发环境不陌生: 要知道开发软件(比如IDE、文本编辑器)长什么样,怎么用。毕竟你最终是要用 CMake 来构建你的软件,得先知道软件开发流程是怎样的,对吧?
  • 至少熟悉一门编程语言: 你得对 C++、C 或者 Fortran 这类编程语言比较熟悉。而且,你知道你用的是哪个编译器(比如 GCC、Clang、MSVC)编译的。这样你才能更好地理解 CMake 是怎么帮你把代码变成可执行程序的。
  • 对 Python 有点了解: 虽然 CMake 主要不是用 Python 写的,但是它有时候需要用到 Python 来做一些辅助操作,比如处理一些构建脚本。如果你了解 Python,会更容易理解 CMake 的一些高级用法。当然,不会也不要紧,但是了解一下肯定没坏处。

特别是命令行,建议熟悉以下常用命令:

  • cd <目录路径>:切换目录。例如:cd my_project 进入 my_project 目录, cd .. 返回上一级目录。

  • pwd(Linux/macOS)或 echo %cd%(Windows):显示当前工作目录的路径。

  • ls(Linux/macOS)或 dir(Windows):列出当前目录下的文件和子目录。

  • mkdir <目录名>:创建新目录。例如:mkdir build 创建一个名为 build 的目录。

  • rm <文件名>(Linux/macOS)或 del <文件名>(Windows):删除文件。

  • rm -rf <目录名>(Linux/macOS): 强制删除目录及其内容。(注意:使用此命令时要小心

  • cp <源文件> <目标文件>:复制文件。

  • mv <源文件> <目标文件>: 移动文件,也可以用于重命名文件。

  • touch <文件名>(Linux/macOS):创建空文件。

  • type <文件名>(Windows) 或 cat <文件名>(Linux/macOS):显示文件内容。

  • ./<可执行文件名>(Linux/macOS)或 <可执行文件名>.exe(Windows):执行当前目录下的可执行文件。

  • makeninja:使用构建工具编译代码 (CMake 生成构建文件后使用)。

  • echo <字符串>: 将字符串输出到终端。

  • clear(Linux/macOS)或 cls(Windows):清空终端屏幕。

  • git --version:查看 Git 版本号 (如果使用 Git)。

  • <命令> --help: 查看命令帮助文档。

简单来说,如果你已经掌握了一些编程的基本技能,并且对软件开发流程有一定了解,那学习 CMake 就会轻松很多。 如果你对这些还比较陌生,也不要害怕,可以先补充一些相关的知识,再来挑战 CMake 也会事半功倍!

四、CMake的工作时序

在CMake管理的项目中,工作流可以被理解为一个由多个阶段组成的过程链,每个阶段都有其特定的功能和目的。
在这里插入图片描述

  • 配置阶段(CMake time或confighure time):在这一阶段,CMake 解析和处理项目根目录以及所有子目录下的 CMakeLists.txt 文件。这里,CMake 收集所有构建指令和依赖关系,生成一个内部的构建模型。
  • 生成阶段(Generation time):配置完成后,CMake 利用收集到的信息生成适合特定构建工具(如Make、Ninja、Visual Studio等)的构建脚本或项目文件。此阶段的输出是特定于平台的构建文件。
  • 编译阶段(Build time):使用生成的构建脚本或项目文件,调用本地编译器进行代码编译。所有的源代码被编译成库和可执行文件。注意,在这个过程中,可能会有子项目的CMake文件再次被调用(递归配置),以确保依赖正确处理。
  • 测试阶段(CTest time或 test time):一旦构建完成,CTest工具被用于执行项目的测试脚本,验证生成的可执行文件和库是否正常工作。
  • 报告阶段(CDash time或report time):测试结果通过CDash上传到一个中央仪表板,供开发团队查看和分析,以便跟踪项目的质量和进度。
  • 安装阶段(Install time):项目构建完成后,CMake提供的cmake --install命令用于将编译好的文件(如可执行文件、库、配置文件等)从构建目录复制到指定的安装目录。
  • 打包阶段(CPack time或packaging time):CPack工具在此阶段被用于将项目打包成各种格式的安装包,比如DEB、RPM、NSIS、ZIP等,以便于项目发布和分发。
  • 包安装阶段(Package install time):一旦包被创建,用户可以将其安装到他们的系统中。此阶段涉及系统范围的文件安装和配置。

每个阶段都依赖于前一阶段的成功完成,但也允许一定程度的灵活性。

五、总结

CMake 作为现代构建工具,核心价值在于跨平台、灵活配置和高效管理。它统一了不同平台的构建流程,简化了复杂的依赖关系,并提供了强大的测试、打包和部署能力。学习 CMake 能够提升开发效率、确保软件质量并简化发布流程。从基础概念入手,逐步掌握高级技巧,并结合实践不断探索,你就能充分利用 CMake 的优势。

参考:

  1. 【cmake社区帮助文档】(https://cmake.org/cmake/help/latest/)
  2. 【CMake Tutorial (官方)】(https://cmake.org/cmake/help/latest/guide/tutorial/index.html)
  3. 《CMake Cookbook》- Radovan Bast & Roberto Di Remigio
  4. 《精通CMake》- Ken Martin & Bill Hoffman

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lion 莱恩呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值