CMake find_package语法

1. find_package常用指令形式

该指令是用来搜索包,并将包头文件、库文件、包目录记录下来;

find_package常用形式为

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

其中

  • < PackageName > 包名,必填参数。注意大小写。
  • [version] 指定版本,可选参数。添加该参数后会检查找到的包的版本是否和version兼容。
  • [EXACT] 版本号必须匹配,可选参数。必须完全匹配的版本而不是兼容版本就可以。
  • [QUIET] 没找到包也没关系;可选参数
  • [REQUIRED] ,没找到包会停止CMake;可选参数,会覆盖掉 [QUIET] 参数,输出查找失败提示语。
  • [MODULE]:可选字段。CMake有两个包查找模式,指定查找模式为MODULE模式,只在MODULE查找。
  • [COMPONENTS],[components]:可选字段,表示查找的包中必须要找到的组件(components),如果有任何一个找不到,CMake停止执行。

2. find_package两种包查找模式

在第一章了解了find_package语法后,下面需要了解一下find_package的内部实现机制,了解find_packge是如何查找包的;
主要有两种包查找模式:MODUEL模式和CONFIG模式。

2.1 MODULE模式

MODULE模式为 命令基础工作模式(Basic Signature),也是默认工作模式。

2.1.1 Find< PackageName>.cmake文件

Module模式主要依赖于查找到名为Find.cmake的配置文件。在Find.cmake配置文件中会将以下几个CMake变量赋值:

<LibaryName>_FOUND # 是否找到对应包
<LibaryName>_INCLUDE_DIR or <LibaryName>_INCLUDES #将找到的包的头文件保存在变量中
<LibaryName>_LIBRARY or <LibaryName>_LIBRARIES #将找到的包的库文件保存在变量中

2.1.2 Find< PackageName>.cmake是什么

.cmake文件是什么?
.cmake 是给cmake执行用的,可认为是cmake的一种执行脚本
Find< PackageName>.cmake 是什么
cmake执行,用于查找包的脚本;执行完成后会赋值几个变量

<LibaryName>_FOUND # 是否找到对应包
<LibaryName>_INCLUDE_DIR or <LibaryName>_INCLUDES #将找到的包的头文件保存在变量中
<LibaryName>_LIBRARY or <LibaryName>_LIBRARIES #将找到的包的库文件保存在变量中

Find< PackageName>.cmake 哪里来?
1.CMake官方会内置一些常用的Find< PackageName>.cmake文件 方便用户使用。
2.别人做好的包一般会提供该文件(反正这个文件不是你作为包的使用者来写出来的)。

cmake官方为我们预定义的Find< PackageName>.cmake,存储在path_to_your_cmake/share/cmake-/Modules目录下。
可以直接使用指令查询CMake内置了哪些模块:
cmake --help-module-list | grep -E ^Find
·
下图是我电脑上存在的一些CMake
这是我的路径D:\Program Files (x86)\cmake\cmake-3.20.1-windows-x86_64\share\cmake-3.20\Modules
在这里插入图片描述

2.1.3 查找.cmake文件

前面介绍可知,基本上所有的Find< PackageName>.cmake均会在CMake安装路径下的Modules目录;因此Module模式在find_package肯定会从上述路径查找对应的.cmake文件。除此外我们还可以在CMakeLists.txt中设置CMAKE_MODULE_PATH变量,指定Find< PackageName>.cmake的查找路径。
只需记住find_package只有两个查找路径:CMAKE_MODULE_PATH和CMake安装路径下的Modules目录
对应CMakeLists.txt变量名为:

CMAKE_MODULE_PATH
CMAKE_ROOT

搜包路径次序依次为:

  1. 先在CMAKE_MODULE_PATH变量对应的路径中查找。
  2. 如果路径为空,或者路径中查找失败,则在CMake安装目录(即CMAKE_ROOT变量)下查找。

这两个变量可以在CMakeLists.txt文件中打印查看具体内容:

message(STATUS “CMAKE_MODULE_PATH = ${CMAKE_MODULE_PATH}”)
message(STATUS “CMAKE_ROOT = ${CMAKE_ROOT}”)

其中CMAKE_MODULE_PATH默认为空,可以利用set命令赋值。

2.2 CONFIG模式

如果MODULE模式下查找失败,一般情况下会自动转到Config模式进行包搜索;
config模式下,find_package的指令语法也更多:

find_package(<package> [version] [EXACT] [QUIET]
             [REQUIRED] [[COMPONENTS] [components...]]
             [CONFIG|NO_MODULE]
             [NO_POLICY_SCOPE]
             [NAMES name1 [name2 ...]]
             [CONFIGS config1 [config2 ...]]
             [HINTS path1 [path2 ... ]]
             [PATHS path1 [path2 ... ]]
             [PATH_SUFFIXES suffix1 [suffix2 ...]]
             [NO_DEFAULT_PATH]
             [NO_CMAKE_ENVIRONMENT_PATH]
             [NO_CMAKE_PATH]
             [NO_SYSTEM_ENVIRONMENT_PATH]
             [NO_CMAKE_PACKAGE_REGISTRY]
             [NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing.
             [NO_CMAKE_SYSTEM_PATH]
             [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
             [CMAKE_FIND_ROOT_PATH_BOTH |
              ONLY_CMAKE_FIND_ROOT_PATH |
              NO_CMAKE_FIND_ROOT_PATH])

Config模式是通过另外一种.cmake文件来进行查找依赖库的:
<LibraryName>Config.cmake或者< lower-case-package-name>-config.cmake
这个文件从哪里来?
安装第三方库时,会自动在系统目录生成一份,因此有时没有指定搜索路径时也可以正确引用包
有的包安装时会在cmake/XXXX/目录下生成上述文件,有的会直接将对应文件所在目录添加到环境变量PATH中,这两个都是find_package的搜索路径

2.1.3 查找.cmake文件

具体查找顺序为:
1、名为_DIR的CMake变量或环境变量路径;默认为空,非根目录:
必须要指定到Config.cmake或-config.cmake文件所在目。
2、名为CMAKE_PREFIX_PATH、CMAKE_FRAMEWORK_PATH、CMAKE_APPBUNDLE_PATH的CMake变量或环境变量路径;默认为空,根目录。
3、PATH环境变量路径;根目录;
这个路径的查找规则为:
遍历PATH环境变量中的各路径,如果该路径如果以bin或sbin结尾,则自动回退到上一级目录得到根目录。

根目录的查找规则:
CMake会首先检查根目录路径下是否有名为Config.cmake或-config.cmake的模块文件,如果没有,CMake会继续检查或匹配这些根目录下的以下路径

/(lib/|lib|share)/cmake//
/(lib/|lib|share)/
/
/(lib/|lib|share)/*/(cmake|CMake)/

其中为系统架构名,如Ubuntu下一般为:/usr/lib/x86_64-linux-gnu,整个(lib/|lib|share)为可选路径,例如OpenCV库而言会检查或匹配

  • < prefix>/OpenCV/
  • < prefix>/lib/x86_64-linux-gnu/OpenCV/
  • < prefix>/lib/share/OpenCV/
  • < prefix>/share/OpenCV/等路径;

name为包名,不区分大小写,*意思是包名后接一些版本后等字符也是合法的,如pcl-1.9也会被找到。

参考文章:
https://blog.csdn.net/zhanghm1995/article/details/105466372

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CoomCon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值