第 11 步:杂项功能

有些功能在主教程中不便展开或重要性不足,但值得一提。这些练习收集了其中一些功能。它们应被视为“额外内容”。

CMake 有许多未被教程覆盖的功能,其中一些被认为是使用它们项目的核心。另一些则是打包者常用的,但在从事本地构建的软件开发者中讨论较少。

此列表并非对 CMake 剩余功能的详尽探讨。随着时间和需求的变化,它可能会增加或减少。

练习 1:目标别名 (Target Aliases)

本教程侧重于安装依赖项并从安装树中调用它们。它还建议使用包管理器来简化此过程。然而,由于各种历史和现实原因,CMake 项目并不总是以这种方式被使用。

可以将依赖项的源代码完全“供应商化”(vendor)到父项目中,并使用 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:生成器表达式 (Generator Expressions)

生成器表达式 是 CMake 中某些上下文中支持的一种复杂的特定领域语言。它们最容易被理解为延迟求值的条件语句,它们用于表达那些在 CMake 配置阶段无法确定输入条件的需求。

注意

这就是“生成器表达式”得名的由来——它们是在生成底层构建系统时进行求值的。

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

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>")