【001】CMake 第一课:什么是 CMake,为什么你需要它?

一、前言

软件开发的世界里,代码只是第一步。如何将这些代码转换成可执行的程序,就需要构建工具的帮助。今天,我们要一起认识一个非常重要的工具 —— CMake。

前面的一篇【不知道怎么学 CMake ?这份精炼的学习路线拯救你!】文章详细介绍了CMake的学习路线图。说明了如何从基础概念入手,逐步掌握高级技巧,并结合实践不断探索。你可能会疑惑,什么是 CMake?为什么我们要学习它? 简单来说,CMake 就像是一位优秀的“项目经理”,它负责管理你的项目构建过程,让你的代码能够顺利地在各种不同的环境中编译和运行。

这篇文章开始 CMake 的第一课:什么是 CMake?为什么需要 CMake?以及如何下载安装 CMake?

在这里插入图片描述

CMake 已经成为现代软件开发中不可或缺的一部分,特别是在 C++、C 等需要编译型语言的开发中,掌握 CMake 可以说是你进阶的必经之路。如果你正在学习或者使用 C++ 开发,那么本系列教程更是为你量身定做的,因为现代 C++ 项目几乎都离不开 CMake。

二、什么是 CMake?

CMake 的定义:CMake(Cross-platform Make)是一个开源的、跨平台的构建系统生成工具。可以理解为一位建筑师要建造一栋房子,不会直接拿起砖头开始堆砌,而是会先画出设计图纸,明确房子的结构和使用的材料;CMake 就类似于这个设计图纸,只不过它是为软件项目服务的。

CMake 不是一个编译器,也不是一个直接执行构建的工具。 你可以把它看作是一个“构建系统生成器”。即 CMake 的主要任务是读取项目描述(一个名为 CMakeLists.txt 的文件),然后根据描述生成特定平台所需要的构建系统文件。比如在 Linux/macOS 上的 Makefile 文件。

所以,CMake 本身不负责编译你的代码。 它就像一个“翻译器”,将项目描述翻译成不同平台能够理解的“语言”,然后让这些平台上的构建工具(比如 make、Visual Studio 等)真正执行编译、链接等操作。

更重要的是,CMake 是跨平台的! 所以,无论是在 Windows、macOS、Linux 还是其他平台上开发,只需要编写一份 CMakeLists.txt 文件,CMake 就可以生成适用于各种平台的构建系统,从而避免了为每个平台编写不同构建脚本的麻烦。

已经了解了 CMake 是什么,接下来看看它是如何工作的
在这里插入图片描述

CMake 的工作流程可以简化为以下几个步骤:

  1. 读取 CMakeLists.txt 文件。

  2. 根据 CMakeLists.txt 文件中的描述,分析项目结构和依赖关系。在这个阶段,CMake 会检测系统环境、编译器信息以及其他必要的配置。会生成一个内部的“项目模型”,这个模型包含了项目的所有必要信息。

  3. CMake 根据之前生成的“项目模型”,选择合适的构建系统生成器(比如 Makefile 生成器,或者 Visual Studio 项目文件生成器),将项目模型转换为特定平台的构建系统文件。

  4. 使用对应的构建工具(例如 make、Visual Studio)来实际编译代码。构建工具会读取 CMake 生成的文件,执行编译、链接等操作,最终生成可执行程序或库。

除了 CMake, 还存在着许多不同的构建工具,都致力于解决同一个问题:如何将源代码转化为可执行程序或库。比如 makeAutomakeSCons 等。

  • make 一个非常基础的构建工具,它读取 Makefile 文件来执行构建操作。虽然 make 很强大,但编写 Makefile 文件需要一定的经验和技巧,而且不同的平台要不同的 Makefile 文件。make 的缺点在于可移植性较差,对于大型项目,维护 Makefile 文件会变得非常复杂。

  • Automake 旨在简化 Makefile 的编写,但它需要与 Autoconf 配合使用。Autoconf 会检测系统环境,并生成适合当前平台的 Makefile 文件。AutomakeAutoconf 比较复杂,学习曲线较陡峭,而且生成的文件往往也比较庞大。

  • SCons 一个使用 Python 编写的构建工具,它可以自动检测依赖关系,并且相对容易配置。问题在于它需要安装 Python 环境,对于一些简单的项目来说,显得有些重型。

