CMakeLists.txt中FIND_PACKAGE()是如何工作的?

2023-05-16

官方文档:https://cmake.org/cmake/help/latest/command/find_package.html

FIND_PACKAGE(<PackageName>)如何查找头文件和库文件路径?
有两种模式:Module模式和Config模式。

1. Module模式

该模式通过寻找Find<PackageName>.cmake文件,由该文件找到对应的库以及路径。
Find<PackageName>.cmake文件负责查找包、检查版本、提供任何所需的消息。
查找Find<PackageName>.cmake文件有两种方式:

  1. 首先,通过CMAKE_MODULE_PATH变量指定的目录查找。
  2. 其次,在<cmake安装目录>/Modules文件夹内查找。
    ubuntu默认cmake安装在/usr/share/cmake-3.16目录。

如果没有找到对应的.cmake文件,则进入Config模式。如果指定了MODULE选项,则只在Module模式下寻找。

2. Config模式

该模式查找<PackageName>Config.cmake<lower-case-package-name>-config.cmake文件。cmake会创建<PackageName>_DIR 变量存储含有上述文件的路径。
如果.cmake文件未找到,会生成错误信息。
可以手动设置<PackageName>_DIR,如果对应的路径中没有.cmake文件,则会忽略该路径。

查找过程:

对于要查找的包,CMake生成一组可能的安装路径前缀<prefix>,对于每个<prefix>,将查找以下路径:

  • <prefix>/ (W)
  • <prefix>/(cmake|CMake)/ (W)
  • <prefix>/<name>*/ (W)
  • <prefix>/<name>*/(cmake|CMake)/ (W)
  • <prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/ (U)
  • <prefix>/(lib/<arch>|lib*|share)/<name>*/ (U)
  • <prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (U)
  • <prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/ (W/U)
  • <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/ (W/U)
  • <prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (W/U)
    其中W代表Windows系统,U代表UNIX系统。这只是惯例,实际上在Windows或UNIX系统上述所有路径都会搜索到。

关于如何生成<prefix>,官方文档给出了九条说明:
在这里插入图片描述

FIND_PACKAGE(OpenCV REQUIRED)命令如何找到OpenCV?

由第7条说明中的变量:CMAKE_SYSTEM_PREFIX_PATH,它包含以下路径:

  • /usr

根据第五条前缀查询规则:<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/,cmake查找到了这个路径:

  • /usr/lib/x86_64-linux-gnu/cmake/opencv4

这也就是变量OpenCV_DIR的值。而该路径中的OpenCVConfig.cmake文件中又有如下定义:

  1. 设置变量OpenCV_INSTALL_PATH值为当前路径向上四层,即/usr目录
  2. 设置变量OpenCV_INCLUDE_DIRS值为${OpenCV_INSTALL_PATH}/include/opencv4

因此,CMakeList.txt文件中的变量OpenCV_INCLUDE_DIRS的值为/usr/include/opencv4


同理,在CMakeList.txt文件中加入:

  • SET(OpenCV_DIR /opt/opencv4.5.0/lib/cmake/opencv4)

则CMake查找到/opt/opencv4.5.0/lib/cmake/opencv4路径下的OpenCVConfig.cmake文件,该文件定义:

  1. 设置变量OpenCV_INSTALL_PATH值为当前路径向上三层,即/opt/opencv4.5.0目录
  2. 设置变量OpenCV_INCLUDE_DIRS值为${OpenCV_INSTALL_PATH}/include/opencv4

因此此时变量OpenCV_INCLUDE_DIRS的值为/opt/opencv4.5.0/include/opencv4

到这里,CMake终于找到了系统中的OpenCV。

*注意:当你曾经成功运行FIND_PACKAGE(OpenCV REQUIRED)命令并找到了opencv的安装路径,CMake就会将该路径存入变量OpenCV_DIR中,如果不手动清空变量OpenCV_DIR,则该值可能一直存在并指向某个版本的OpenCV的安装位置,导致无法让CMake找到其他安装位置、其他版本的OpenCV,亦或使你的CMakeList.txt中的错误被掩盖。我使用的两个方法是:1. 删除build文件夹重新生成;2.使用Clion中Tools | CMake | Reset Cache and Reload Project功能

FIND_PACKAGE(OpenCV REQUIRED)命令如何找到Eigen?

