用户交互指南

介绍

如果软件包为基于 CMake 的构建系统提供其软件源,则软件的消费者需要运行 CMake 用户交互工具才能构建它。

行为良好的基于​​ CMake 的构建系统不会在源目录中创建任何输出,因此通常,用户执行源外构建并在那里执行构建。首先,必须指示 CMake 生成合适的构建系统,然后用户调用构建工具来处理生成的构建系统。生成的构建系统特定于用于生成它的机器,并且不可再分发。所提供的源软件包的每个消费者都需要使用 CMake 来生成特定于其系统的构建系统。

生成的构建系统通常应被视为只读的。作为主要工件的 CMake 文件应该完全指定构建系统,并且没有理由在集成开发环境中手动填充属性,例如在生成构建系统之后。 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 工具可能会报告针对软件提供者而非软件消费者的警告。此类警告以“This warning is for project developers”结尾。用户可以通过将 -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 系统上,适当的工具通常在系统范围的位置提供,并且可以通过系统包管理器轻松安装。也可以使用用户提供的或安装在非默认位置的其他工具链。

交叉编译时,一些平台可能需要设置环境变量,或者可能会提供脚本来设置环境。

虚拟实验室附带多个命令提示符和“vcvarsall.bat”脚本,用于为命令行构建系统设置正确的环境。虽然在使用 Visual Studio 生成器时不一定非要使用相应的命令行环境,但这样做没有任何缺点。

使用 Xcode 时,可以安装多个 Xcode 版本。可以通过多种不同的方式选择使用哪一个,但最常见的方法是:

  • 在 开发环境的首选项中设置默认版本。

  • 通过“xcode-select”命令行工具设置默认版本。

  • 在运行 CMake 和构建工具时通过设置“DEVELOPER_DIR”环境变量覆盖默认版本。

为了方便起见, cmake-gui(1) 提供了一个环境变量编辑器。

命令行 -G 选项

CMake 默认根据平台选择一个生成器。通常,默认生成器足以让用户继续构建软件。

用户可以使用 -G 选项覆盖默认生成器:

$ cmake .. -G Ninja

cmake --help 的输出包括一个可供用户选择的 generators 列表。请注意,生成器名称区分大小写。

在类 Unix 系统(包括 Mac OS X)上,默认使用 Unix Makefiles 生成器。该生成器的变体也可以在 Windows 上的各种环境中使用,例如:generator:NMake Makefiles 和:generator:MinGW Makefiles 生成器。这些生成器生成一个 Makefile 变体,可以使用 makegmakenmake 或类似工具执行。有关目标环境和工具的更多信息,请参阅各个生成器文档。

Ninja 生成器可在所有主要平台上使用。 ninja 是一个在用例上类似于 make 的构建工具,但侧重于性能和效率。

在 Windows 上, cmake(1) 可用于为虚拟实验室集成开发环境生成解决方案。 Visual Studio 版本可以由集成开发环境的产品名称指定,其中包括一个四位数的年份。为有时引用虚拟实验室版本的其他方式提供了别名,例如对应于 VisualC++ 编译器产品版本的两个数字,或两者的组合:

$ cmake .. -G "Visual Studio 2019"
$ cmake .. -G "Visual Studio 16"
$ cmake .. -G "Visual Studio 16 2019"

虚拟实验室生成器可以针对不同的体系结构。可以使用 -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 生成器可用于为 开发环境生成项目文件。

一些集成开发环境,例如 KDevelop4、QtCreator 和 CLion 原生支持基于 CMake 的构建系统。这些集成开发环境提供了用于选择要使用的底层生成器的用户界面,通常是在基于“Makefile”或“Ninja”的生成器之间进行选择。

请注意,在第一次调用 CMake 后,无法使用 -G <cmake -G> 更改生成器。要更改生成器,必须删除构建目录并且必须从头开始构建。

在生成虚拟实验室项目和解决方案文件时,在最初运行 cmake(1) 时可以使用其他几个选项。

可以使用 cmake -T 选项指定虚拟实验室工具集:

$ # 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 选项指定了_target_ 体系结构,而 -T 选项可用于指定所用工具链的详细信息。例如,可以给出 -Thost=x64 来选择主机工具的 64 位版本。下面演示了如何使用 64 位工具以及如何构建 64 位目标架构:

$ cmake .. -G "Visual Studio 16 2019" -A x64 -Thost=x64

在 cmake-gui 中选择生成器

“配置”按钮触发一个新对话框以选择要使用的 CMake 生成器。

配置生成器

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

选择生成器

选择虚拟实验室生成器时,可以使用更多选项来设置要生成的体系结构。

为虚拟实验室生成器选择架构

设置构建变量

软件项目通常需要在调用 CMake 时在命令行上设置变量。下表列出了一些最常用的 CMake 变量:

变量

意义

CMAKE_PREFIX_PATH

搜索路径 依赖包

CMAKE_MODULE_PATH

搜索其他 CMake 模块的路径

