【学习笔记】Mastering CMake (十九)—— 依赖使用指南

前言:

学习笔记,随时更新。如有谬误,欢迎指正。


说明:

  1. 红色字体为较为重要部分。
  2. 绿色字体为个人理解部分。

19 依赖使用指南

19.1 介绍

对于希望使用 CMake 来使用第三方二进制包的开发人员来说,有多种可能的最佳方式,这取决于 CMake 对第三方库的感知程度。

与软件包一起提供的 CMake 文件包含查找每个构建依赖项的说明。有些构建依赖项是可选的,因为如果缺少依赖项,使用不同的特性集构建可能会成功,而有些依赖项是必需的。 CMake 为每个依赖项搜索已知的位置,并且提供的软件可能会为 CMake 提供额外的提示或位置来查找每个依赖项。

如果 cmake 没有找到所需的依赖项,则用包含 NOTFOUND 值的项填充缓存。该值可以通过在命令行或 ccmakecmake-gui 工具中指定来替换。有关设置缓存项的更多信息,请参阅用户交互指南

19.2 提供配置文件包的库

第三方提供库二进制文件以供 CMake 使用的最方便的方法是提供配置文件包。这些包是与库一起发布的文本文件,指导 CMake 如何使用库二进制文件和相关的头文件、辅助工具和库提供的 CMake 宏。

配置文件通常可以在名称与 lib/cmake/<PackageName> 模式相匹配的目录中找到,尽管它们也可能在其他位置。 <PackageName> 对应于在 CMake 中使用 find_package 命令的代码,如 find_package(PackageName REQUIRED) 。

lib/cmake/<PackageName> 目录将包含一个名为 <PackageName>Config.cmake 或 <PackageName>-config.cmake 的文件。这是 CMake 包的入口点。一个单独的可选文件 <PackageName>ConfigVersion.cmake 也可能存在于该目录中。 CMake 使用该文件来确定第三方包的版本是否满足指定了版本约束的 find_package 命令的使用。使用 find_package 时指定版本是可选的,即使存在 ConfigVersion 文件。

如果找到 Config.cmake 文件并且满足可选指定的版本,则 CMake 的 find_package 命令确认了要找到的包,并且假定整个库包按照设计完成的。

可能有其他文件提供 CMake 宏或导入的目标供你使用。 CMake 对这些文件不强制任何命名约定。它们通过 CMake 的 include 命令与主配置文件相关联。

出于使用第三方二进制文件包的目的而调用 CMake (的前提条件是)需要 CMake 的 find_package 命令能成功地找到包。如果包的位置在 CMake 已知的目录中,则 find_package 调用应该会成功。CMake 已知的目录是特定于平台的。例如,使用标准系统包管理器安装在 Linux 上的包将自动在 /usr 前缀中寻找。类似地,安装在 Windows 上的Program Files 中的包也会自动被寻找。

不能自动找到的包位于 CMake 无法预测的位置,例如 /opt/mylib 或 $HOME/dev/prefix 。这是一种正常的情况, CMake 为用户提供了几种方法来指定在哪里找到这样的库。

CMAKE_PREFIX_PATH 变量可以在调用 CMake 时设置。它被当作搜索配置文件包的路径列表。安装在 /opt/somepackage 中的包通常会安装配置文件,如 /opt/somepackage/lib/cmake/somepackage/SomePackageConfig.cmake 。在这种情况下, /opt/somepackage 应该被添加到 CMAKE_PREFIX_PATH 中。

环境变量 CMAKE_PREFIX_PATH 也可以用前缀填充以搜索包。与 PATH 环境变量一样,这是一个列表,需要使用特定于平台的环境变量列表项分隔符(在 Unix 上是 : ,在 Windows 上是 ; )。

当需要指定多个前缀,或者当多个不同的包二进制文件在同一个前缀中可用时, CMAKE_PREFIX_PATH 变量为此提供了方便。包的路径也可以通过设置与 <PackageName>_DIR 匹配的变量来指定,比如 SomePackage_DIR 。注意,这不是一个前缀,而应该是一个包含配置风格的包文件的目录的完整路径,比如上面的例子中的 /opt/somepackage/lib/cmake/somepackage/ 。

19.3 从包中导入目标

提供配置文件包的第三方包也可能提供被导入目标。这些将在包含与包相关的特定于配置的文件路径的文件中指定,例如库的 Debug 和 Release 版本。

通常,第三方包文档会指出在对库成功执行 find_package 后可用的导入目标的名称。这些导入的目标器名称可以被 target_link_libraries 命令使用。

简单使用第三方库的完整示例如下:

cmake_minimum_required(VERSION 3.10)
project(MyExeProject VERSION 1.0.0)

find_package(SomePackage REQUIRED)
add_executable(MyExe main.cpp)
target_link_libraries(MyExe PRIVATE SomePrefix::LibName)

有关开发 CMake 构建系统的更多信息,请参见 CMake 构建系统

19.3.1 不提供配置文件包的库

如果 FindSomePackage.cmake 文件可用,则不提供配置文件包的第三方库仍然可以使用 find_package 命令找到。

这些模块文件包与配置文件包的不同之处在于:

  1. 它们不应该由第三方提供,除非可能以文档的形式提供。
  2. Find<PackageName>.cmake 文件的可用性并不代表二进制文件本身的可用性。
  3. CMake 不搜索 CMAKE_PREFIX_PATH 来查找 Find<PackageName>.cmake 文件。相反, CMake 在 CMAKE_MODULE_PATH 变量中搜索这些文件。用户通常在运行 CMake 时设置 CMAKE_MODULE_PATH ,并且 CMake 项目通常会附加到 CMAKE_MODULE_PATH 以允许使用本地模块文件包。
  4. 在第三方没有直接提供配置文件包的情况下,为了方便, CMake 为一些第三方包提供了 Find<PackageName>.cmake 文件。这些文件是 CMake 的维护负担,所以新的 Find 模块通常不会再添加到 CMake 中。第三方应该提供配置文件包,而不是依赖于 CMake 提供的查找模块。

模块文件包也可以提供导入的目标。找到这样一个包的完整示例如下:

cmake_minimum_required(VERSION 3.10)
project(MyExeProject VERSION 1.0.0)

find_package(PNG REQUIRED)

# 向 FindSomePackage.cmake 文件添加路径
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
find_package(SomePackage REQUIRED)

add_executable(MyExe main.cpp)
target_link_libraries(MyExe PRIVATE
    PNG::PNG
    SomePrefix::LibName
)

<PackageName>_ROOT 变量也作为使用模块文件包(如 FindSomePackage )的 find_package 的调用的前缀进行搜索。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值