CMake 用户交互指南 您所在的位置:网站首页 eclipse警告构建路径指定执行环境 CMake 用户交互指南

CMake 用户交互指南

2023-06-20 09:24| 来源: 网络整理| 查看: 265

1. 简介

通过CMake系列博文中的第一篇CMake快速入门,相信大家对于CMake已经有了一个感性的认识。本文在此基础上,主要介绍如何使用cmake交互程序完成构建任务。文章的内容主要翻译自User Interaction Guide,重点关注了针对Windows和Linux平台的内容,并增加了一些必要的解释。但需要说明的是,本人并没有完全实践原文中的所有内容,如有理解错误,欢迎指出和探讨。

CMake的本质是一个跨平台的构建系统生成器,它允许开发人员使用统一的语法来描述构建过程,并生成适用于各种平台和构建工具的构建系统。而使用CMake工具生成这个构建系统的过程称为配置过程。若我们使用了CMake文件(CMakeLists.txt)来管理软件源代码的构建,那么,为了完成最终的代码编译,我们就需要先运行CMake用户交互工具来启动配置过程以生成构建系统。这里生成的构建系统是特定于生成它的机器的,不可再分发,每个使用者都需要使用CMake工具来生成特定于其系统的构建系统。

生成的构建系统应该被视为只读的,并且CMake文件应该完全指定构建系统,不需要在IDE中手动填写属性。CMake会定期重写生成的构建系统,因此用户对已经生成的构建系统的修改将被覆盖。

因为CMake文件是标准的,并不会随着构建系统的不同而发生变化,所以本文描述的功能和用户界面对于所有基于CMake的构建系统都是可用的。但实际运行环境可能存在差异,因此,在实际处理提供的CMake文件时,CMake工具可能会向用户报告一些错误,例如报告编译器不支持,或编译器不支持CMake文件指定的编译选项,或找不到依赖项等。这些错误必须由用户通过选择不同的编译器、安装依赖项或指示CMake在哪里找到它们来解决。

1.1. 命令行cmake工具

假定有一份代码从未执行过编译,那么,使用cmake的一个简单但典型的用法如下:

cd some_software-1.4.2 mkdir build cd build cmake .. -DCMAKE_INSTALL_PREFIX=/opt/the/prefix cmake --build . cmake --build . --target install

在这个例子中,首先进入软件源代码目录,创建一个新的build目录,并在其中运行cmake命令执行配置过程。例子中使用-DCMAKE_INSTALL_PREFIX选项指定安装目录,然后使用--build选项编译和安装软件。如果看过第一篇博文,相信大家一定对这些命令都不陌生。

需要再次强调的是,建议在一个单独的目录中对源代码进行构建,因为这样可以使源目录保持原始状态,并且允许使用多个工具链构建同一份源文件,并允许通过删除构建目录轻松清除构建工件。

CMake工具可能会报告一些针对软件提供者的警告(而不是针对软件使用者的警告)。这样的警告以“此警告是针对项目开发人员的”结尾。用户可以通过将-wno-dev标志传递到cmake工具来禁用此类警告。

1.2. cmake-gui工具

更熟悉GUI界面的用户可以使用cmak-gui工具调用CMake并生成一个构建系统。

在GUI界面中,必须首先设置源目录和二进制目录。正如前面的建议,源文件和构建应该使用不同的目录。

cmake-gui

2. 生成一个构建系统

有几种用户交互工具可用于从CMake文件生成构建系统。cmake和cmak-gui工具通过设置各种必要选项指导用户。在命令行上,可以调用cmake工具来指定选项。本文描述了可以使用任何用户交互工具设置的选项,尽管每个工具设置选项的模式不同。

2.1. 命令行环境

当cmake用于基于命令行的构建系统(如Makefiles或Ninja)时,必须使用正确的构建环境来确保构建工具是可用的。CMake必须能够根据实际需要,找到适当的构建工具、编译器、链接器和其他工具。

在linux系统上,通常在系统范围内提供适当的工具,并且它们可以通过系统包管理器轻松安装。用户提供的或安装在非默认位置的其他工具链也可以被cmake使用。

当采用交叉编译时,一些平台可能要求设置环境变量,或者提供设置环境的脚本。

