为何选择 CMake?¶
如果你曾经维护软件包的构建与安装流程,那么你肯定对 CMake 感兴趣。CMake 是一个面向软件项目的开源构建系统生成器,开发人员可使用简单、可移植的文本文件格式来指定构建参数。之后,CMake 会使用该文件来生成面向本地构建工具(包括 Microsoft Visual Studio 或 Apple 的 Xcode 等集成开发环境 (IDE))的项目文件,以及 UNIX、Linux、NMake 和 Ninja。CMake 以简洁的方式处理软件构建的难点,如跨平台构建、系统自省和用户自定义构建,这使用户能够轻松地为复杂的硬件和软件系统定制构建。
对于任何项目(特别是跨平台项目),都需要一个统一的构建系统。许多基于非 CMake 的项目都随附 UNIX Makefile(或 Makefile.in)以及 Microsoft Visual Studio 工作区。这样一来,开发人员就需要不断地使这两个构建系统保持最新并彼此一致。如果要定位其他构建系统(如 Xcode),则需要创建这些文件的更多自定义副本,从而造成更大的问题。如果你尝试支持可选组件(例如,在系统上包含 JPEG 支持时包括 libjpeg),则这个问题会更加复杂。CMake 通过将这些不同的操作合并到一个简单、易于理解的文件格式中来解决这个问题。
如果你有多个开发人员从事一个项目或多个目标平台,那么软件就必须在多台计算机上构建。考虑到构建现代计算机涉及的广泛已安装软件和自定义选项,运行相同操作系统的两台计算机略有不同的可能性很高。CMake 为单平台、多机器开发环境提供了许多 优势,包括
能够自动搜索软件构建可能需要的程序、库和头文件。在搜索时,这包括考虑环境变量和 Windows 注册表设置。
能够在源代码树外部的目录树中构建。这是许多 UNIX 平台上的一个有用功能;CMake 也在 Windows 中提供了此功能。这允许开发者删除整个构建目录,而不必担心删除源文件。
能够为自动生成的文件(如 Qt 的 moc() 或 SWIG 包裹器生成器)创建复杂、自定义的命令。这些命令用于在构建过程中生成新源文件,而后者则编译到软件中。
能够在配置时选择可选组件。例如,VTK 的一些库是可选的,而且 CMake 为用户提供了一种简单的方法来选择要构建的库。
能够根据一个简单的文本文件自动生成工作区和项目。这对于拥有众多程序或测试用例且每个用例都需要一个单独项目文件的系统而言非常方便(通常,使用 IDE 创建是一个繁琐的手动过程)。
能够轻松地在静态和共享构建之间切换。CMake 了解如何在受支持的所有平台上创建共享库和模块。复杂的平台特定链接标志得到处理,并且许多 UNIX 系统上都支持共享库的内置运行时搜索路径等高级功能。
在大多数平台上自动生成文件依赖项并支持并行构建。
在开发跨平台软件时,CMake 提供了许多附加功能
能够测试机器字节顺序和其他特定硬件特征。
一套适用于所有平台的构建配置文件,这样,开发人员就可以不用在项目中以不同的格式维护相同的信息。
支持在支持所有平台上构建共享库。
可以使用系统相关的信息配置文件,例如数据文件的位置和其他信息。CMake 可以创建包含信息的标头文件,例如数据文件的路径和其他信息,形式为
#define
宏。系统特定标志也可以放在已配置的标头文件中。这比命令行-D
编译器选项有优势,因为它允许其他构建系统使用 CMake 构建库,而不必指定在构建期间使用的完全相同的命令行选项。
CMake 的历史¶
自 1999 年以来,CMake 一直处于活跃开发阶段,并已发展成熟,成为解决各种构建问题的成熟解决方案。CMake 开发最初是 Insight Toolkit (ITK) 的一部分,该项目由美国国家医学图书馆提供资金支持。ITK 是一个大型软件项目,可在许多平台上运行,并且可以与许多其他软件包进行交互。为了支持这一点,需要一个功能强大且易于使用的构建工具。开发人员曾经使用过大型项目的构建系统,因此设计了 CMake 来满足这些需求。从那时起,CMake 的受欢迎度不断提高,许多项目和开发人员因其易用性和灵活性而采用它。最明显的例子是 CMake 被成功采用为 K Desktop Environment (KDE) 的构建系统,KDE 可能是现存最大的开源软件项目。
CMake 还以 CTest 的形式包含软件测试支持。测试软件的过程的一部分涉及构建软件、可能安装软件并确定哪些部分的软件适用于当前系统。这使得 CTest 成为 CMake 的一个合乎逻辑的扩展,因为它已经拥有这些信息。类似地,CMake 包含 CPack,旨在支持跨平台软件分发。它提供了一种跨平台方法来为您的软件创建本地安装,利用了流行的现有包,例如 WiX、RPM、Cygwin 和 PackageMaker。
随着流行构建工具的出现,CMake 会持续跟踪并支持它们。CMake 为 Microsoft 的 Visual Studio 和 Apple 的 Xcode IDE 新版本迅速提供了支持。此外,还为 CMake 添加了对 Google 新构建工具 Ninja 的支持。使用 CMake,一旦编写了输入文件,即可免费获得对新编译器和构建系统支持,因为对这些内容的支持已内置到 CMake 的新版本中,并且与您的软件分发无关。CMake 还持续支持交叉编译到其他操作系统或嵌入式设备。跨编译时,CMake 中的大多数命令都能正确处理主机系统和目标平台之间的差异。
为何不使用 Autoconf?¶
在开发 CMake 之前,其作者已经积累了使用已有的构建工具的经验。Autoconf 与 Automake 组合在一起提供了与 CMake 相同的部分功能,但是在 Windows 平台上使用这些工具需要安装许多额外的工具,而这些工具并非作为 Windows 计算机上的本机程序存在的。除了需要大量工具之外,autoconf 可能难以使用或扩展,而且不可能执行在 CMake 中很容易实现的某些任务。即使您确实在系统中运行了 autoconf 及其所需的环境,它也会生成 Makefiles,这将强制用户使用命令行界面。另一方面,CMake 提供了一个选择,允许开发人员生成可直接从 Windows 和 Xcode 开发人员习惯使用的 IDE 中使用的项目文件。
虽然 autoconf 支持用户指定选项,但它不支持依赖选项,在这种情况下,一个选项依赖于另一个属性或选择。例如,在 CMake 中,您可以让一个用户选项要求多线程取决于首先确定用户的系统是否支持多线程。CMake 提供了一个交互式用户界面,使用户能够轻松查看可用的选项以及如何设置这些选项。
对于 UNIX 用户,CMake 还提供自动依赖项生成,这项工作并非 autoconf 直接完成的。与 Makefile.in 和 configure.in 文件的组合相比,CMake 的简单输入格式也更易于阅读和维护。CMake 的记忆和链接库依赖项信息的能力在 autoconf/automake 中是没有对应的。
为何不用 JAM、qmake、SCons 或 ANT?¶
其他工具(如 ANT、qmake、SCons 和 JAM)采用不同的方法来解决这些问题,它们帮助我们塑造了 CMake。在四种工具中,qmake 与 CMake 最相似,尽管它缺少 CMake 提供的大量系统查询。qmake 的输入格式与传统 Makefile 关系更为密切。ANT、JAM 和 SCons 也是跨平台的,尽管它们不支持生成本机项目文件。它们通过 ANT 使用 XML、JAM 使用自己的语言以及 SCons 使用 Python 从传统的 Makefile 导向输入中脱离出来。许多此类工具直接运行编译器,而不是让系统的构建过程执行此任务。在这些工具中,很多需要安装 Python 或 Java 之类工具才能工作。
为何不自己编写脚本?¶
有些项目利用现有的脚本语言(如 Perl 或 Python)配置构建过程。虽然利用此类系统可以实现类似的功能,但是过度使用这些工具可能会使构建过程更像一场寻宝游戏,而不是一个易于使用的构建系统。在构建您的软件包时,用户被迫先找到并安装此软件的 4.3.2 版和彼软件的 3.2.4 版,然后才能开始构建过程。为了避免此问题,我们决定 CMake 只需要比它用来构建的软件所需的更多工具。最低限度,使用 CMake 需要一个 C 编译器,该编译器的本机构建工具以及一个 CMake 可执行文件。CMake 是用 C++ 编写的,只需要 C++ 编译器即可构建,并且为大多数系统提供了预编译二进制文件。自己编写脚本通常也意味着您不会生成本机 Xcode 或 Visual Studio 工作区,这会限制 Mac 和 Windows 的构建。
CMake 在哪些平台上运行?¶
CMake 运行在各种平台上,包括 Microsoft Windows、Apple Mac OS X 和大多数 UNIX 或类 UNIX 平台。同样,CMake 也支持大多数常见编译器。
CMake 有多稳定?¶
在为项目采用任何新技术或工具之前,开发人员会想要了解该工具的支持程度和受欢迎程度。自最初的 CMake 实施以来,CMake 作为构建工具而越来越受欢迎。开发人员和用户社区都在持续增长。CMake 一直在持续开发对新构建技术和工具的支持,因为它们已经可用。CMake 开发团队对向后兼容性做出了坚定承诺。如果 CMake 可以构建您的项目一次,它就应该始终可以构建您的项目。此外,由于 CMake 是一个开源项目,所以源代码始终可供项目编辑和按需修补。