CMake 的优势:

  1. CMake 的重点是“生成构建系统”而不是执行构建。它读取 CMakeLists.txt 文件,然后生成适用于不同平台的构建系统文件(例如 Makefile、Visual Studio 项目文件等)。因此,只需维护一个 CMakeLists.txt 文件,而无需关心不同平台的构建细节。这与 makeAutomake 的手动编写构建文件的方式有着根本的区别。

  2. CMake 的跨平台能力非常强大。它可以在各种不同的操作系统(如 Linux、macOS、Windows)和编译器之间工作,只需一份 CMakeLists.txt 文件,就可以生成适用于不同平台的构建系统,而不需要修改构建脚本。这使得代码的移植和部署变得更加简单和高效。

  3. 相比 Automake 复杂的配置和 make 的手动编写,CMake 的 CMakeLists.txt 文件更加简洁和易于理解,学习曲线相对平缓,更容易上手。

  4. CMake 提供了丰富的模块和功能,可以方便地管理依赖关系、测试框架、代码生成等任务。

许多初学者在接触 CMake 时,可能会有一些常见的误解。这里再次强调一下(虽然啰嗦了很多遍,但还是要再澄清一下):

  1. CMake 不是编译器: CMake 本身不负责编译你的源代码。它只是一个构建系统生成器,它的作用是生成构建文件(如 Makefile),然后由真正的编译器(如 gccclang、Visual Studio 编译器等)来执行编译操作。

  2. CMake 不会直接编译代码: 如上所述,CMake 只负责生成构建系统,实际的编译工作是由构建工具(如 make、Visual Studio)和编译器完成的。

  3. CMake 不是一个一体化的构建工具: CMake 的目标不是替代构建工具,而是更好地利用它们。它通过生成不同平台的构建文件,使得开发者可以在统一的环境下使用不同的构建工具。

  4. CMakeLists.txt 文件不是脚本: CMakeLists.txt 文件描述的是项目的构建信息,它使用自己的语法,不是 shell 脚本或者其他编程语言的脚本。

三、为什么需要 CMake?

在软件开发过程中,经常会遇到一个棘手的问题:如何保证我们的代码可以在不同的操作系统、不同的编译器下都能正常构建? 这正是 CMake 发挥作用的地方。

一个跨平台的项目,需要在 Linux、macOS 和 Windows 等多个操作系统上运行。如果使用传统的构建方式,要为每个平台编写不同的构建脚本:

  • Linux: 要编写 Makefile 文件,使用 gccclang 编译器。
  • macOS: 要一个 Makefile 文件,使用 clang 编译器。
  • Windows: 要创建 Visual Studio 项目文件,使用 Visual Studio 编译器。

这是非常繁琐且容易出错的。不仅需要花费大量时间编写和维护这些构建脚本,还需要熟悉不同平台的构建方式和工具链。而且,即使编写了这些脚本,它们仍然可能存在一些细微的差异,导致在某些平台上构建失败。

更糟糕的是,如果项目依赖于第三方库,还要考虑如何在不同平台上正确地链接这些库。这更加复杂化了。

而 CMake 恰好是为了解决这些问题而生的:

  1. 只需要编写一个 CMakeLists.txt 文件,其中描述了项目的结构、依赖关系以及编译选项。这个文件是平台无关的,可以在所有支持 CMake 的平台上使用。

  2. CMake 会读取 CMakeLists.txt 文件,然后根据当前所在的操作系统和编译器,自动生成相应的构建系统文件,如 Makefile (Linux/macOS) 或 Visual Studio 项目文件 (Windows)。

  3. CMake 确保在不同平台上生成的构建文件具有一致的结构和行为,从而大大减少了构建过程中的错误。

  4. CMake 提供了强大的依赖管理功能,可以轻松地找到并链接第三方库,无论它们在哪个平台上。在大型项目中,降低了管理依赖库的复杂性。

使用 CMake 后,不再需要手动编写和维护不同平台的构建脚本。可以专注于编写代码,而不用过多地操心构建细节。CMake 会自动处理这些繁琐的任务。