Visual Studio提供多个命令提示和vcvarsall.bat脚本,用于为命令行构建系统设置正确的环境。虽然在使用Visual Studio生成器时并不严格需要使用相应的命令行环境,但这样做并没有缺点。

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

2.2. 命令行-G选项

默认情况下,CMake根据平台自动选择一个生成器。通常,默认生成器足以允许用户完成构建。但用户还是可以使用-G选项覆盖默认的生成器,例如:

cmake .. -G Ninja

cmake --help可输出支持的生成器列表。注意,生成器名称区分大小写。

在类Unix的系统(包括MacOSX)上,默认情况下使用Unix Makefiles生成器。该生成器存在一些变体可在Windows的各种环境中使用,例如NMake Makefiles和MinGW Makefiles。这些生成器生成Makefile的变体,它们可以使用make、gmake、nmake或类似工具执行编译。有关目标环境和工具的更多信息,请参见各个生成器的文档。

Ninja生成器可在所有主流平台上使用。Ninja的用例与make类似,但它更注重性能和效率。

在Windows上,可以使用cmake为Visual Studio IDE生成解决方案。Visual Studio版本可以通过IDE的产品名称指定,其中包含四位数的年份。还可以使用其他方法来指定Visual Studio版本,例如与Visual C++编译器的产品版本相对应的两位数字,或是它与Visual Studio版本号的组合,如下所示:

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

一些IDE,如KDevelop4、QtCreator和CLion,都对基于CMake的构建系统提供了本地支持。这些IDE为选择要使用的底层生成器提供了用户接口,通常是在Makefile或基于Ninja的生成器之间进行选择。

注意,一旦完成CMake的配置过程后,我们无法再用-G选项来更改生成器。若要更换生成器,必须删除构建目录,然后重新构建。

在生成Visual Studio项目和解决方案文件时,还可以在最初运行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选项指定了_target_体系结构,但-T选项可以用于指定所使用的工具链的细节。例如,可以给出-Thost=x64来选择主机工具的64位版本。下面演示了如何使用64位工具,以及如何为64位目标体系结构进行构建:

cmake .. -G "Visual Studio 16 2019" -A x64 -Thost=x64 3. 设置构建变量(Setting Build Variables)

软件项目在配置过程中通常需要一些预设的变量,它们可以命令行上调用cmake时进行设置。下表列出了一些最常用的CMake变量:

变量含义CMAKE_PREFIX_PATH搜索依赖软件包的路径CMAKE_MODULE_PATH搜索额外的CMake模块的路径CMAKE_BUILD_TYPE构建配置,如Debug或Release,用于确定调试/优化标志。这仅与Makefile和Ninja等单一配置构建系统相关。多配置构建系统(如Visual Studio和Xcode)忽略此设置。CMAKE_INSTALL_PREFIX当构建install目标时,软件被安装的位置CMAKE_TOOLCHAIN_FILE包含交叉编译数据的文件,如toolchains和sysroot。BUILD_SHARED_LIBS若被启用,则当使用add_library()命令时构建动态库而非静态库CMAKE_EXPORT_COMPILE_COMMANDS生成一个compile_commands.json文件,用于基于clang的工具,以支持语言分析功能,例如自动补全,符号跳转等

除了以上列举的变量之外,还有其他特定于项目的变量可以用于控制生成,例如启用或禁用项目中的组件。

CMake没有为不同提供的构建系统关于如何命名这些变量提供约定,除了以CMAKE_为前缀的变量通常是指CMake本身提供的选项,不应该在第三方选项中使用,而第三方选项应该使用自己的前缀。cmak-gui工具可以根据前缀以组显示选项,因此第三方工具确保使用自洽前缀来定义变量是有意义的。

3.1. 在命令行上设置变量

我们可以在创建初始构建时,通过命令行设置CMake变量:

mkdir build cd build cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug

也可以在之后的cmake调用中设置变量:

cd build cmake .. -DCMAKE_BUILD_TYPE=Debug

还可以使用-U选项取消变量:

cd build cmake .. -UMyPackage_DIR

在命令行上创建的CMake构建系统可以使用cmak-gui进行编辑,反之亦然。

cmake工具允许使用-C选项来指定用于填充初始缓存的文件。这可以简化需要重复使用相同缓存条目的命令和脚本。

3.2. 使用cmake-gui来设置变量

