CMake-深入理解find_package()的用法

前言:

CMake给我们提供了find_package()命令用来查找依赖包,理想情况下,一句find_package()命令就能把一整个依赖包的头文件包含路径、库路径、库名字、版本号等情况都获取到,后续只管用就好了。但实际使用过程可能会出现这样那样的问题,因此需要我们对find_package这个强大的命令有个大概的理解。

在进行find_package()探索之前,先熟悉一下我们使用源码安装第三方库的流程。

源码安装流程

以OpenCV 3.4.20 为例,源码安装的流程为:

mkdir build 
cd build 
cmake .. 
make -j8
sudo make install 

其中将cmake .. 更换成以下指令,然后 make install 就可以指定第三方库的安装位置。

cmake -DCMAKE_INSTALL_PREFIX=安装路径 .. 

 在build文件夹中make之后,生成的库文件都在build文件夹内,通过make install 命令又安装到了系统根目录下。因此在安装完库后,如果不删除源码,系统中将会有两个地方存着库的文件(根目录和build文件)。

下面来看一下,指定安装位置和不指定安装位置,库都安装在了哪里。

一般安装库文件后关于库的相关内容会存放在4个子文件夹中,bin、include、lib、share。 

<package_name>Config.cmake 文件的安装目录:

  1. 指定安装目录的情况下,<package_name>Config.cmake一般会存放在share文件夹下。
  2. 默认不指定安装目录的情况下, <package_name>Config.cmake可能会被安装在/usr/local/lib/cmake /usr/lib/cmake 目录下,具体取决于系统的配置和权限设置。
  3. 使用命令行安装的情况下, <package_name>Config.cmake一般会被安装在/usr/lib/x86_64-linux-gnu/cmake目录下

find_package命令搜包过程

find_package是为了得到这三个变量的值:<PackageName>_DIR<PackageName>_INCLUDE_DIRS<PackageName>_LIBS,这三个变量的值可以通过搜索Find<PackageName>.cmake或<PackageName>Config.cmake<lower-case-package-name>-config.cmake得到。

find_package命令有两种工作模式,这两种工作模式的不同决定了其搜包路径的不同:

1. Module模式

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

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

搜包路径依次为:

CMAKE_MODULE_PATH
CMAKE_ROOT

先在CMAKE_MODULE_PATH变量对应的路径中查找。如果路径为空,或者路径中查找失败,则在CMake安装目录(即CMAKE_ROOT变量)下的Modules目录下(通常为/usr/share/cmake-3.16/Modules,3.16是我的CMake版本)查找。

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

2. Config模式

find_package命令高级工作模式(Full Signature)。 只有在find_package()中指定CONFIG、NO_MODULE等关键字,或者Module模式查找失败后才会进入到Config模式。

Config模式下是要查找名为<PackageName>Config.cmake<lower-case-package-name>-config.cmake的模块文件。

搜包路径依次为:

1、<PackageName>_DIR

这个变量路径默认为空。
这个路径是非根目录路径,需要指定到<PackageName>Config.cmake<lower-case-package-name>-config.cmake文件所在目录才能找到。

2、CMAKE_PREFIX_PATH、CMAKE_FRAMEWORK_PATH、CMAKE_APPBUNDLE_PATH的CMake变量或环境变量路径根目录,默认都为空。
注意如果你电脑中安装了ROS并配置好之后,你在终端执行echo $CMAKE_PREFIX_PATH会发现ROS会将CMAKE_PREFIX_PATH这个变量设置为ROS中的库的路径,意思是会首先查找ROS安装的库,如果恰好你在ROS中安装了OpenCV库,就会发现首先找到的是ROS中的OpenCV,而不是你自己安装到系统中的OpenCV。

3、PATH环境变量路径
其实这个路径才是Config模式大部分情况下能够查找到安装到系统中各种库的原因。
这个路径的查找规则为:
遍历PATH环境变量中的各路径,如果该路径如果以bin或sbin结尾,则自动回退到上一级目录得到根目录。

$ echo $PATH 
/home/jq/.local/bin:/home/jq/bin:/opt/ros/noetic/bin:/home/jq/.local/bin:/home/jq/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/jq/.fishros/bin/

查找指定包建议

如果你明确知道想要查找的库<PackageName>Config.cmake<lower-case-package-name>-config.cmake文件所在路径,为了能够准确定位到这个包,可以直接设置变量<PackageName>_DIR为具体路径,如:

set(OpenCV_DIR "/usr/local/include/opencv-3.4.20/share/OpenCV")

参考:

“轻松搞定CMake”系列之find_package用法详解_/opt/ros/melodic/share/gazebo_dev/cmake/gazebo_dev-CSDN博客

  • 34
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jiqiang_z

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

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

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

打赏作者

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

抵扣说明:

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

余额充值