前言:
学习笔记,随时更新。如有谬误,欢迎指正。
说明:
- 红色字体为较为重要部分。
- 绿色字体为个人理解部分。
1 为什么 CMake ?
如果你曾经维护过软件的构建和安装过程,你将会对 CMake 感兴趣。 CMake 是一个开源的软件项目构建管理器。它允许开发者以简单且可移植的文本文件格式指定构建参数。这个文件将会被 CMake 使用来为本地构建工具生成项目文件。这些构建工具包括 IDE ,如 Macrosoft Visual Studio 或者 Apple XCode ,以及 Unix 、 Linux 、 NMake 和 Borland 风格的 MakeFile 。 CMake 处理了软件项目构建中较为麻烦的部分,例如跨平台构建、系统自检和用户自定义构建,以简单的方式让用户在复杂的硬件和操作系统中非常容易地来定制项目的构建 。
任何项目,特别是跨平台项目,都需要统一的构建系统。当今很多项目都附带 Unix Makefile(或者 Makefile.in )和 Macrosoft Visual Studio 两个工作空间。这要求开发者不断地更新两种构建系统并且保持两者的一致性。为了面向额外的构建系统,如 Borland 或者 XCode ,需要更多的这些文件的副本,这样会造成更大的问题。如果你试图支持可选组件这会使问题加剧,例如在系统中 libjpeg 库可用的情况下支持 JPGE 。 CMake 通过将这些不同的操作合并为一个易于理解的文件格式来解决这个问题。
如果一个项目中有很多开发者或者有很多目标平台,那么软件必然会在多台电脑上构建。由于一台现代计算机在配置时软件安装和选项定制的范围之广,两台运行相同操作系统的计算机也有可能会略有不同(是指电脑的软硬件环境配置)。 CMake 在单平台、多机器开发环境的这种情况下有很大优势,包括:
- 自动寻找软件构建时所需的程序、库和头文件的能力。这包括在搜索时考虑环境变量和 Windows 注册表的能力。
- 在源码目录之外的目录构建工程的能力。这在许多 Unix 平台上是一个很有用的特性。 CMake 在 Windows 平台上也同样提供这个特性。这让开发者在移除整个构建目录时不用害怕是否会移除了源码。
- 为自动生成文件而创建复杂自定义命令的能力。例如 Qt 的 moc() 或 SWIG 包装生成器。
- 在配置时期选择可选组件的能力。例如有几个 VTK 的库是可选择的, CMake 为用户提供了非常简单的方式来选择需要构建的库。
- 通过简单文本文件来自动生成工作空间和项目的能力。这对那些有很多程序和测试用例的系统是非常有用的,这些程序和测试用例每一个都需要一个独立的工程文件,使用IDE来创建这些工程文件会是一个很繁琐的手动过程。
- 非常简单的在静态(库)和共享(库)的构建之间进行切换的能力。 CMake 知道如何在所有所支持的平台上创建共享库和模块。它处理了复杂的特定于平台的链接器标志,并且在许多 Unix 系统上支持一些高级特性,比如共享库的内置运行时搜索路径等。
- 自动生成文件依赖,并且在大部分平台上支持并行构建。
在开发跨平台软件时,CMake提供了许多额外的特性:
- 测试机器字节序和其他的硬件具体特性的能力。
- 一组可以在所有平台工作的构建配置文件。这就避免了在一个项目中开发者需要维护几种不同格式的相同信息。
- 在所有支持( CMake )的平台上支持构建共享库。
- 使用系统相关信息配置文件的能力,例如数据文件和其他信息的位置。CMake可以创建头文件,头文件中以 #define 宏的形式定义一些信息,例如数据文件和其他信息的路径。系统的特性标志也可以放在配置的头文件中。这比编译器命令行的 -D 选项更有优势,因为这允许其他构建系统使用 CMake 构建的库,而不需要指定额外的与构建时相同的命令行选项。
1.1 CMake 的历史
自1999年以来,CMake一直处于积极的开发状态,并且已经成熟到可以解决各种构建问题的地步。CMake最早是美国所资助的 Insight Toolkit (ITK) 的项目一部分。 ITK 是一个非常大的软件项目,它可以在许多平台上工作,并且可以与很多其他的软件包进行交互。为了支持这些,需要一个更强大且容易使用的构建工具。在过去与大型项目的构建系统的工作中,开发者设计了 CMake 来满足这些需求。从那以后, CMake 就越来越受欢迎,很多项目和开发者由于它的易于使用以及灵活性而采用它。最生动的一个例子就是 K Desktop Environment(KDE) 对 CMake 的成功采用, KDE 可以说是现存的最大的开源软件项目。
CMake 还以 CTest 的形式支持软件测试。软件测试过程包括构建软件、可能有安装软件,并确定软件的哪一部分适合当前系统。这使得 CTest 成为了 CMake 的一个逻辑扩展,因为它本来就含有绝大部分这些相关信息。类似的, CMake 还有 CPack ,它被设计用来支持跨平台的软件发布。它通过使用现存的受欢迎的软件包,如 WiX 、 PRM 、 Cygwin 和 PackageMaker ,来提供跨平台的方法来创建软件的本机安装。
CMake会继续跟踪和支持可用且流行的构建工具。 CMake 很快就为微软的 Visual Studio 和苹果的 Xcode IDE 的新版本提供了支持。此外, CMake 还增加了对 Google 新构建工具 Ninja 的支持。当使用 CMake 的时候,只要你编写输入文件,你将会免费得到新的编译器和构建系统的支持,因为对他们(新编译器和构建系统)的支持已经被内置在了 CMake 新的发行版中,而与你的软件发行无关。 CMake 还支持交叉编译到其他操作系统或嵌入式设备。在交叉编译时, CMake 中的大多数命令都能正确处理主机系统和目标平台之间的差异。
1.1.1 为什么不用 AutoConf ?
在开发 CMake 之前,它的作者对使用现存的可用工具集很有经验。融合了 Automake 的 Autoconf 提供了一些与 CMake 相似的功能,但是在 Windows 平台上使用这些工具需要安装很多无法直接在 Windows 工具盒里找到的额外的工具。除了需要大量的工具之外, Autoconf 还很难用或且很难扩展,并且几乎不可能完成一些在 CMake 中很容易的任务。就算你确实设置好了 Autoconf 和它在你的操作系统上运行所需要的环境,它会生成 Makefile ,这会强制用户使用命令行。 CMake 另一方面也提供了一个选择,允许用户生成工程文件,这些工程文件能在 Windows 和 XCode 开发者所熟悉的IDE中直接使用。
虽然 Autoconf 支持用户指定一些选项,但是它不支持一个选项依赖于一些其他选项或其他选择这种选项依赖。例如,在 CMake 中有一个启用多线程的选项,此选项首先依赖于用户操作系统是否支持多线程。 CMake 提供一个交互式的用户界面,使得用户能够很多容易的看见哪些选项是可用的并且如何设置它们。
对 Unix 用户来说, CMake 也提供了自动的依赖生成,这是 Autoconf 没有直接提供的。 CMake 简单的输入格式也比一个 Makefile.in 和 configure.in 的混合文件要更容易阅读和维护。 CMake 记住并且链接库依赖项信息的能力在 Autoconf/Automake 中是没有的。
1.1.2 为什么不用 JAM 、 qmake 、 SCons ,或者 ANT ?
其他工具如 JAM 、 qmake 、 SCons ,或者 ANT 都有不同的方式来解决这些问题,它们已经帮我们塑造了 CMake 。 qmake 尽管缺失了不少 CMake 提供的系统查询,但是四者中它是最像 CMake 的。 qmake 的输入格式更接近于传统的 Makefile 。 ANT 、 JAM 和 SCons 尽管不支持生成原生的工程文件,但是它们都是跨平台的。它们确实打破了传统的面向 Makefile 的输入形式: ANT 使用 XML , JAM 使用它自己的语言, SCons 使用 Python 。许多工具直接运行编译器,而不是让系统的构建程序来执行此任务。许多工具在使用之前要求其他工具,如先安装 Python 或者 Java 。
1.1.3 为什么不自己编写脚本 ?
许多项目使用已存在的脚本语言如 Prel 或者 Python 来配置构建过程。尽管使用像这样的系统能实现相似的功能,但是过度使用这些工具比起简单易用的构建系统来说,会让构建过程变得更像寻找复活节彩蛋(意思是一环套一环,每个工具都要安装配置好)。在构建软件包的时候,在他们能开始构建过程之前,用户必须去查找并且安装 4.3.2 的这个、3.2.4的那个(指各种版本的各种工具)。为了避免这些问题, CMake 决定不使用比用来构建(程序)的软件所使用(的工具)更多的工具。最小(规模)的 CMake 的使用只需要 C 编译器、编译器的原生构建工具以及 CMake 的可执行文件。 CMake 是用 C++ 编写的,只需要一个 C++ 编译器来构建,预编译的二进制文件从大多数系统获得。自己编写脚本通常意味着你将不会生成原生的 XCode 或者 Visual Studio 工作空间,这样会使得 Mac 和 Windows 的构建工作受限。
1.1.4 CMake 能在哪些平台上运行 ?
CMake 能在各种各样的平台上工作,包括 Macrosodt Windows 、 Apple Mac OS X 以及大部分 Uinx 或者 Unix-like 平台。同样的, CMake 支持大部分常规编译器。
1.1.5 CMake 有多稳定 ?
在为项目采用任何新技术或工具之前,开发人员希望了解该工具的支持程度和受欢迎程度。自最初的 CMake 实现以来, CMake 作为一种构建工具越来越受欢迎。开发人员和用户社区都在持续增长。当有可用的新构建技术和工具时, CMake 会继续开发对它们的支持。 CMake 开发团队对向后兼容性有着坚定的承诺。如果 CMake 可以构建你的项目一次,它应该总是能够构建你的项目。此外,由于 CMake 是一个开源项目,如果需要,源代码随时可用于项目编辑和修补。