【问题标题】:How CMake finds packagesCMake 如何查找包
【发布时间】:2020-02-28 14:16:05
【问题描述】:

我有一个将 OpenCV 添加到项目中的 CMake。

我使用以下代码将 openCV 添加到项目中:

if (MSVC)
        file(TO_CMAKE_PATH $ENV{OPENCV_ROOT} OpenCV_DIR)
        IF(NOT OpenCV_DIR)
            MESSAGE( FATAL_ERROR "Please point the environment variable OpenCV_ROOT to the root directory of OpenCV installation. required openCv V 4.2.x as minimum")
        ENDIF()
        set(BUILD_SHARED_LIBS OFF)
        find_package(OpenCV 4.2.0 REQUIRED)
    else (MSVC)
        set(BUILD_SHARED_LIBS ON)
        find_package(OpenCV COMPONENTS core highgui imgproc imgcodecs videoio photo stitching flann ml features2d calib3d objdetect REQUIRED)
    endif(MSVC)

如果我没有定义 OpenCV_root 环境变量,CMake 将找不到 OpenCV,如果我定义它,我会收到以下警告:

CMake Warning (dev) at CMakeLists.txt:36 (find_package):
  Policy CMP0074 is not set: find_package uses <PackageName>_ROOT variables.
  Run "cmake --help-policy CMP0074" for policy details.  Use the cmake_policy
  command to set the policy and suppress this warning.

  Environment variable OpenCV_ROOT is set to:

    D:\local\opencv

  For compatibility, CMake is ignoring the variable.
This warning is for project developers.  Use -Wno-dev to suppress it.

如果我没有定义 openCV_root 环境变量,那么 CMake 应该如何找到 OpenCV?

同样的问题也适用于其他包(例如 boost,我得到了同样的警告),我们是否应该定义一个 env 变量?

如果我不定义环境变量,OpenCV 将如何找到包?

【问题讨论】:

  • 您是否阅读了find_package() 的文档?
  • @squareskittles:文档指出,find_package 使用 &lt;PackageName&gt;_ROOT 变量来发现包。提问者正是为此目的设置了这个变量……并得到了CMP0074 警告,即使对我来说,这看起来也很令人困惑。所以帖子里提出的问题很有道理。
  • @Tsyvarev 你是对的。那么问题是否变成了“为什么没有设置 CMP0074?”。 CMake 应该默认使用 NEW 行为,对吗?

标签: c++ opencv cmake


【解决方案1】:

CMP0074 政策的description 告诉我们:

在 CMake 3.12 及更高版本中,find_package(&lt;PackageName&gt;) 命令现在搜索由&lt;PackageName&gt;_ROOT CMake 变量和&lt;PackageName&gt;_ROOT 环境变量指定的前缀...此策略提供与尚未更新的项目的兼容性以避免使用@987654325 @ 变量用于其他目的。

也就是说,在您的项目中,您需要使用 OPENCV_ROOT 变量来直接 影响find_package(OpenCV) 行为以外的目的。

在较新的 CMake 中,此变量会自动使用:

# This sets CMP0074 to NEW.
cmake_minimum_required(VERSION 3.12) # Or bigger version
set(BUILD_SHARED_LIBS OFF)
# If `OPENCV_ROOT` variable is set, it will be used in the next call without a warning.
find_package(OpenCV 4.2.0 REQUIRED)

如果您希望您的项目为其他目的提供有关 OpenCV 安装的提示,请使用具有不同名称的变量。

# We want to support old CMake versions too!
cmake_minimum_required(VERSION 3.11) # Or lower version

# Use `OPENCV_INSTALL_PREFIX` environment variable for set `OpenCV_DIR`, which helps CMake to find OpenCV.
# This setting works for both new and old CMake versions.
file(TO_CMAKE_PATH $ENV{OPENCV_INSTALL_PREFIX} OpenCV_DIR)
IF(NOT OpenCV_DIR)
    MESSAGE( FATAL_ERROR "Please point the environment variable OPENCV_INSTALL_PREFIX to the root directory of OpenCV installation. required openCv V 4.2.x as minimum")
ENDIF()
set(BUILD_SHARED_LIBS OFF)
find_package(OpenCV 4.2.0 REQUIRED)

或者,您可以禁用 CMP0074 策略并使用 OPENCV_ROOT 变量来满足您的目的。但这是不推荐:

# 'find_package' won't use `_ROOT` variable. This suppress the corresponding warning. 
cmake_policy(SET CMP0074 OLD)
file(TO_CMAKE_PATH $ENV{OPENCV_ROOT} OpenCV_DIR)
IF(NOT OpenCV_DIR)
    MESSAGE( FATAL_ERROR "Please point the environment variable OpenCV_ROOT to the root directory of OpenCV installation. required openCv V 4.2.x as minimum")
ENDIF()
set(BUILD_SHARED_LIBS OFF)
find_package(OpenCV 4.2.0 REQUIRED)

【讨论】:

  • 这是否意味着要找到一个包,我们应该定义_root?我记得在旧版本中,我们会使用 opencv_dir 而对于 boost,我认为是 boost_root。
  • 设置变量&lt;packageName&gt;_ROOT 不是找到包的唯一方法。可以设置,例如,CMAKE_PREFIX_PATH 变量。设置&lt;packageName&gt;_DIR 变量也可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-08
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多