入门¶
在您的计算机上获取和安装 CMake¶
在使用 CMake 之前,您需要在系统上安装或构建 CMake 二进制文件。在许多系统上,您可能会发现 CMake 已经安装或可以使用系统的标准包管理器工具进行安装。Cygwin、Debian、FreeBSD、OS X MacPorts、Mac OS X Fink 等等都提供了 CMake 发行版。
如果您的系统没有 CMake 包,您可以在 CMake 的 下载 页面上找到许多常见架构的预编译 CMake。选择所需的版本并按照下载说明进行操作。CMake 可以安装到任何目录,因此安装不需要 root 权限。
如果您在系统上找不到预编译的二进制文件,则可以从源代码构建 CMake。要构建 CMake,您需要一个现代的 C++ 编译器以及来自 CMake 下载 页面或 Kitware 的 GitLab 实例 的源代码分发版。要构建 CMake,请按照源代码树顶部的 README.rst
中的说明进行操作。
目录结构¶
CMake 在构建项目时使用两个主要目录:源目录和二进制目录。源目录是项目源代码所在的目录。这也是 CMakeLists 文件所在的位置。二进制目录有时也称为构建目录,CMake 将把生成的 object 文件、库和可执行文件放在这里。CMake 不会向源目录写入任何文件,只会写入二进制目录。
强烈建议使用源代码和二进制目录不同的“源外构建”。支持源代码和二进制目录相同的“源内构建”,但应尽量避免。源外构建使维护干净的源代码树变得非常容易,并且可以快速删除构建生成的所有文件。使构建树与源代码树不同还可以轻松支持对单个源代码树进行多次构建。当您希望使用不同的选项进行多个构建,但只有一个源代码副本时,这很有用。
基本的 CMake 用法¶
CMake 以一个或多个 CMakeLists 文件作为输入,并生成项目文件或 Makefile,以供各种本地开发工具使用。
典型的 CMake 流程如下
项目在一个或多个 CMakeLists 文件中定义
CMake 配置并生成项目
用户使用他们最喜欢的本地开发工具构建项目
以下各节将详细描述流程的每个步骤。
CMakeLists 文件¶
CMakeLists 文件(实际上是 CMakeLists.txt
,但通常省略扩展名)是包含 CMake 语言中项目描述的纯文本文件。cmake-language
表示为一系列注释、命令和变量。您可能想知道为什么 CMake 选择拥有自己的语言而不是使用现有的语言,例如 Python、Java 或 Tcl。主要原因是 CMake 开发人员不想让 CMake 依赖其他工具才能运行。如果需要这些其他语言之一,所有 CMake 用户都必须安装该语言,并且可能需要特定版本的该语言。这还需要进行语言扩展才能完成某些 CMake 工作,原因在于性能和功能。
CMake 的 Hello World¶
首先,让我们考虑最简单的 CMakeLists 文件。要从一个源文件编译一个可执行文件,CMakeLists 文件将包含三行
cmake_minimum_required(VERSION 3.20)
project(Hello)
add_executable(Hello Hello.c)
顶级 CMakeLists 文件的第一行应始终是 cmake_minimum_required
。这允许项目要求特定版本的 CMake,此外,还允许 CMake 向后兼容。
任何顶级 CMakeLists 文件的下一行应该是 project
命令。此命令设置项目的名称,并可能指定其他选项,例如语言或版本。
对于项目中每个包含 CMakeLists.txt 文件并调用 project
命令的目录,CMake 生成一个顶级 Makefile 或 IDE 项目文件。该项目将包含 CMakeLists.txt 文件中以及任何子目录中的所有目标,如 add_subdirectory
命令所指定。如果在 add_subdirectory
命令中使用了 EXCLUDE_FROM_ALL
选项,则生成的项目将不会出现在顶级 Makefile 或 IDE 项目文件中;这对于生成在主构建过程中没有意义的子项目很有用。可以考虑一个包含许多示例的项目,它可以使用此功能在一个 CMake 运行中生成每个示例的构建文件,但不会将示例作为正常构建过程的一部分进行构建。
最后,使用 add_executable
命令使用给定的源文件向项目添加可执行文件。
在此示例中,源目录中有两个文件:CMakeLists.txt
和 Hello.c
。
接下来的部分将介绍如何使用 CMake GUI 和命令行界面配置和构建项目。
配置和生成¶
创建 CMakeLists 文件后,CMake 会处理文本文件并在缓存文件中创建条目。用户可以使用 CMake gui 或 ccmake 编辑 CMakeLists 文件或指定缓存值,然后重新配置。接下来,CMake 使用缓存条目在用户所需的构建系统(例如 Makefile 或 Visual Studio 解决方案)中生成项目。
运行 CMake GUI¶
CMake 包含一个基于 Qt 的用户界面,可以在大多数平台上使用,包括 UNIX、Mac OS X 和 Windows。cmake-gui
包含在 CMake 源代码中,但您需要在系统上安装 Qt 才能构建它。
在 Windows 上,可执行文件名为 cmake-gui.exe
,它应该位于“程序文件”下的“开始”菜单中。桌面也可能有一个快捷方式,或者如果您从源代码构建了 CMake,它将位于构建目录中。对于 UNIX 和 Mac 用户,可执行文件名为 cmake-gui
,可以在您安装 CMake 可执行文件的位置找到它。将出现一个类似于图 1 中所示的 GUI。前两个字段是源代码目录和二进制目录。它们允许您指定要编译内容的源代码所在位置以及生成的二进制文件应放置的位置。您应首先设置这两个值。如果指定的二进制目录不存在,将为您创建。如果二进制目录之前已由 CMake 配置过,它将自动设置源代码树。
运行 ccmake Curses 界面¶
在大多数 UNIX 平台上,如果支持 curses 库,CMake 提供一个名为 ccmake
的可执行文件。此界面是一个基于终端的文本应用程序,与 cmake-gui
非常相似。要运行 ccmake
,请切换到您希望放置二进制文件的目录。然后使用命令行上的源代码路径运行 ccmake
。这将启动图 2 中所示的文本界面。
窗口底部会显示简要说明。如果按下“c”键,它将配置项目。更改缓存中的值后,应始终进行配置。要更改值,请使用箭头键选择缓存条目,然后按 Enter 键进行编辑。布尔值将通过 Enter 键切换。设置好所有值后,可以按“g”键生成 Makefile 并退出。您还可以按“h”获取帮助,“q”退出,以及“t”切换高级缓存条目的查看。
从命令行运行 CMake¶
从命令行,可以使用 cmake
可执行文件生成项目构建系统。这最适合选项很少或没有选项的项目。对于像 VTK 这样的大型项目,建议使用 ccmake
或 cmake-gui
。要使用 cmake
构建项目,首先创建并切换到您希望放置二进制文件的目录。运行 cmake
并指定源树的路径,并使用 -D
标志传入任何选项。与 ccmake
或 cmake-gui
不同,当使用 cmake
可执行文件时,配置和生成步骤合并为一个步骤。
向 CMake 指定编译器¶
在某些系统上,您可能有多个编译器可供选择,或者您的编译器可能位于非标准位置。在这些情况下,您需要向 CMake 指定所需编译器的位置。有三种方法可以指定:生成器可以指定编译器;可以设置环境变量;或者可以设置缓存条目。某些生成器与特定编译器绑定;例如,Visual Studio 19 生成器始终使用 Microsoft Visual Studio 19 编译器。对于基于 Makefile 的生成器,CMake 将尝试一系列常用的编译器,直到找到一个可用的编译器。
可以使用在运行 CMake 之前设置的环境变量来抢占这些列表。CC
环境变量指定 C 编译器,而 CXX
指定 C++ 编译器。例如,您可以使用 -DCMAKE_CXX_COMPILER=cl
在命令行上直接指定编译器。运行 cmake
并选择编译器后,如果要更改编译器,请使用空二进制目录重新开始。
编译器和链接器的标志也可以通过设置环境变量来更改。设置 LDFLAGS
将初始化链接标志的缓存值,而 CXXFLAGS
和 CFLAGS
将分别初始化 CMAKE_CXX_FLAGS
和 CMAKE_C_FLAGS
。
构建配置¶
构建配置允许以不同的方式构建项目,以进行调试、优化或任何其他特殊标志集。默认情况下,CMake 支持 Debug、Release、MinSizeRel 和 RelWithDebInfo 配置。Debug 已启用基本的调试标志。Release 已启用基本的优化标志。MinSizeRel 具有生成最小目标代码的标志,但不一定是速度最快的代码。RelWithDebInfo 构建具有调试信息的优化版本。
CMake 根据使用的生成器以略微不同的方式处理配置。尽可能遵循原生构建系统的约定。这意味着在使用 Makefile 与使用 Visual Studio 项目文件时,配置对构建的影响方式不同。
Visual Studio IDE 支持构建配置的概念。Visual Studio 中的默认项目通常具有 Debug 和 Release 配置。从 IDE 中,您可以选择构建 Debug,文件将使用 Debug 标志进行构建。IDE 将所有二进制文件放入具有活动配置名称的目录中。这为构建需要作为构建过程的一部分从自定义命令运行的程序的项目带来了额外的复杂性。有关如何处理此问题的更多信息,请参见 CMAKE_CFG_INTDIR
变量和自定义命令部分。变量 CMAKE_CONFIGURATION_TYPES
用于告诉 CMake 将哪些配置放入工作区。
对于基于 Makefile 的生成器,在运行 CMake 时只能激活一个配置,并使用 CMAKE_BUILD_TYPE
变量指定。如果变量为空,则不会向构建添加任何标志。如果变量设置为配置的名称,则相应的变量和规则(例如 CMAKE_CXX_FLAGS_<ConfigName>
)将添加到编译行。Makefile 不使用用于对象文件的特殊配置子目录。要构建调试和发布树,用户应使用 CMake 的源外构建功能创建多个构建目录,并将 CMAKE_BUILD_TYPE
设置为每个构建所需的选项。例如
# With source code in the directory MyProject
# to build MyProject-debug create that directory, cd into it and
ccmake ../MyProject -DCMAKE_BUILD_TYPE=Debug
# the same idea is used for the release tree MyProject-release
ccmake ../MyProject -DCMAKE_BUILD_TYPE=Release
构建您的项目¶
运行 CMake 后,您的项目将准备好构建。如果您的目标生成器基于 Makefile,则可以通过将目录更改为您的二进制树并键入 make(或 gmake 或 nmake,具体取决于情况)来构建项目。如果您为 IDE(例如 Visual Studio)生成了文件,则可以启动您的 IDE,将项目文件加载到其中,并像往常一样构建。
另一种选择是从命令行使用 cmake
的 --build
选项。此选项只是一个便利,允许您从命令行构建项目,即使这需要启动 IDE。
对于简单的项目,安装和运行 CMake 就这么简单。在接下来的章节中,我们将更详细地讨论 CMake,并解释如何在更复杂的软件项目中使用它。