CMake 不仅解决跨平台构建的难题,还是一个强大的项目管理工具。 大型软件项目通常会依赖于许多第三方库、模块或子项目。CMake 通过一系列强大的功能来简化依赖管理:

  1. find_package 命令: find_package 命令是 CMake 中最核心的依赖管理工具。它可以自动查找第三方库,并设置相应的编译和链接选项。

  2. 模块化管理: CMake 可以轻松地管理复杂的项目结构,包括子模块和子项目。 add_subdirectory 命令将子项目包含到主项目中,并使用 target_link_libraries 命令将不同模块链接在一起。

  3. CMake 提供了许多预定义的模块,用于查找和集成常见的第三方库,如 OpenSSLZLIBQt 等。

  4. CMake 还提供 FetchContent 模块,用于直接从 URL 下载并构建依赖,简化了第三方库的集成流程。

一个工具的强大程度不仅取决于其功能,还取决于其背后的社区支持和应用范围。CMake 在这两方面都表现出色:

  1. CMake 拥有一个庞大而活跃的社区,提供丰富的官方文档、教程、示例代码。
  2. CMake 被广泛应用于各种类型的项目中,许多著名的开源项目都采用 CMake 作为其构建系统,如 LLVM、Qt、OpenCV、Boost 等。

四、下载安装 CMake

4.1、Linux 安装 CMake

大多数 Linux 发行版都提供了 CMake 的包管理器。可以使用以下命令安装 CMake:

# Debian/Ubuntu:
sudo apt update && sudo apt install cmake
# 或者 升级 CMake
sudo apt upgrade cmake  

# Fedora:
sudo dnf install cmake
# 或者 升级 CMake
sudo dnf update cmake

# CentOS/RHEL:
sudo yum install cmake
# 或者 升级 CMake
sudo yum update cmake

# Arch Linux:
sudo pacman -S cmake
# 或者 升级 CMake
sudo pacman -Syu cmake

但是,在一些发行版中,CMake 版本可能比较旧,因此下载由Kitware提供的二进制文件就变成了首选,CMake 官网下载页面 https://cmake.org/download/。下面提供一个X86 64 bit系统自动下载对应CMake版本的shell脚本:

cmake_version="3.22.1"
target_path=$HOME/workspace/cmake/${cmake_version}
cmake_url="https://cmake.org/files/v${cmake_version%.*}/cmake-${cmake_version}-Linux-x86_64.tar.gz"
mkdir -p "${target_path}"
curl -Ls "${cmake_url}" | tar -xz -C "${target_path}" --strip-components=1
export PATH=$HOME/workspace/cmake/${cmake_version}/bin${PATH:+:$PATH}
cmake --version

如果你的 Linux 发行版也支持通过 snapFlatpak 安装 CMake。可以使用 sudo snap install cmake --classic命令安装CMake。

4.2、Windows 安装 CMake

访问 CMake 官网下载页面,在下载页面,会看到不同平台的安装包,下载 Windows Installer 版本(一个 .msi 文件)。选择与Windows 系统架构 (32 位 或 64 位) 相匹配的版本。推荐下载最新版本的 CMake,以确保拥有最新的特性和修复的 bug。
在这里插入图片描述

下载完成后,双击 .msi 文件运行安装程序。安装过程比较简单,按照安装程序的提示一直进行“next”操作即可。在安装过程中,安装程序询问是否将 CMake 添加到系统环境变量中。虽然是可选项,但是强烈建议勾选此选项。 如果没有勾选此选项,后面就要手动将 CMake 的安装路径添加到系统的 Path 环境变量中。添加系统环境变量后,就可以在命令行 (CMD 或 PowerShell) 中直接使用 cmake 命令。

在命令提示符 (CMD) 或 PowerShell 输入 cmake --version 并按下回车验证安装是否成功, 如果 CMake 安装成功,会看到 CMake 的版本信息。

除了前面说的直接下载安装包,Windows 上安装 CMake 还有一些更“高级”的玩法。

Visual Studio “自带”的 CMake: 如果用的是 Visual Studio 2017 或者更新的版本,那就方便了!Visual Studio 已经内置了对 CMake 的支持,都不需要单独安装 CMake 了,在安装Visual Studio 2017时 组件中勾选"用于Windows的c++ CMake工具"。

MSYS2,一个“伪 Linux” 的开发环境: MSYS2 就是一个在 Windows 上模拟 Linux 环境的工具,有类似 Linux 终端的命令行界面,还有强大的包管理器 pacman。可以去 https://www.msys2.org 下载 MSYS2 的安装程序,然后按照官网的说明进行安装。然后使用包管理器pacman安装 CMake。

