用户交互指南¶
简介¶
当软件提供基于 CMake 的构建系统和其软件源代码时,软件的消费者需要运行 CMake 用户交互工具来构建它。
行为良好的基于 CMake 的构建系统不会在源目录中产生任何输出,因此通常情况下,用户会执行“out-of-source”构建并在那里执行构建。首先,必须指示 CMake 生成合适的构建系统,然后用户调用构建工具来处理生成的构建系统。生成的构建系统特定于用于生成它的机器,并且不可重新分发。每个提供的软件源代码包的消费者都需要使用 CMake 为其系统生成特定的构建系统。
生成的构建系统通常应被视为只读。CMake 文件作为主要产物应完全指定构建系统,并且不应有任何理由手动填充 IDE 中的属性,例如在生成构建系统之后。CMake 将定期重写生成的构建系统,因此用户所做的修改将被覆盖。
通过提供 CMake 文件,本手册中描述的功能和用户界面可用于所有基于 CMake 的构建系统。
CMake 工具在处理提供的 CMake 文件时可能会向用户报告错误,例如报告编译器不受支持,或编译器不支持必需的编译选项,或者找不到依赖项。这些错误必须由用户通过选择不同的编译器、安装依赖项
,或指示 CMake 何处可以找到它们等来解决。
命令行 cmake 工具¶
一个简单但典型的 cmake(1)
的用法是,对于一份新的软件源代码副本,创建一个构建目录并在那里调用 cmake
$ cd some_software-1.4.2
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_INSTALL_PREFIX=/opt/the/prefix
$ cmake --build .
$ cmake --build . --target install
建议在与源代码分开的目录中进行构建,因为这样可以保持源代码目录的整洁,允许使用多个工具链构建单个源代码,并允许通过简单删除构建目录来轻松清除构建工件。
CMake 工具可能会向用户报告一些警告,这些警告是为软件提供者准备的,而不是为软件消费者准备的。此类警告的结尾是“此警告供项目开发人员参考”。用户可以通过将 -Wno-dev
标志传递给 cmake(1)
来禁用这些警告。
cmake-gui 工具¶
更习惯 GUI 界面的用户可以使用 cmake-gui(1)
工具来调用 CMake 并生成构建系统。
必须先填充源目录和二进制目录。始终建议为源和构建使用不同的目录。

生成构建系统¶
有几种用户界面工具可用于从 CMake 文件生成构建系统。 ccmake(1)
和 cmake-gui(1)
工具引导用户完成设置各种必需选项的过程。 cmake(1)
工具可以调用以在命令行上指定选项。本手册描述了可使用任何用户界面工具设置的选项,尽管为每个工具设置选项的方式不同。
命令行环境¶
当使用 Makefiles
或 Ninja
等命令行构建系统调用 cmake(1)
时,必须使用正确的构建环境来确保构建工具可用。CMake 必须能够根据需要找到适当的 构建工具
、编译器、链接器和其他工具。
在 Linux 系统上,适当的工具通常位于系统范围的目录中,并且可以通过系统包管理器轻松安装。也可以使用用户提供的或安装在非默认位置的其他工具链。
进行交叉编译时,某些平台可能需要设置环境变量,或者可能提供脚本来设置环境。
Visual Studio 附带多个命令提示符和 vcvarsall.bat
脚本,用于为命令行构建系统设置正确的环境。虽然在使用 Visual Studio 生成器时严格来说不必使用相应的命令行环境,但这样做没有坏处。
使用 Xcode
时,可能安装有多个 Xcode 版本。可以通过多种方式选择要使用的版本,但最常见的方法是:
在 Xcode IDE 的首选项中设置默认版本。
通过
xcode-select
命令行工具设置默认版本。在运行 CMake 和构建工具时,通过设置
DEVELOPER_DIR
环境变量来覆盖默认版本。
为了方便起见,cmake-gui(1)
提供了一个环境变量编辑器。
命令行 -G
选项¶
CMake 默认根据平台选择生成器。通常,默认生成器足以让用户继续构建软件。
用户可以使用 -G
选项覆盖默认生成器。
$ cmake .. -G Ninja
运行 cmake --help
的输出包含用户可供选择的 生成器
列表。请注意,生成器名称区分大小写。
在类 Unix 系统(包括 Mac OS X)上,默认使用 Unix Makefiles
生成器。该生成器的变体也可以在 Windows 的各种环境中(例如 NMake Makefiles
和 MinGW Makefiles
生成器)中使用。这些生成器生成一个 Makefile
变体,可以使用 make
、gmake
、nmake
或类似工具执行。有关目标环境和工具的更多信息,请参阅各个生成器文档。
Ninja
生成器可在所有主要平台上使用。 ninja
是一个构建工具,其用例与 make
类似,但侧重于性能和效率。
在 Windows 上,cmake(1)
可用于为 Visual Studio IDE 生成解决方案。Visual Studio 版本可以通过 IDE 的产品名称指定,其中包括四位数字的年份。还为其他有时引用 Visual Studio 版本的方式提供了别名,例如对应于 VisualC++ 编译器产品版本的两位数字,或者两者的组合。
$ cmake .. -G "Visual Studio 2019"
$ cmake .. -G "Visual Studio 16"
$ cmake .. -G "Visual Studio 16 2019"
Visual Studio 生成器 可以针对不同的架构。可以使用 -A
选项指定目标架构。
cmake .. -G "Visual Studio 2019" -A x64
cmake .. -G "Visual Studio 16" -A ARM
cmake .. -G "Visual Studio 16 2019" -A ARM64
在 Apple 上,可以使用 Xcode
生成器生成 Xcode IDE 的项目文件。
一些 IDE,如 KDevelop4、QtCreator 和 CLion,对基于 CMake 的构建系统具有原生支持。这些 IDE 提供了用户界面来选择要使用的底层生成器,通常是在 Makefile
或 Ninja
基于的生成器之间进行选择。
请注意,在首次调用 CMake 后,无法使用 -G
更改生成器。要更改生成器,必须删除构建目录并从头开始构建。
在生成 Visual Studio 项目和解决方案文件时,在首次运行 cmake(1)
时还有其他选项可用。
可以使用 cmake -T
选项指定 Visual Studio 工具集。
$ # Build with the clang-cl toolset
$ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T ClangCL
$ # Build targeting Windows XP
$ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T v120_xp
而 -A
选项指定*目标*架构,-T
选项可用于指定所用工具链的详细信息。例如,可以给出 -Thost=x64
来选择 64 位版本的宿主工具。以下示例演示了如何使用 64 位工具并为 64 位目标架构构建:
$ cmake .. -G "Visual Studio 16 2019" -A x64 -Thost=x64
在 cmake-gui 中选择生成器¶
“配置”按钮会触发一个新的对话框,用于选择要使用的 CMake 生成器。

