cmake之find_pakage(详细版)

本文介绍了CMake中find_package()函数的两种模式——模块模式和配置模式的区别,如何通过find_package()指定MODULE选项来限制搜索,以及各自的查找顺序和变量设置。重点讲解了如何在不同模式下处理版本匹配和组件查找。

基本签名和模块模式

find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
             [REQUIRED] [[COMPONENTS] [components...]]
             [OPTIONAL_COMPONENTS components...]
             [NO_POLICY_SCOPE])cs

查找并从外部项目加载设置。 <PackageName>_FOUND 将设置为指示是否找到该软件包。找到软件包后,将通过软件包本身记录的变量和“ imported target”提供特定于软件包的信息。该 QUIET选项禁用信息性消息,包括指示信息性消息的信息,如果未找到则无法找到REQUIREDREQUIRED 如果找不到软件包,该选项将停止处理并显示一条错误消息。

COMPONENTS选件后(或REQUIRED选件后,如果有的话)可以列出所需组件的特定于包装的列表 。后面可能会列出其他可选组件 OPTIONAL_COMPONENTS。可用组件及其对是否认为要查找包的影响由目标包定义。

[version]参数要求找到的软件包应与之兼容的版本(格式为major[.minor[.patch[.tweak]]])。该 EXACT选项要求版本完全匹配。如果未[version]对find-module内部的递归调用提供任何 和/或组件列表,则将从外部调用(包括的EXACT标志 [version])自动转发相应的参数。当前仅在逐个软件包的基础上提供版本支持

两种模式

该命令有两种搜索包的模式:“模块”模式和“配置”模式。上面的签名选择模块模式。如果未找到模块,该命令将退回到配置模式,如下所述。如果提供了此MODULE选项,则禁用此回退。

如何区分这两种模式

也就是说,只有这3种情况下才是Config模式:

find_package()中指定CONFIG关键字
find_package()中指定NO_MODULE关键字
find_package()中使用了不在"basic signature"(也就是Module模式下所有支持的配置)关键字
换句话说,只要我不指定"CONFIG",不指定“NO_MODULE",也不使用"full signature"中的关键字,那我就是在Module模式。排查find_package()的第一步,应当判断它是Module模式还是Config模式。


指定关键字MODULE指定只用module模式

img

模块模式

在模块模式下,CMake搜索名为的文件Find<PackageName>.cmake。首先在CMAKE_MODULE_PATH,然后在CMake安装提供的“ 查找模块”中。如果找到该文件,则由CMake读取和处理。它负责查找软件包,检查版本并生成任何需要的消息。某些查找模块仅提供有限的版本支持或不提供版本支持。检查模块文档

find_package( [version] [EXACT] [QUIET] [MODULE]

         [REQUIRED] [[COMPONENTS] [components...]]
         [OPTIONAL_COMPONENTS components...]
         [NO_POLICY_SCOPE])

查找模块

“查找模块”是Find<PackageName>.cmake要由find_package()为调用时的命令<PackageName>

查找模块的主要任务是确定系统上是否存在软件包,设置<PackageName>_FOUND变量以反映此问题,并提供使用该软件包所需的任何变量,宏和导入的目标。在上游库不提供配置文件包的情况下,查找模块很有用 。

传统方法是对所有内容使用变量,包括库和可执行文件:请参见下面的“ 标准变量名称”部分。这是CMake提供的大多数现有查找模块的功能。

更现代的方法是通过提供导入的target,使其行为尽可能像 配置文件包文件。这具有向消费者传播传递使用要求的优点。

无论哪种情况(甚至提供变量和导入的目标),find模块都应与具有相同名称的旧版本提供向后兼容性。

从文件或模块加载并运行CMake代码。

include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>]
                      [NO_POLICY_SCOPE])

从给定的文件加载并运行CMake代码。变量读写访问调用者的范围(动态作用域)。如果OPTIONAL 存在,则如果文件不存在,则不会引发任何错误。如果 RESULT_VARIABLE给出,则变量<var>将设置为已包含的完整文件名,或者NOTFOUND失败。

如果指定了模块而不是文件,<modulename>.cmake则首先搜索名称为的文件 CMAKE_MODULE_PATH,然后在CMake模块目录中。对此有一个例外:如果调用的文件include()位于CMake内置模块目录中,则首先搜索CMake内置模块目录,然后 CMAKE_MODULE_PATH之后

关键字解释

versionEXACT: 都是可选的,version指定的是版本,如果指定就必须检查找到的包的版本是否和version兼容。如果指定EXACT则表示必须完全匹配的版本而不是兼容版本就可以。

QUIET 可选字段,表示如果查找失败,不会在屏幕进行输出(但是如果指定了REQUIRED字段,则QUIET无效,仍然会输出查找失败提示语)。

MODULE 可选字段。前面提到说“如果Module模式查找失败则回退到Config模式进行查找”,但是假如设定了MODULE选项,那么就只在Module模式查找,如果Module模式下查找失败并不回落到Config模式查找。

REQUIRED可选字段。表示一定要找到包,找不到的话就立即停掉整个cmake。而如果不指定REQUIRED则cmake会继续执行。

COMPONENTScomponents:可选字段,表示查找的包中必须要找到的组件(components),如果有任何一个找不到就算失败,类似于REQUIRED,导致cmake停止执行。

OPTIONAL_COMPONENTScomponents:可选的模块,找不到也不会让cmake停止执

Module模式查找顺序

Module模式下是要查找到名为Find<PackageName>.cmake的文件。

先在CMAKE_MODULE_PATH变量对应的路径中查找。如果路径为空,或者路径中查找失败,则在cmake module directory(cmake安装时的Modules目录,比如/usr/local/share/cmake/Modules)查找。

配置模式

如果MODULE以上签名中未指定该选项,则CMake首先使用“模块”模式搜索软件包。然后,如果找不到该软件包,它将使用Config模式再次搜索。用户可以设置变量CMAKE_FIND_PACKAGE_PREFER_CONFIGTRUE直接CMake的第一搜索回落

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值