安装 64位版本:

$ pacman -S mingw64/mingw-w64-x86_64-cmake

安装 32位版本:

$ pacman -S mingw64/mingw-w64-i686-cmake

4.3、macOS 安装 CMake

同样的,先访问 CMake 官网下载页面。在下载页面,选择 macOS 对应的 .dmg 文件。下载完成后,双击 .dmg 文件,然后将 CMake.app 拖放到 Applications 文件夹中。这就完成了 CMake 的安装。

或者直接获取最新的CMake版本:

$ brew upgrade cmake

为了能够在终端中使用 cmake 命令,需要创建一个软链接。

sudo "/Applications/CMake.app/Contents/bin/cmake" --install-prefix=/usr/local

或者 创建一个软链接到 /usr/local/bin:

    sudo ln -s /Applications/CMake.app/Contents/bin/cmake /usr/local/bin/cmake
    sudo ln -s /Applications/CMake.app/Contents/bin/cpack /usr/local/bin/cpack
    sudo ln -s /Applications/CMake.app/Contents/bin/ctest /usr/local/bin/ctest

五、编译器

在 GNU/Linux 环境下,GNU 编译器集合 (GCC) 无疑是最为普遍和直接的选择。它不仅是自由开源软件,而且被几乎所有的 Linux 发行版所原生支持。GCC 包含了 C、C++、Fortran 等多种编程语言的编译器,可以满足绝大多数开发需求。

安装 GCC (以 Ubuntu 为例):

sudo apt-get update   # 更新软件包列表 (强烈推荐)
sudo apt-get install g++ gcc

除了 GCC 之外,LLVM 项目下的 Clang 也是一个非常优秀的 C/C++ 编译器。 Clang 旨在提供更高的编译速度和更好的错误诊断信息。

sudo apt-get install clang clang++

在 macOS 上,苹果公司提供的 Xcode 开发工具包中已经包含了 LLVM 编译器套件。这个套件包含了 C 和 C++ 编译器(Clang,它与 Linux 系统上的 Clang 相同),可以直接用于 C 和 C++ 项目的编译。无需单独安装 LLVM 编译器。

在 Windows 上,通常有两种主要的编译器选择:

  • Visual Studio: 微软的 Visual Studio 提供了完善的开发环境,包括 C 和 C++ 编译器。Visual Studio 是商业软件,但社区版是免费的。

  • MSYS2/MinGW-w64: MSYS2 是一个为 Windows 提供类 Unix 环境的软件发行版。它包含了一个软件包管理器 pacman,可以用于安装各种工具链,包括 GCC 和 Clang。MinGW-w64 是 MSYS2 提供的一个 GCC 编译套件,它为 Windows 提供了原生编译环境。

“交叉编译” 是一种重要的技术。它指的是在一个平台上(例如你的开发机)编译代码,然后在另一个不同的平台上(例如嵌入式设备、其他操作系统)运行。 为了实现这一点,需要使用专门的“交叉编译器”,而非普通的编译器。

对于类 Debian/Ubuntu 系统,使用 apt 包管理器来安装交叉编译器。

sudo apt-get update  # 强烈建议先更新软件包列表
sudo apt-get install gcc-mingw-w64 g++-mingw-w64

安装了交叉编译器,就可以在 Linux 系统上编译出可在 Windows 上运行的可执行文件(例如 .exe 文件)。

在 macOS 上,使用 Homebrew 包管理器来安装针对 Windows 平台的交叉编译工具链:

brew install mingw-w64

除了使用包管理器直接安装交叉编译器外,另一种方法是使用 MXE (M Cross Environment),MXE 的官方网站 (https://mxe.cc) 。

六、总结

CMake 作为一款强大的构建工具,在 C/C++ 开发中扮演着重要的角色。它解决了跨平台构建的难题,提供了强大的功能和灵活性,但也存在一定的学习曲线和配置复杂性。如果你正在进行 C/C++ 项目的开发,尤其是跨平台项目,那么掌握 CMake 绝对是一项值得投资的技能。

在下一篇文章中,我们将开始学习如何编写第一个 CMakeLists.txt 文件,并使用 CMake 来构建项目。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lion 莱恩呀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值