可以使用“Add entry”按钮在cmak-gui中设置变量。这将触发一个新的对话框来设置变量的值。

使用cmake-gui来设置变量

cmake-gui用户界面的主视图可以用来编辑已有的变量。

3.3. CMake缓存

执行CMake时,它需要查找编译器、工具和依赖模块的位置。它还需要能够始终如一地、以使用相同的编译/链接标志和依赖关系的路径,重复生成构建系统。这些参数还必须是用户可配置的,因为它们是特定于用户系统的路径和选项。

当第一次执行配置时,CMake在构建目录中生成一个CMakeCache.txt文件,其中包含这些工件的键值对。用户可以通过运行cmak-gui或ccmake工具查看或编辑缓存文件。当我们编辑了缓存值后,需要重新配置所提供的源代码和重新生成构建系统,而这些工具为此提供了一个交互接口。每个缓存条目可以关联一个简短的帮助文本,用于显示在用户界面工具中。

缓存条目也有一个类型来表示它应该如何在用户接口中显示。例如,BOOL类型的缓存条目可以由用户界面中的复选框编辑,STRING可以在文本字段中编辑,FILEPATH(类似于STRING)还应该提供一种使用文件对话框定位文件系统路径的方法。类型字符串的条目可以提供值域的列表,然后在cmak-gui用户界面中的下拉菜单中展现这些值(详情请参阅STRING缓存属性)。

软件包内附带的CMake文件还可以使用option()命令定义布尔开关选项。该命令创建一个具有帮助文本和默认值的缓存条目。这些缓存条目通常特定于所提供的软件,并影响构建的配置,例如用于决定是否构建测试和示例,是否在启用异常的情况下进行构建等。

4. 预设配置(Presets)

CMakePresets.json文件及其特定于用户的对应文件CMakeUserPresets.json可用于保存常用的预设配置,它们会被CMake程序读取。这些预设配置可以设置构建目录、生成器、缓存变量、环境变量和其他命令行选项。所有这些选项都可以被用户覆盖。CMakePresets.json格式的全部细节列在cmake-presets手册中。

4.1. 在命令行中使用预置配置

当使用cmake命令行工具时,可以使用--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中可用的预设配置列表,但不生成构建树。

4.2. 在cmake-gui中使用预设配置

如果一个项目有可用的预设配置,无论是通过读取CMakePresets.json还是CMakeUserPresets.json,预置列表将出现在cmak-gui源目录和二进制目录之间的下拉菜单中。选择一个预设配置将自动设置二进制目录、生成器、环境变量和缓存变量,但所有这些选项都可以在选定预设配置后被重写。

5. 调用构建系统

生成构建系统后,可以通过调用特定的构建工具来构建软件。在IDE生成器的情况下,这可能涉及将生成的项目文件加载到IDE中以调用构建过程。

CMake知道调用构建所需的特定构建工具,因此,如果想在配置过程完成后,从命令行构建项目,可以在构建目录中调用以下命令:

cmake --build .

--build标志为cmake工具启用了特定的操作模式。它调用与生成器关联的CMAKE_MAKE_PROGRAM命令,或用户配置的构建工具。

--build模式还接受--target参数指定要构建的特定目标,例如特定库、可执行文件或自定义目标,或某些特殊目标(如install):

cmake --build . --target myexe

在使用支持多配置的生成器时,--build模式还接受一个--config参数,以指定要构建的特定配置:

cmake --build . --target myexe --config Release

但是,如果在调用cmake执行配置时指定了CMAKE_BUILD_TYPE变量,此时生成器生成的是特定与某个配置的构建系统,那么,--build模式就无法使用--config选项了。

有些构建系统省略了在构建过程中调用的命令行的细节。但如果我们关心这些细节,则可以使用--verbose标志来显示这些命令行:

cmake --build . --target myexe --verbose

--build模式还可以将特定的命令行选项传递给底层的构建工具,只需要在--之后列出需要传递的选项即可。这个功能在某些场景下非常好用,例如当cmake并没有提供用户交互手段的情况下,我们希望构建过程中出现的错误不要中止构建过程,就可以通过这种方式来直接配置底层的构建工具以使能该特性。