Eigen3Config.cmake文件位置:/usr/lib/cmake/eigen3/Eigen3Config.cmake

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMakeLists.txt中FIND_PACKAGE()是如何工作的? 的相关文章

  • Unix 'find' + 'grep' 语法与 awk

    我使用这一行在我所在目录及其所有子目录的文件中查找短语 B206 find exec grep s B206 print 当它尝试读取某些文件并实际上将 putty 中的标题栏更改为一堆奇怪的字符时 它会崩溃 例如 当它遇到子目录中的 jp
  • 为什么我在mongodb中找不到_id的记录

    我试图通过 MongoID id 字段在 mongoDB 中查找记录 我找到了有关如何执行此操作的示例 但无法使其发挥作用 例子 recID 010101010101011 would be a valid mongodb id recID
  • “查找”或任何其他工具可以广度优先搜索文件吗?

    有时我知道某个文件并不那么深 但是非常密集的子目录不允许我轻松找到我想要的文件 Can find http www gnu org software findutils manual html mono find html 或任何其他工具
  • 跨包模块设置日志记录的有效方法

    我有一个包 其中包含多个组件 这些组件将从使用日志记录和输出有用信息中受益匪浅 我不想做的是为每个文件 设置 正确的日志记录 并在以下位置进行 import logging logging basicConfig level DEBUG m
  • 软件包“syncwave”/“mvcwt”不可用(对于 R 版本 3.0.2)[重复]

    这个问题在这里已经有答案了 我想安装软件包mvcwt and SynchWave但收到以下消息 Warning message package mvcwt is not available for R version 3 0 2 Warni
  • Java 包结构中的模块与层

    我曾经把所有东西都放在这样的包中 com company app module1 com company app module2 但它使得基于包的 AOP 切入点变得困难 并导致需要 IDE 才能理解的巨大包 所以现在我意识到我需要一个更深
  • 更新嵌入数据,例如 sysdata.rda

    我最近向 CRAN 提交的内容被退回了 因为我有一份关于全球环境的作业 但现在这已引起人们的不满 我有一个嵌入式数据集 sysdata rda 其中包含基于用户所在州 如美国 的配置参数 我希望当新用户使用该程序时可以更新此嵌入数据集 我之
  • 使用“npm install”的漏洞问题

    我已经使用安装了一个快速服务器express coserver命令 然后我使用 npm install 命令来安装其他节点包 依赖项 但我得到了这个结果 npm audit security report Manual Review Som
  • 创建 SSIS 包 - 将数据从 Oracle 复制到 SQL Server

    我想编写一个 SSIS 包 用于将数据从 Oracle 复制到 MS Sql 服务器 而且条件是 通过在 SQL 中选择一个表 就可以知道哪些数据必须从 oracle 移动到 SQL 基本上 如果 SQL Server 中的该表中没有该值
  • 如何在 log4j 中启用包级别日志记录

    谁能告诉我 log4j 中的包级别日志记录是什么 以及如何实现这一点 今天我的面试问题无法回答 即使我在谷歌中也没有找到好的解决方案 太感谢了 包级别日志记录是 log4j 的标准日志记录 使用 log4j 配置 您可以指定包和关联的级别
  • R - 安装插入符号包时出错

    gt Error in loadNamespace j lt i 1L c lib loc libPaths gt versionCheck vI j namespace pbkrtest 0 4 2 is being gt loaded
  • 管理 2 个以上具有依赖关系的 Nodejs 包的开发

    我正在开发 2 个 node js 包 每个包都在自己的 git 存储库中管理 包裹B取决于套餐A 所以我的本地目录结构如下所示 A1 B node modules A2 如果我更改本地代码A1 我想测试一下B在将其推送到公共存储库之前 我
  • 有没有办法使用 emacs 安装 R 包?

    我正在使用 ESS 但每次需要安装新软件包时 我都必须使用 R gui 有没有办法在不离开 emacs 的情况下做到这一点 From help Startup Example of Rprofile site local add MASS
  • Golang 中的“相互”包导入

    是否可以在 Golang 中执行 相互 包导入之类的操作 举例来说 我有两个包 A 和 B 分别具有 AFunc 和 BFunc BFunc2 函数 package A import B func AFunc do stuff but al
  • 将 pandas 数据框中的所有 inf、-inf 值替换为 NaN

    我有一个大型数据框 不同列中包含 inf inf 值 我想用 NaN 替换所有 inf inf 值 我可以逐栏这样做 所以这有效 df column name df column name replace np inf np nan 但我的
  • 选择性罐包装

    我有一个小program jar 它使用了巨大的library jar 的一小部分 有没有一种工具可以将多个 jar 重新打包成一个 以便它可以独立运行并且尽可能小 Update 大小事项 有proguard http proguard s
  • Python 包?

    好吧 我认为无论我做错了什么 它可能都是显而易见的 但我无法弄清楚 我已经阅读并重新阅读了有关包的教程部分 我唯一能想到的是这不起作用 因为我直接执行它 这是目录设置 eulerproject init py euler1 py euler
  • R 中的优化函数可以接受目标、梯度和粗麻布吗?

    我有一个想要优化的复杂目标函数 优化问题需要相当长的时间来优化 幸运的是 我确实有可用的函数的梯度和粗麻布 R 中是否有一个优化包可以接受所有这三个输入 optim 类不接受 Hessian 矩阵 我已经扫描了用于优化的 CRAN 任务页面
  • Emacs-Lisp:如何将emacs-lisp程序打包为PC应用程序?

    只是想知道是否可以将 emacs 和 Lisp 程序打包和部署为 PC 应用程序 这样一旦下载并运行 setup exe 某种程度 用户就可以启动应用程序以使 emacs 运行特定的 Lisp 程序 就像应用程序已实现一样通过其他语言和平台
  • 为 Linux 安装 R 包时出错

    我试图在 R 3 3 上安装一个名为 rgeos 的包 但是当我输入 install packages rgeos 但它返回给我以下错误 其他包也会发生同样的情况 但不是所有包 gt installing source package rg

随机推荐