命令行中所有可用的生成器在 cmake-gui(1)
中也可用。

选择 Visual Studio 生成器时,还可以选择设置要生成的目标架构。

设置构建变量¶
软件项目通常需要在调用 CMake 时在命令行上设置变量。下表列出了一些最常用的 CMake 变量:
变量 |
含义 |
---|---|
搜索 |
|
搜索其他 CMake 模块的路径 |
|
构建配置,例如 |
|
使用 |
|
包含交叉编译数据的ファイル,例如 |
|
对于不带类型使用的 |
|
生成用于 clang 相关工具的 |
|
生成用于 clang 相关工具的 |
其他项目特定的变量可能可用,用于控制构建,例如启用或禁用项目的组件。
CMake 未为不同提供程序之间的变量命名约定提供约定,除非以 CMAKE_
为前缀的变量通常指 CMake 本身提供的选项,不应用于第三方选项,第三方应使用自己的前缀。 cmake-gui(1)
工具可以按其前缀定义的组显示选项,因此第三方确保使用一致的前缀是有意义的。
在命令行设置变量¶
CMake 变量可以在创建初始构建时在命令行上设置
$ mkdir build
$ cd build
$ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug
或者在后续调用 cmake(1)
时设置。
$ cd build
$ cmake . -DCMAKE_BUILD_TYPE=Debug
可以使用 -U
标志在 cmake(1)
命令行上取消设置变量。
$ cd build
$ cmake . -UMyPackage_DIR
最初在命令行上创建的 CMake 构建系统可以使用 cmake-gui(1)
进行修改,反之亦然。
使用 cmake-gui 设置变量¶
可以使用“添加条目”按钮在 cmake-gui 中设置变量。这会触发一个新对话框来设置变量的值。

