第 11 步:杂项功能

有些功能不适合或不够重要,无法在主教程中引起关注,但值得提及。这些练习收集了一些这些功能。它们应被视为“奖金”。

教程未涵盖许多 CMake 功能,其中一些功能被认为是使用它们的项目所必需的。其他功能则被打包者普遍使用,但软件开发人员在本地构建时很少讨论。

此列表并非对 CMake 剩余功能的详尽讨论。随着时间和相关性,它可能会增长或缩小。

练习 1:目标别名

本教程侧重于安装依赖项并从安装树中消耗它们。它还建议使用包管理器来促进此过程。然而,由于历史和当代各种原因,CMake 项目并不总是这样被消耗。

可以将在父项目中完全供应商依赖项的源代码,并使用 add_subdirectory() 进行消耗。执行此操作时,公开的目标名称是项目内部使用的名称,而不是通过 install(EXPORT) 导出的名称。目标名称将没有该命令添加到目标的前缀命名空间字符串。

一些项目希望通过与 find_package() 消费者呈现的接口一致的接口来支持此工作流。CMake 通过 add_library(ALIAS)add_executable(ALIAS) 支持此功能。

add_library(MyLib INTERFACE)
add_library(MyProject::MyLib ALIAS MyLib)

目标

MathFunctions 库添加一个库别名。

有用资源

要编辑的文件

  • TutorialProject/MathFunctions/CMakeLists.txt

开始

对于这一步,我们只编辑 Step11 文件夹中的 TutorialProject 项目。完成 TODO 1

构建并运行

要构建项目,我们首先需要配置和安装 SimpleTest。导航到 Help/guide/Step11/SimpleTest 并运行相应的命令。

cmake --preset tutorial
cmake --install build

然后导航到 Help/guide/Step11/TutorialProject 并执行常规构建。

cmake --preset tutorial
cmake --build build

添加别名后,行为应无明显变化。

解决方案

我们在 MathFunctions CML 中添加了一行。

TODO 1 点击显示/隐藏答案
TODO 1: TutorialProject/MathFunctions/CMakeLists.txt
add_library(Tutorial::MathFunctions ALIAS MathFunctions)

练习 2:生成器表达式

生成器 表达式 是 CMake 中某些上下文支持的复杂特定领域语言。它们最容易理解为延迟求值的条件,它们表达的需求,其确定正确行为的输入在 CMake 配置阶段是未知的。

注意

这就是生成器表达式得名的地方,它们在底层构建系统正在生成时进行评估。

生成器表达式通常与 target_include_directories() 结合使用,以表达跨构建和安装树的包含目录需求,但文件集已取代了此用例。它们现在最常见的应用是在多配置生成器和复杂的依赖注入系统中。

target_compile_definitions(MyApp PRIVATE "MYAPP_BUILD_CONFIG=$<CONFIG>")

目标

SimpleTest 添加一个生成器表达式,该表达式在编译定义中检查构建配置。

有用资源

要编辑的文件

  • SimpleTest/CMakeLists.txt

开始

对于这一步,我们只编辑 Step11 文件夹中的 SimpleTest 项目。完成 TODO 2

构建并运行

要构建项目,我们首先需要配置和安装 SimpleTest。导航到 Help/guide/Step11/SimpleTest 并运行相应的命令。

cmake --preset tutorial
cmake --install build

然后导航到 Help/guide/Step11/TutorialProject 并执行常规构建。

cmake --preset tutorial
cmake --build build

直接运行 TestMathFunctions 二进制文件时,我们应该看到一个命名用于构建可执行文件的构建配置的消息(不一定与用于配置 SimpleTest 的配置相同)。在单配置生成器上,可以通过设置 CMAKE_BUILD_TYPE 来更改构建配置。

解决方案

我们在 SimpleTest CML 中添加了一行。

TODO 2 点击显示/隐藏答案
TODO 2: SimpleTest/CMakeLists.txt
target_compile_definitions(SimpleTest INTERFACE "SIMPLETEST_CONFIG=$<CONFIG>")