基本签名和模块模式¶
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])cs
查找并从外部项目加载设置。 <PackageName>_FOUND 将设置为指示是否找到该软件包。找到软件包后,将通过软件包本身记录的变量和“ imported target”提供特定于软件包的信息。该 QUIET选项禁用信息性消息,包括指示信息性消息的信息,如果未找到则无法找到REQUIRED。REQUIRED 如果找不到软件包,该选项将停止处理并显示一条错误消息。
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模式

模块模式
在模块模式下,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之后
关键字解释
version和EXACT: 都是可选的,version指定的是版本,如果指定就必须检查找到的包的版本是否和version兼容。如果指定EXACT则表示必须完全匹配的版本而不是兼容版本就可以。
QUIET 可选字段,表示如果查找失败,不会在屏幕进行输出(但是如果指定了REQUIRED字段,则QUIET无效,仍然会输出查找失败提示语)。
MODULE 可选字段。前面提到说“如果Module模式查找失败则回退到Config模式进行查找”,但是假如设定了MODULE选项,那么就只在Module模式查找,如果Module模式下查找失败并不回落到Config模式查找。
REQUIRED可选字段。表示一定要找到包,找不到的话就立即停掉整个cmake。而如果不指定REQUIRED则cmake会继续执行。
COMPONENTS,components:可选字段,表示查找的包中必须要找到的组件(components),如果有任何一个找不到就算失败,类似于REQUIRED,导致cmake停止执行。
OPTIONAL_COMPONENTS和components:可选的模块,找不到也不会让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_CONFIG以 TRUE直接CMake的第一搜索回落

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

被折叠的 条评论
为什么被折叠?