cmake-gui(1)
用户界面的主视图可用于编辑现有变量。
CMake 缓存¶
当 CMake 执行时,它需要找到编译器、工具和依赖项的位置。它还需要能够一致地重新生成构建系统,以使用相同的编译/链接标志和依赖项路径。这些参数也需要用户可配置,因为它们是用户系统特有的路径和选项。
当它首次执行时,CMake 在构建目录中生成一个 CMakeCache.txt
文件,其中包含这些工件的键值对。用户可以通过运行 cmake-gui(1)
或 ccmake(1)
工具来查看或编辑缓存文件。这些工具提供了一个交互式界面,用于在编辑缓存值后重新配置提供的软件并重新生成构建系统。每个缓存条目可能有一个相关的简短帮助文本,该文本显示在用户界面工具中。
缓存条目也可以有一个类型来指示它应如何在用户界面中呈现。例如,类型为 BOOL
的缓存条目可以通过用户界面中的复选框进行编辑,STRING
可以在文本字段中编辑,而 FILEPATH
虽然与 STRING
类似,但也应提供一种使用文件对话框定位文件系统路径的方法。类型为 STRING
的条目可以提供允许值的受限列表,这些值然后显示在 cmake-gui(1)
用户界面中的下拉菜单中(请参阅 STRINGS
缓存属性)。
随软件包一起提供的 CMake 文件还可以使用 option()
命令定义布尔开关选项。该命令创建一个具有帮助文本和默认值的缓存条目。此类缓存条目通常特定于提供的软件,并影响构建的配置,例如是否构建测试和示例,是否启用异常构建等。
预设¶
CMake 理解一个文件 CMakePresets.json
及其用户特定的对应文件 CMakeUserPresets.json
,用于保存常用配置设置的预设。这些预设可以设置构建目录、生成器、缓存变量、环境变量和其他命令行选项。所有这些选项都可以由用户覆盖。 CMakePresets.json
格式的完整详细信息列在 cmake-presets(7)
手册中。
在命令行使用预设¶
当使用 cmake(1)
命令行工具时,可以使用 --preset
选项调用预设。如果指定了 --preset
,则不需要生成器和构建目录,但可以指定它们来覆盖它们。例如,如果您有以下 CMakePresets.json
文件:
{
"version": 1,
"configurePresets": [
{
"name": "ninja-release",
"binaryDir": "${sourceDir}/build/${presetName}",
"generator": "Ninja",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
]
}
并且您运行以下命令:
cmake -S /path/to/source --preset=ninja-release
这将使用 Ninja
生成器在 /path/to/source/build/ninja-release
中生成构建目录,并将 CMAKE_BUILD_TYPE
设置为 Release
。
如果您想查看可用预设的列表,您可以运行:
cmake -S /path/to/source --list-presets
这将列出 /path/to/source/CMakePresets.json
和 /path/to/source/CMakeUserPresets.json
中可用的预设,而无需生成构建树。
在 cmake-gui 中使用预设¶
如果项目提供了预设,无论是通过 CMakePresets.json
还是 CMakeUserPresets.json
,预设列表都会出现在 cmake-gui(1)
中源目录和二进制目录之间的下拉菜单中。选择预设将设置二进制目录、生成器、环境变量和缓存变量,但所有这些选项都可以在选择预设后进行覆盖。
调用构建系统¶
生成构建系统后,可以通过调用特定的构建工具来构建软件。对于 IDE 生成器,这可能涉及将生成的项目文件加载到 IDE 中以调用构建。
CMake 知道调用构建所需的特定构建工具,因此通常,在生成后从命令行构建构建系统或项目,可以在构建目录中调用以下命令:
$ cmake --build .
--build
标志启用了 cmake(1)
工具的特定操作模式。它调用与 生成器
关联的 CMAKE_MAKE_PROGRAM
命令,或用户配置的构建工具。
--build
模式还接受 --target
参数来指定要构建的特定目标,例如特定的库、可执行文件或自定义目标,或者特定的特殊目标,如 install
。
$ cmake --build . --target myexe
对于多配置生成器, --build
模式还接受 --config
参数来指定要构建的特定配置。
$ cmake --build . --target myexe --config Release
如果生成器生成了一个使用 CMAKE_BUILD_TYPE
变量调用 cmake 时选择的配置特定的构建系统,则 --config
选项无效。
某些构建系统会省略构建期间调用的命令行细节。可以使用 --verbose
标志来显示这些命令行。
$ cmake --build . --target myexe --verbose
--build
模式还可以通过在 --
之后列出它们来将特定命令行选项传递给底层构建工具。这对于指定构建工具的选项很有用,例如在作业失败后继续构建,而 CMake 没有提供高级用户界面。
对于所有生成器,都可以在调用 CMake 后运行底层构建工具。例如,在使用 Unix Makefiles
生成器后,可以执行 make
来调用构建,或者在使用 Ninja
生成器后执行 ninja
等。 IDE 构建系统通常提供构建项目的命令行工具,也可以调用它们。
选择目标¶
CMake 文件中描述的可执行文件和库都是构建目标,构建系统可以描述自定义目标,用于内部使用,或供用户使用,例如创建文档。
CMake 为所有提供 CMake 文件的构建系统提供了一些内置目标。
all
Makefile 生成器 和 Ninja 生成器 使用的默认目标。构建构建系统中的所有目标,除了那些被其
EXCLUDE_FROM_ALL
目标属性或EXCLUDE_FROM_ALL
目录属性排除的目标。对于Xcode
和 Visual Studio 生成器,此目的使用名称ALL_BUILD
。help
列出可供构建的目标。使用 Makefile 生成器 或 Ninja 生成器 时可用此目标,具体输出取决于工具。
clean
删除已构建的对象文件和其他输出文件。 Makefile 生成器 为每个目录创建一个
clean
目标,以便可以清理单个目录。Ninja
工具提供其自己的精细-t clean
系统。测试
运行测试。只有当 CMake 文件提供基于 CTest 的测试时,此目标才可用。另请参见 运行测试。
安装
package
创建二进制包。只有当 CMake 文件提供基于 CPack 的包时,此目标才可用。
package_source
创建源包。只有当 CMake 文件提供基于 CPack 的包时,此目标才可用。
对于 Makefile 生成器,提供了二进制构建目标的 /fast
变体。 /fast
变体用于构建指定目标,而不考虑其依赖项。不检查依赖项,并且如果过时也不会重新构建。 Ninja 生成器 在依赖项检查方面足够快,因此不为该生成器提供此类目标。
Makefile 生成器 还提供用于预处理、汇编和编译特定目录中单个文件的构建目标。
$ make foo.cpp.i
$ make foo.cpp.s
$ make foo.cpp.o
文件名扩展名内置在目标名称中,因为可能存在同名但扩展名不同的文件。但是,也提供了没有文件扩展名的构建目标。
$ make foo.i
$ make foo.s
$ make foo.o
在包含 foo.c
和 foo.cpp
的构建系统中,构建 foo.i
目标将预处理这两个文件。
指定构建程序¶
由 --build
模式调用的程序由 CMAKE_MAKE_PROGRAM
变量确定。对于大多数生成器,不需要配置特定的程序。
生成器 |
默认 make 程序 |
备选方案 |
---|---|---|
XCode |
|
|
Unix Makefiles |
|
|
NMake Makefiles |
|
|
NMake Makefiles JOM |
|
|
MinGW Makefiles |
|
|
MSYS Makefiles |
|
|
Ninja |
|
|
Visual Studio |
|
|
Watcom WMake |
|
jom
工具能够读取 NMake
风格的 makefile 并并行构建,而 nmake
工具始终串行构建。在生成 NMake Makefiles
生成器后,用户可以运行 jom
而不是 nmake
。如果在使用 NMake Makefiles
生成器时将 CMAKE_MAKE_PROGRAM
设置为 jom
,则 --build
模式也会使用 jom
。为方便起见,提供了 NMake Makefiles JOM
生成器,用于正常方式查找 jom
并将其用作 CMAKE_MAKE_PROGRAM
。为了完整起见, nmake
是一个替代工具,可以处理 NMake Makefiles JOM
生成器的输出,但这样做会是一种性能的降低。
软件安装¶
可以通过在 CMake 缓存中设置 CMAKE_INSTALL_PREFIX
变量来指定安装提供软件的位置。如果提供的软件具有使用 install()
命令定义的安装规则,它们会将工件安装到该前缀中。在 Windows 上,默认安装位置对应于可能特定于体系结构的 ProgramFiles
系统目录。在 Unix 主机上,/usr/local
是默认安装位置。
CMAKE_INSTALL_PREFIX
变量始终指目标文件系统上的安装前缀。
在文件系统根目录只读或无论如何都应保持原始状态的交叉编译或打包场景中,可以设置 CMAKE_STAGING_PREFIX
变量到一个实际安装文件的位置。
命令:
$ cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \
-DCMAKE_SYSROOT=$HOME/root \
-DCMAKE_STAGING_PREFIX=/tmp/package
$ cmake --build .
$ cmake --build . --target install
将文件安装到主机机器上的路径,例如 /tmp/package/lib/libfoo.so
。对主机机器上的 /usr/local
位置没有影响。
某些提供的软件可能指定了 uninstall
规则,但 CMake 本身默认不生成此类规则。
运行测试¶
ctest(1)
工具随 CMake 分发版提供,用于执行提供的测试并报告结果。 test
构建目标用于运行所有可用测试,但 ctest(1)
工具允许对运行哪些测试、如何运行它们以及如何报告结果进行精细控制。在构建目录中执行 ctest(1)
等同于运行 test
目标。
$ ctest
可以传递正则表达式来仅运行匹配表达式的测试。例如,要仅运行名称中包含 Qt
的测试:
$ ctest -R Qt
也可以通过正则表达式排除测试。例如,要仅运行名称中不包含 Qt
的测试:
$ ctest -E Qt
可以通过传递 -j
参数给 ctest(1)
来并行运行测试:
$ ctest -R Qt -j8
可以另外设置环境变量 CTEST_PARALLEL_LEVEL
以避免需要传递 -j
。
默认情况下, ctest(1)
不会打印测试的输出。命令行参数 -V
(或 --verbose
)启用详细模式以打印所有测试的输出。 --output-on-failure
选项仅为失败的测试打印测试输出。可以另外将环境变量 CTEST_OUTPUT_ON_FAILURE
设置为 1
,以替代向 ctest(1)
传递 --output-on-failure
选项。