CMAKE_BUILD_TYPE

构建配置,例如“调试”或“发布”,确定调试/优化标志。这仅与单配置构建系统相关,例如“Makefile”和“Ninja”。用于 Visual Studio 和 Xcode 的多配置构建系统会忽略此设置。

CMAKE_INSTALL_PREFIX

使用“install”构建目标安装软件的位置

CMAKE_TOOLCHAIN_FILE

包含交叉编译数据的文件,例如 toolchains sysroots

BUILD_SHARED_LIBS

是否为没有类型的 add_library() 命令构建共享库而不是静态库

CMAKE_EXPORT_COMPILE_COMMANDS

生成一个 compile_commands.json 文件以与基于 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(1) 工具允许使用 -C 选项指定用于填充初始缓存的文件。这对于简化重复需要相同缓存条目的命令和脚本很有用。

使用 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) 用户界面的下拉菜单中提供这些值(请参阅:prop_cache:`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/CMakeUsersPresets.json`` 中可用的预设,而不生成构建树。

在 cmake-gui 中使用预设

如果项目有可用的预设,无论是通过“CMakePresets.json”还是“CMakeUserPresets.json”,预设列表将出现在 cmake-gui(1) 之间的下拉菜单中源目录和二进制目录。选择预设设置二进制目录、生成器、环境变量和缓存变量,但在选择预设后可以覆盖所有这些选项。

调用构建系统

生成构建系统后,可以通过调用特定的构建工具来构建软件。对于集成开发环境生成器,这可能涉及将生成的项目文件加载到集成开发环境中以调用构建。

CMake 知道调用构建所需的特定构建工具,因此一般来说,要在生成后从命令行构建构建系统或项目,可以在构建目录中调用以下命令:

$ cmake --build .

--build 标志为 cmake(1) 工具启用特定的操作模式。它调用与 generator <cmake-generators(7)> 或用户配置的构建工具关联的 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 后运行底层构建工具。例如,make 可以在使用 Unix Makefiles 生成器生成后执行以调用构建,或者``ninja`` 在使用 Ninja 生成器等生成后执行。集成开发环境构建系统通常提供用于构建也可以调用的项目的命令行工具。

选择目标

CMake 文件中描述的每个可执行文件和库都是构建目标,构建系统可以描述自定义目标,供内部使用或供用户使用,例如创建文档。

CMake 为所有提供 CMake 文件的构建系统提供了一些内置目标。

全部

MakefileNinja 生成器使用的默认目标。构建构建系统中的所有目标,除了那些被它们的 EXCLUDE_FROM_ALL 目标属性或 EXCLUDE_FROM_ALL 目录属性排除的目标。名称“ALL_BUILD”用于 Xcode 和虚拟实验室生成器。

帮助

列出可用于构建的目标。使用 Unix MakefilesNinja 生成器时可以使用此目标,并且确切的输出是特定于工具的。

干净

删除构建的目标文件和其他输出文件。基于``Makefile`` 的生成器为每个目录创建一个``clean`` 目标,以便可以清理单个目录。 Ninja 工具提供了自己的粒度``-t clean`` 系统。

测试

运行测试。此目标仅在 CMake 文件提供基于 CTest 的测试时自动可用。另见`运行测试`_。

安装

安装软件。只有当软件使用 install() 命令定义安装规则时,此目标才会自动可用。另见`软件安装`_。

创建一个二进制包。只有当 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 变量决定。对于大多数生成器,不需要配置特定程序。

生成器

默认制作程序

备择方案

XCode

xcodebuild

Unix 生成文件

制作

NMake 生成文件

nmake

乔姆

NMake 生成文件 JOM

乔姆

nmake

MinGW 生成文件

mingw32-make

MSYS 生成文件

制作

忍者

忍者

视觉工作室

msbuild

沃通WMake

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_INSTALL_PREFIX 变量可以在 CMake 缓存中设置,以指定安装提供的软件的位置。如果提供的软件有安装规则,使用 install() 命令指定,它们会将工件安装到该前缀中。在 Windows 上,默认安装位置对应于可能特定于体系结构的“ProgramFiles”系统目录。在 Unix 主机上,/usr/local 是默认安装位置。

CMAKE_INSTALL_PREFIX 变量总是指目标文件系统上的安装前缀。

在 sysroot 为只读或 sysroot 应保持原始状态的交叉编译或打包场景中,可以将 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 位置不受影响。

某些提供的软件可能会指定“卸载”规则,但 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

也可以设置环境变量:envvar:CTEST_PARALLEL_LEVEL 以避免需要传递:option:-j <ctest -j>

默认情况下:manual:ctest(1) 不打印测试的输出。命令行参数:option:-V <ctest -V>`(或`--verbose``)启用详细模式以打印所有测试的输出。 --output-on-failure 选项仅打印失败测试的测试输出。环境变量 CTEST_OUTPUT_ON_FAILURE 可以设置为 1 作为将 --output-on-failure 选项传递给 :manual 的替代方法:ctest(1)