Directory Structure
CMake在构建项目时使用两个主要目录:源目录和二进制目录。源目录是项目源代码所在的位置,也是CMakeLists文件的位置。二进制目录有时被称为构建目录,CMake将在其中放置生成的对象文件、库和可执行文件。CMake不会将任何文件写入源目录,只会写入二进制目录。
强烈鼓励源代码和二进制目录不同的源代码外构建。支持源代码和二进制目录相同的源代码构建,但应尽可能避免。源代码外构建使维护干净的源代码树变得非常容易,并允许快速删除构建生成的所有文件。使构建树不同于源树也可以很容易地支持单个源树的多个构建。当您希望有多个具有不同选项的构建,但只有一个源代码副本时,这很有用。
Basic CMake Usage
CMake接收一个或多个CMakeLists文件作为输入,并生成项目文件或Makefile,以供各种本地开发工具使用。
典型的CMake过程如下:
1.为项目定义一个或多个CMakeLists文件;
2.CMake配置(configure)并生成(generate)项目;
3.用户使用他们最喜欢的本地开发工具构建(build)项目。
以下部分详细描述了该过程的每个步骤。
CMakeLists Files
CMakeLists.txt
是纯文本文件,包含CMake语言的项目描述。are plain text files that contain the project description in CMake’s Language. cmake-language
表示为一系列注释、命令和变量。你可能想知道为什么CMake决定拥有自己的语言,而不是使用现有的语言,如Python、Java或Tcl。主要原因是CMake开发人员不想让CMake需要额外的工具来运行。通过要求使用这些其他语言之一,所有CMake用户都需要安装该语言,并可能安装该语言的特定版本。出于性能和功能的原因,这是完成一些CMake工作所需的语言扩展的基础。
Hello World for CMake
首先,让我们考虑最简单的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和命令行界面配置和构建项目。
Configure and Generate
创建CMakeLists文件后,CMake处理文本文件并在缓存文件中创建条目。用户可以编辑CMakeLists文件,或使用CMakegui或ccmake指定缓存值,然后重新配置。接下来,CMake使用缓存条目在用户所需的构建系统(例如Makefile或Visual Studio解决方案)中生成项目。
Running the CMake GUI
CMake包括一个基于Qt的用户界面,可以在大多数平台上使用,包括UNIX、Mac OS X和Windows。cmakegui包含在cmake源代码中,但您需要在系统上安装Qt才能构建它。
在Windows上,可执行文件名为cmake-gui.exe,它应该位于“开始”菜单的“程序文件”下。您的桌面上也可能有一个快捷方式,或者如果您从源代码构建CMake,它将位于构建目录中。对于UNIX和Mac用户,可执行文件名为cmake-gui,可以在安装cmake可执行文件的位置找到。GUI将显示类似于图1所示的内容。前两个字段是源代码和二进制目录。它们允许您指定要编译的源代码的位置,以及应将生成的二进制文件放置在何处。您应该先设置这两个值。如果您指定的二进制目录不存在,将为您创建它。如果CMake之前已经配置了二进制目录,那么它将自动设置源代码树。
Running the ccmake Curses Interface
在大多数UNIX平台上,如果支持curses库,CMake会提供一个名为ccmake的可执行文件。这个界面是一个基于终端的文本应用程序,与cmakegui非常相似。要运行ccmake,请将目录更改为要放置二进制文件的目录。然后在命令行上使用源目录的路径运行ccmake。这将启动如图2所示的文本界面。
简要说明显示在窗口底部。如果按'c'键,它将配置项目。您应该始终在更改缓存中的值后进行配置。要更改值,请使用箭头键选择缓存条目,然后按enter键进行编辑。布尔值将使用enter键切换。设置完所有值后,您可以按“g”键生成Makefiles并退出。您还可以点击“h”获取帮助,点击“q”退出,点击“t”切换高级缓存条目的查看。
Running CMake from the Command Line
从命令行,cmake
可执行文件可用于生成项目构建系统。这最适合选择很少或没有选择的项目。对于像VTK这样的大型项目,建议使用ccmake
或cmake-gui
。要使用cmake
构建项目,首先创建并更改要放置二进制文件的目录。运行cmake
,指定源树的路径,并使用 -D 标志传递任何选项。与ccmake
或cmake-gui
不同,使用cmake
可执行文件时,配置和生成步骤被合并为一个步骤。
Specifying the Compiler to 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。
Build Configurations
构建配置允许以不同的方式构建项目,以进行调试、优化或任何其他特殊的标志集。CMake默认支持Debug、Release、MinSizeRel和RelWithDebInfo配置。
- Debug启用了基本调试标志。
- Release启用了基本优化。
- MinSizeRel具有生成最小目标代码但不一定是最快代码的标志。
- RelWithDebInfo也使用调试信息构建优化的构建。
CMake根据所使用的生成器以略有不同的方式处理配置。尽可能遵循本地构建系统的惯例。这意味着使用Makefile和使用Visual Studio项目文件时,配置对构建的影响不同。
Visual Studio IDE支持构建配置的概念。Visual Studio中的默认项目通常具有调试和发布配置。从IDE中,您可以选择构建调试,文件将使用调试标志构建。IDE将所有二进制文件放入具有活动配置名称的目录中。这给构建需要从自定义命令作为构建过程的一部分运行的程序的项目带来了额外的复杂性。有关如何处理此问题的更多信息,请参阅CMAKE_CFG_INTDIR变量和自定义命令部分。变量CMAKE_CONFIGURATION_TYPES用于告诉CMAKE将哪些配置放入工作区。
使用基于Makefile的生成器,在运行CMake时只能有一个配置处于活动状态,并且是用CMake_BUILD_TYPE变量指定的。如果变量为空,则不会向构建中添加任何标志。如果变量设置为配置的名称,则相应的变量和规则(如CMAKE_CXX_FLAGS_<ConfigName>)将添加到编译行中。Makefiles不为对象文件使用特殊的配置子目录。要构建调试树和发布树,用户需要使用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
Building Your Project
运行CMake后,您的项目就可以构建了。如果你的目标生成器基于Makefiles,那么你可以通过将目录更改为二叉树并键入make
(或gmake
或nmake
,视情况而定)来构建你的项目。如果您为Visual Studio等IDE生成了文件,则可以启动IDE,将项目文件加载到其中,然后像往常一样进行构建。
另一种选择是从命令行使用cmake
的--build选项。此选项只是一种方便,允许您从命令行构建项目,即使这需要启动IDE。
这就是为简单项目安装和运行CMake的全部内容。在接下来的章节中,我们将更详细地考虑CMake,并解释如何在更复杂的软件项目中使用它。