【问题标题】:CMAKE_PREFIX_PATH and CMAKE_MODULE_PATH are both empty,find_package still worksCMAKE_PREFIX_PATH 和 CMAKE_MODULE_PATH 都是空的,find_package 仍然有效
【发布时间】:2021-05-09 10:23:16
【问题描述】:

我是 cmake 新手,目前正在学习 find_package()

来自doc : find_package

在模块模式下,CMake 会搜索一个名为 Find.cmake 的文件。该文件首先在 CMAKE_MODULE_PATH 中搜索,然后在 CMake 安装提供的 Find Modules 中搜索。如果找到该文件,则由 CMake 读取并处理该文件。它负责查找包、检查版本并生成任何需要的消息。一些查找模块对版本控制提供有限或不支持;检查模块文档。

例如,如果我输入 find_package(OpenCV) 并使用以下命令打开 cmake_find_debug_mode :

cmake -DCMAKE_FIND_DEBUG_MODE=ON .

而且,确实屏幕上的信息显示它首先尝试搜索{Path where I install cmake}/Modules/FindOpenCV.cmake,我认为但不确定是CMAKE_MODULE_PATH,但没有找到,它继续搜索,最后从OpenCVConfig.cmake我在一个脚本中定义的环境变量 OpenCV_DIR。

在我打印出消息之前我所期望的一切

message(STATUS "CMAKE_PREFIX_PATH : ${CMAKE_PREFIX_PATH}")
message(STATUS "CMAKE_MODULE_PATH : ${CMAKE_MODULE_PATH}")

doc 中的第一个定义为“用于 FIND_XXX() 搜索的路径,并添加了适当的后缀”。

而且他们都没有返回任何东西......

我有两个问题:

(1) 为什么find_package 甚至${CMAKE_MODULE_PATH} 是空的? (2) 如何查看cmake定义的所有这些环境变量,例如CMAKE_MODULE_PATH?

谢谢!!

【问题讨论】:

    标签: cmake


    【解决方案1】:

    我会很简短。

    您应该意识到的一件重要事情是,与 GNU Makefile 不同,CMake 变量和环境变量是不同的。您似乎在问题中混合了这些术语。

    find_package 文档对其搜索过程非常精确。我相信如果您阅读了全文,您可以自己回答这个问题。

    不是不想详细回答。只是我无法比文档本身更清楚地解释。

    我只是提出一些要点:

    • CMAKE_MODULE_PATH 是 CMake 搜索“查找模块”的位置,即 FindOpenCV.cmake,如果它存在,则在我们生活的这个世界上不存在,因为下一点。

    • 因为 OpenCV 的作者提供了一个“配置”文件,所以不需要任何人写一个“查找模块”。 CMAKE_PREFIX_PATH 是 CMake 在许多 find_xxx API 中搜索的地方,包括 find_package,因为如果您正确设置路径,它将能够找到 OpenCVConfig.cmake。但在你的情况下,它是空的。

    • 您已经设置了环境变量OpenCV_DIR,这正是一切正常的原因。根据文档,这个 var 有助于找到包:

    配置模式搜索尝试查找由 要找到的包。名为 PackageName_DIR 的缓存条目是 创建来保存包含该文件的目录。默认情况下 命令搜索名称为 PackageName 的包。如果 NAMES 选项被赋予它后面的名称,而不是 包裹名字。该命令搜索一个名为 PackageNameConfig.cmake 或小写包名-config.cmake 对于每个指定的名称。一组可能的配置替换 文件名可以使用 CONFIGS 选项给出。搜索过程 指定如下。找到后,读取配置文件并 由 CMake 处理。由于文件是由包提供的 已经知道包裹内容的位置。的完整路径 配置文件存储在 cmake 变量中 _配置。

    在 cmake 特定环境变量中指定的搜索路径。这些 旨在在用户的 shell 配置中设置,并且 因此使用主机的本地路径分隔符 (; 在 Windows 和 : on UNIX)。如果通过了 NO_CMAKE_ENVIRONMENT_PATH 或 通过将 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH 设置为 FALSE:

    PackageName_DIR

    CMAKE_PREFIX_PATH

    CMAKE_FRAMEWORK_PATH

    CMAKE_APPBUNDLE_PATH


    编辑:

    问:为什么 CMake 能找到 OpenCV?

    A:当find_package(OpenCV)被调用时,cmake会尝试从多个位置寻找OpenCVConfig.cmake。我从不费心去记住地点的顺序(因为我从来不需要)。

    它将寻找:

    1. CMake 变量CMAKE_PREFIX_PATH
    2. 环境变量CMAKE_PREFIX_PATH
    3. CMake 变量OpenCV_DIR
    4. 环境变量OpenCV_DIR
    5. 还有更多...

    注意:CMake 变量是 分号 分隔的字符串,而 Unix 系统上的环境变量是 冒号 分隔的字符串。

    根据您的描述,CMake 似乎通过选项 #4 找到了 OpenCV。

    注意:请参阅文档了解更多详细信息,因为:

    • cmake 将尝试查找更多位置
    • 这些变量有细微的差别。 (例如,它们由不同的find_package 参数等控制开/关)

    通常情况下,不会针对每个包指定要查找的路径。这就是为什么CMAKE_PREFIX_PATH(选项#1)更常用的原因。 (如果不设置,默认为空)

    通常是在命令行中设置的,像这样:

    cmake -D CMAKE_PREFIX_PATH="/install/path0;/install/path1/;...;/install/pathn/" .....
    

    然后 cmake 将迭代每个由; 分隔的路径。

    当然,每个包的基础有其自身的价值:如果您的电脑上安装了多个版本,以防止使用错误的版本(我已经看到太多/usr 与 /usr/local/ 的问题),像这样:

    cmake -DOpenCV_DIR=/path/to/the/version/I/meant/to/use .....
    

    【讨论】:

    • "但是在你的情况下,它是空的。(因为有一个“配置”文件,所以不需要任何人写一个“查找模块”)”,我不太明白这个句子,尤其是“存在一个“配置”文件”,这是什么意思?从这个cmake.org/cmake/help/v3.0/variable/CMAKE_PREFIX_PATH.html 来看,CMAKE_PREFIX_PATH 似乎意味着默认为空。
    • @Pro_gram_mer 抱歉,措辞不好。我的意思是解释为什么这个世界上没有“FindOpenCV.cmake”,与为什么 CMAKE_PREFIX_PATH 为空无关。我会在一分钟内编辑。
    • 好的,还有一个问题,来自这个链接:cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html 它说默认情况下 CMAKE_MODULE_PATH 是空的,这实际上让我感到困惑,它设置为空,但是,当我运行 cmake 并打开在调试模式下,cmake 实际上是通过在 {Path where I install cmake}/Modules/FindOpenCV.cmake 中查找某些内容来查找包。
    • @Pro_gram_mer 在底部编辑了更多内容。
    • @Pro_gram_mer 这就是你的情况。为了清楚起见,MODULE 模式寻找FindOpenCV.cmake; Config 模式查找 OpenCVConfig.cmake。当库 authors 提供配置文件时,库 users 无需编写FindOpenCV.cmake。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    • 2012-12-30
    • 2016-04-18
    • 1970-01-01
    • 2014-10-21
    • 2019-08-02
    • 1970-01-01
    相关资源
    最近更新 更多