CMAKE_PREFIX_PATH 和 CMAKE_MODULE_PATH 均为空,find_package 仍然有效

Pro*_*mer 6 cmake

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

来自文档:find_package

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

例如,如果我find_package(OpenCV)使用以下命令键入并运行 cmake_find_debug_mode:

cmake -DCMAKE_FIND_DEBUG_MODE=ON .
Run Code Online (Sandbox Code Playgroud)

而且,屏幕上打印的信息确实显示它首先尝试搜索{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}")
Run Code Online (Sandbox Code Playgroud)

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

他们俩都没有返回任何内容......

我有两个问题:

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

谢谢!!

Ter*_*sao 5

我会简短地说。

\n

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

\n

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

\n

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

\n

相反,我只会提出一些要点:

\n
    \n
  • CMAKE_MODULE_PATH是 CMake 搜索“查找模块”的地方,即 ,FindOpenCV.cmake如果它存在,但在我们生活的这个世界中不存在,因为下一点。

    \n
  • \n
  • 因为OpenCV的作者提供了一个“Config”文件,所以任何人都不需要编写“Find Module”。CMAKE_PREFIX_PATH是 CMake 搜索许多find_xxxAPI 的地方,包括,因为如果您设置正确的路径,find_package它将能够找到。OpenCVConfig.cmake但就你而言,它是空的。

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

    \n
  • \n
\n
\n

配置模式搜索尝试查找要查找的包提供的配置文件。\n 创建一个名为 PackageName_DIR 的缓存条目来保存包含该文件的目录。默认情况下,\n命令搜索名为 PackageName 的包。如果给出\nNAMES 选项,则使用其后面的名称而不是\nPackageName。该命令为每个指定的名称搜索名为\nPackageNameConfig.cmake 或 lower-case-package-name-config.cmake\n的文件。可以使用 CONFIGS 选项给出可能的配置\n文件名的替换集。下面指定了搜索过程。一旦找到,配置文件就会被 CMake 读取并\n处理。由于该文件是由包提供的,因此它已经知道包内容的位置。配置文件的完整路径存储在 cmake 变量_CONFIG 中。

\n
\n
\n

搜索特定于 cmake 的环境变量中指定的路径。这些\n旨在在用户\xe2\x80\x99s shell 配置中设置,因此\n使用主机\xe2\x80\x99s 本机路径分隔符(在 Windows 上为 ; 在 UNIX 上为 :)。如果传递 NO_CMAKE_ENVIRONMENT_PATH 或通过将 CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH 设置为 FALSE,则可以跳过此操作:

\n

包名_DIR

\n

CMAKE_PREFIX_PATH

\n

CMAKE_FRAMEWORK_PATH

\n

CMAKE_APPBUNDLE_PATH

\n
\n
\n

编辑:

\n

问:为什么CMake能找到OpenCV?

\n

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

\n

它将寻找:

\n
    \n
  1. CMake变量CMAKE_PREFIX_PATH
  2. \n
  3. 环境变量CMAKE_PREFIX_PATH
  4. \n
  5. CMake变量OpenCV_DIR
  6. \n
  7. 环境变量OpenCV_DIR
  8. \n
  9. 还有更多...
  10. \n
\n

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

\n

从你的描述来看,CMake 似乎通过选项 #4 找到了 OpenCV。

\n

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

\n
    \n
  • cmake 将尝试查找更多位置
  • \n
  • 这些变量之间存在微小差异。(例如通过不同的参数控制开/关find_package等)
  • \n
\n

通常,人们不会指定要在每个包的基础上查找的路径。这就是为什么CMAKE_PREFIX_PATH(选项#1)更常用的原因。(如果不设置则默认为空)

\n

通常,它是在命令行上设置的,如下所示:

\n
cmake -D CMAKE_PREFIX_PATH="/install/path0;/install/path1/;...;/install/pathn/" .....\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

然而,当然,每个软件包都有其自身的价值:如果您的电脑上安装了多个版本,则可以防止使用错误的版本(我已经看到了/usrvs的太多问题/usr/local/),如下所示:

\n
cmake -DOpenCV_DIR=/path/to/the/version/I/meant/to/use .....\n
Run Code Online (Sandbox Code Playgroud)\n

  • @Pro_gram_mer 这对于你的情况来说差不多了。需要明确的是,“MODULE”模式会查找“FindOpenCV.cmake”;“Config”模式查找“OpenCVConfig.cmake”。当库**作者**提供配置文件时,库**用户**无需编写“FindOpenCV.cmake”。 (2认同)