浅聊find_package命令的搜索模式(Search Modes)

发布于:2025-05-08 ⋅ 阅读:(17) ⋅ 点赞:(0)

在这里插入图片描述

背景

find_package应该算是我们使用最多的cmake命令了。但是它是如何找到上游库的.cmake文件的?
根据官方文档,整理下find_package涉及到的搜索模式。

搜索模式

find_package涉及到的搜索模式有两种:模块模式(Module mode)和配置模式(Config mode)。

模块模式

在此模式下,CMake搜索名为Find<PackageName>.cmake的文件,首先在CMAKE_MODULE_PATH中列出的位置查找,然后在CMake安装提供的查找模块(Find moduls)中查找。查找模块(Find moduls)的主要任务是确定软件包是否可用,设置<PackageName>_FOUND变量以反映这一点,并提供使用该软件包所需的任何变量、宏和导入目标。在上游库未提供配置文件包的情况下,查找模块非常有用。

Find.cmake 文件通常不是由上游库本身提供的。我们发现在安装CMake时,会一并安装一些上游库的查找模块(Find modules)

以Ubuntu上的CMake为例,在/usr/share/cmake-3.22/Modules目录下可以查看到CMake提供的查找模块(Find modules),仅列举部分文件。

FindALSA.cmake
FindBZip2.cmake
FindCUDA.cmake
FindCURL.cmake
FindGTK2.cmake
FindJPEG.cmake
FindLibXml2.cmake
FindOpenGL.cmake
FindOpenSSL.cmake
FindProtobuf.cmake
FindQt.cmake
FindRuby.cmake
FindSDL.cmake
FindSQLite3.cmake
FindVulkan.cmake
FindX11.cmake

由于这些查找模块(Find modules)是由CMake维护的,所以有可能会过时。

我们可以使用CMAKE_MODULE_PATH添加自定义的模块搜索路径。CMAKE_MODULE_PATH的值默认为空,其自定义搜索路径的优先级比默认模块搜索路径高。

配置模式(Config mode)

在此模式下,CMake搜索名为<lowercasePackageName>-config.cmake<PackageName>Config.cmake的文件。如果指定了版本详细信息,它还会查找<lowercasePackageName>-config-version.cmake<PackageName>ConfigVersion.cmake

配置和版本文件通常作为上游库安装文件的一部分,因此它们往往比查找模块(Find modules)更可靠。

配置模式(Config mode)会搜索指定目录下的.cmake文件。以Ubuntu系统为例,其搜索路径如下:

<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/
<prefix>/(lib/<arch>|lib*|share)/<name>*/
<prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/
<prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/

其中<prefix>可通过变量CMAKE_PREFIX_PATH设置。需要注意<name>不区分大小写,并且对应于指定的<PackageName>

以Ubuntu系统上安装的ITK(Insight Toolkit)库为例,我们可以找到ITKConfig.cmakeITKConfigVersion.cmake

$ dpkg -L libinsighttoolkit5-dev | grep -i cmake
/usr/lib/cmake
/usr/lib/cmake/ITK-5.2
/usr/lib/cmake/ITK-5.2/ITKConfig.cmake
/usr/lib/cmake/ITK-5.2/ITKConfigVersion.cmake
...

典型用法

find_package的典型用法如下,是基本签名(basic signature)的一个简化形式。

find_package(<PackageName> [<version>] [REQUIRED] [COMPONENTS <components>...])

在这种典型用法下,命令首先在模块模式下搜索。如果未找到相应的Find<PackageName>.cmake文件,则回退到配置模式继续搜索。

当然我们也可以通过显示设置MODULE或是CONFIG参数指定只使用模块模式或者配置模式。

find_package(<PackageName> [<version>] [CONFIG|MODULE] [REQUIRED] [COMPONENTS <components>...])

参考资料

  1. https://cmake.org/cmake/help/latest/command/find_package.html

网站公告

今日签到

点亮在社区的每一天
去签到