第一章 为什么选择CMake?
如果你曾经维护过软件包的构建和安装过程,你将会对Cmake产生兴趣。CMake 是一个开放源代码的构建管理器。他允许开发者在一个简单可移植的文本格式文件(txt)中,构建指定的构建参数的项目工程。这个文件随后将用于生成包括集成开发环境在内的本地开发工具(例如Microsoft Visual Studio , Apple’s Xcode ,Unix Linux,Nmake,Borlandstyle Makefiles)的工程文件。CMake允许用户通过简单的裁剪构建出复杂的硬件和软件系统,解决了软件构件中多个方面的难题,例如跨平台构建,系统鉴别(system introspection)以及用户自定义构建。
对于很多项目工程来说,尤其是跨平台的工程,有一个统一的构建系统尤为重要。现在很多工程既要用于Unix Makefile(or Makefile.in)也要用 Microsoft Visual Studio的工作空间。
这就要求开发者不断的更新两个不同的构建系统,使他们相互保持一致。为了一些额外的构建系统例如Borland或者甚至要求更多这些文件的自定义副本的Xcode,以至于衍生出一个更大的问题。如果你想要支持一些可选的组建(例如当系统支持libjpeg时工程中要增加jpeg支持),这个问题将变得异常复杂。CMake 通过将这些不同的操作合并到一个简单易用的文本格式文件中,来解决这些难题。
如果你存在多个开发者在使用同一个工程或者一个工程拥有多个目标平台的情况,并且这个软件将不得不在不止一台电脑上构建。给一台现代计算机在安装软件和自定义选项时一个宽泛的选择范围,即时两台同样操作系统的计算机也会有细微不同的概率。CMake 具备很多用于解决单平台多机器开发环境问题的功能:
自动搜索那些软件构建过程中会用到的bin文件,库文件以及头文件的能力(还能够在搜索时考虑环境变量和windows注册表的设置)。
在源码树目录之外构建一个构建目录树的功能。这是在很多linux平台上非常有用的功能。Cmake在windows上也提供这些功能。这就允许开发者在删除一个完整的构建目录时,不用担心任何删除源码文件的风险。
创建一个用于自动生成例如 qt moc ,ITK(InsightToolkit) 的cable wrappers以及 SWIG包装生成器文件列表的复杂自定义命令的功能。这些命令用于在按照一定顺序编译成软件的构建过程中生成新源码文件。
在配置时选择一个可选组件的功能。例如,几个不同版本VTK的库是可选的,并且Cmake提供了简单的方式让用户选择一个指定版本的库用于构建。
从一个简单的文本文件自动生成工作空间和工程文件的功能。这对于使用IDE手工创建一个繁琐的拥有多个测试用例或者程序(包括可只执行文件,库文件),并且这些测试用例和程序都是在一个单独的工程内的系统来说还是很方便的。
非常方便的在静态和共享库之间切换的功能。Cmake拥有创建出跨所有平台的共享库和模块的功能。一些复杂的平台特化的链接标识,和在unix族系统上支持运行时搜索指定目录下面的共享库的高级特性都能够被很方便的处理。
支持机器字节序以及其他硬件特性问题的测试。
支持能够在所有平台工作的仅仅一套配置文件。这就避免了开发者在必须在一个项目中掌握不同平台不同格式的工程(而这些工程的内容却必须是同步的)。
支持构建所有平台共享库(不同平台构建出该平台支持的共享库)。
在大部分平台下支持并行构建和自动生成文件依赖。
在你开发一个跨平台的软件项目时,Cmake提供很多附加的特性:
支持包含系统依赖信息的配置文件,例如本地数据文件或者其他信息的位置。CMake能够创建出包含以下信息的头文件,例如:用#define宏列表示的数据文件的路径或者其他信息。也能够将系统特定的标识放入头文件中。通过命令行-D选项传递给编译器具备一些优点,因为它允许其他的构建系统使用CMake构建库,而不必指定在构建期使用的在不同编译器上代表相同含义却有可能不同的命令行。
1.1 CMake的历史
CMake 起源于 1999年作为ITK(InsightToolkit)的一部分被美国国家医学图书馆资助。ITK是一个非常大的并且能在很多平台工作的软件项目,他能够跟许多其他软件包互动。为实现这个目标,需要一个强大的,且容易使用的构建工具。在过去的一些大项目中已经使用了构建工具,ITK的开发者们基于这些需要设计了CMake。从此越来越多的项目和开发者由于CMake的易用性和灵活性而采用他,CMake迅速持续不断的完善。从1999年开始CMake就是一个非常活跃的开发项目,并且是一个用于跨平台构建的成熟解决方案。最广为人知案例:KDE的就是采用CMake构建,这几乎可以说是已经存在的最大的开源项目。
最近更新的功能之一就是CTest的形式支持软件测试。测试软件过程的一部分涉及到软件的构建,可能在安装时要决定软件的哪一部分适合当前的系统。这就促使CTest 成为了CMake已经存在的大部分信息的一个逻辑扩展。类似,CMake的一个新特性是CPack。CPack
支持跨平台的软件发行包构建。CPack提供了一个为你的软件提供一个本机安装包的捷径,能够构建出现有的很多流行构建包,例如NSIS,RPM,Cygwin以及PackageMaker。
另外一个最近的新功能是,支持苹果的XcodeIDE并且支持微软的Visual Studio 10。使用CMake,一旦你编写了你的输入文件,你就获得了新编译器的支持,并且能够自由的利用构建系统将你的工程构建成CMake发行包,而不用局限于软件现有的发行包。CMake也支持交叉编译到其他的操作系统或者嵌入式设备。现在,在交叉编译时CMake中许多命令能够合适的处理在不同的主机系统与目标平台之间的不同。
1.2 为什么不使用Autoconf?
在CMake的作者在开发它之前已经有使用存在的一系列的可用工具的经验。Autoconf结合automake 提供了许多类似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.3 为什么不采用JAM, qmake,Scons,或者ANT?
其他一些工具例如ANT,qmake,Scons和JAM有一些不同的方案来解决这些问题。这些工具帮助我们使CMake成型。在这四个工具中,qmake是与cmake最相似的,尽管它缺少一些CMake中提供的一些系统适配的功能。Qmake输入文件跟传统的makefile文件关系更近。ANT,JAM和Scons也能提供跨平台功能,尽管他们不支持本地工程文件的生成。ANT使用xml作为输入使其与传统的makefile区分开来,JAM用他自有的语言,而Scons使用的是python。这些工具中的几个直接调用编译器,而不是构建系统来直接处理这些构建任务。它们中的一些工具要求安装例如python和Java的第三方工具才能够正常工作。
1.4 为什么不自己使用脚本
有一些工程使用了一些已经存在的脚本语言例如Perl或者 Python 来配置构建过程。尽管用这些类似的系统能够实现一些相似的功能,相对于一个简单易用的构建系统,使用这些工具会比寻找一个复活节彩蛋更麻烦。当构建你的软件时,你甚至都还没有开始进入构建过程,用户被强制要求找到并安装,4.3.2版本的这个工具以及3.2.4版本的其他工具。为了避免这些问题,这就要求CMake构建时除了这个软件本身要用到的一些工具不再需要其他的任何工具。使用Cmake一个最低限制是一个c编译器,以及编译器的原生构建工具和一个CMake的可执行文件。CMake是用C++编写的,仅仅要求必须有一个c++的编译器来构建CMake本身,并且在大部分系统中已经有已经编译好的可执行文件可以直接用。如果你自己用脚本来实现,意味着不能生成本地的Xcode或者Visual Studio的工作空间,使得在Mac或者Windows上构建受限。
1.5 CMake支持哪些平台
CMake能够在非常的平台上运行包括微软的Windows,苹果的Mac OS X以及绝大多数的UNIX以及类UNIX的平台。在编者写这本书的时候CMake已经在以下平台长期测试过:Windows 98/2000/XP/Vista/7,AIX,HPUX,IRIX,Linux,Mac OS X,Solaris,OSF,QNX,CYGWIN,MinGW以及FreeBSD。你能够从www.cmake.org这个网站得到一个已测试平台的列表。
同样,CMake支持绝大部分常规编译器。它支持GNU编译器在所有CMake支持的平台上。其他已测试过的编译器包括Visual Studio 6到10,Intel C,SGI CC,Mips Pro,Borland,Sun CC 以及HP aCC。CMake 也能够在列表之外的绝大多数Unix风格的编译器上使用。如果编译器用一个奇怪的方式传递这些参数,你可以查看在第241的“将CMake 移植到新编译器”的章节中的信息,来确定怎样自定义设置一个新的编译器。