我们无论采用何种生成器,都可以在调用CMake之后直接运行底层构建工具。例如,可以在使用Unix Makefiles生成器完成配置过程之后,执行make以启动构建过程,或者在使用Ninja生成器完成配置之后执行ninja。IDE构建系统通常也为构建项目提供命令行工具,这些工具也可以被调用。

5.1. 选择构建目标

CMake文件中描述的每个可执行文件和库都是一个构建目标(build target),构建系统还可以描述一些自定义目标,可以用于内部使用;也可以被用户使用,例如用于创建文档。

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

all:这是Makefile和Ninja生成器使用的默认目标。它表示生成构建系统中的所有目标,但那些被其EXCLUDE_FROM_ALL目标属性或EXCLUDE_FROM_ALL目录属性指定的目标除外。对于Xcode和Visual Studio生成器,则使用ALL_BUILD目标完成相同的功能。help:列出可被构建的目标。当使用Unix Makefiles或Ninja生成器时,这个目标是可用的,并且输出是特定于工具的。clean:删除生成的对象文件和其他输出文件。基于Makefile的生成器为每个目录创建一个clean的目标,以便可以清除单个目录。Ninja工具提供了自己的细粒度-t clean系统。test:执行测试。只有当CMake文件提供基于CTest的测试时,此目标才会自动可用。参见运行测试install:安装当前软件。只有当软件使用install()命令定义安装规则时,此目标才会自动可用。另见软件安装。package:创建二进制包。只有当CMake文件提供基于CPack的包时,此目标才会自动可用。package_source:创建源代码包。只有当CMake文件提供基于CPack的包时,此目标才会自动可用。

对于基于Makefile的系统,CMake还提供了二进制构建目标的/fast变体。/fast变体用于构建指定的目标,而不考虑其依赖关系。因此,在构建过程中,CMake不检查依赖项,就算过期了也不重新生成依赖项。Ninja生成器的依赖检查足够快以至于并不需要这样的变体。

基于Makefile的系统还提供了特殊的构建目标(build-targets),用于预处理、组装和编译特定目录中的各个文件。

make foo.cpp.i make foo.cpp.s make foo.cpp.o

文件扩展名内置在目标的名称中,因为可能存在另一个同名但扩展名不同的文件。不过,也提供了不带文件扩展名的build-targets。

make foo.i make foo.s make foo.o

在包含foo.c和foo.cpp的构建系统中,构建foo.i目标将预处理这两个文件。

5.2. 指定构建程序

由--build模式调用的程序由CMAKE_MAKE_PROGRAM变量确定。对于大多数生成器,不需要配置特定的程序。

生成器默认的make程序备选Unix MakefilesmakeMinGW Makefilesmingw32-makeMSYS MakefilesmakeNinjaninjaVisual Studiomsbuild 6. 软件安装

可以在CMake缓存中设置CMAKE_INSTALL_PREFIX变量,以指定软件将要安装的位置。如果所提供的软件具有使用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位置不受影响。

有些软件可能会指定uninstall规则,但CMake本身并不会默认生成这样的规则。

7. 运行测试

ctest工具随CMake发行版一起提供,以执行CMake文件中指定的测试和报告结果。CMake提供了test构建目标来运行所有可用的测试,但是ctest工具允许对要运行的测试、如何运行测试和如何报告结果进行细粒度控制。在构建目录中执行ctest相当于运行test目标:

ctest

可以通过使用正则表达式来运行与之匹配的测试。例如,仅运行以Qt命名的测试,可以使用下列命令:

ctest -R Qt

正则表达式也可以用于排除匹配的测试。例如,只运行没有以Qt命名的测试:

ctest -E Qt

若想要并行运行测试,则可以使用-j选项,如下所示:

ctest -R Qt -j8

此外,还可以通过设置环境变量CTEST_PARALLEL_LEVEL来指定并行任务数,这样就不需要每次都指定-j选项。

默认情况下,ctest不打印来自测试的输出。命令行参数-V(或--verbose)将使能详细模式以打印来自所有测试的输出。--output-on-failure选项只打印失败测试的测试输出。可以将环境变量CTEST_OUTPUT_ON_FAILURE设置为1,以替代--output-on-failure选项。

8. 小结

本文介绍了如何使用CMake的用户交互工具以完成配置、编译、执行测试和安装。并且介绍了在完成这些任务时常用的命令行选项。

9. Reference User Interaction Guide


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有