CMake查找OpenCV等包的方式及环境变量配置疑问
First, let's address the warning you're seeing because it's directly tied to how CMake handles package root variables:
CMake Warning (dev) at CMakeLists.txt:36 (find_package):
Policy CMP0074 is not set: find_package uses_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 pops up because CMake 3.12 introduced policy CMP0074, which tells CMake to prioritize <PackageName>_ROOT environment/cache variables when running find_package. By default, this policy is unset (for backward compatibility), so CMake ignores your OpenCV_ROOT variable until you explicitly enable the policy.
1. How does CMake find OpenCV when OpenCV_ROOT is undefined?
When OpenCV_ROOT isn't set (and CMP0074 is either unset or disabled), CMake follows this standard lookup flow for find_package(OpenCV):
- CONFIG Mode (Preferred): CMake first looks for an
OpenCVConfig.cmakeoropencv-config.cmakefile. It searches these locations in order:- The
OpenCV_DIRcache variable (if set) - Paths listed in
CMAKE_PREFIX_PATH(environment or cache variable), checking subdirectories likelib/cmake/opencv4orshare/opencv/cmake - System default installation paths (e.g.,
/usr/lib/cmake/opencv4on Linux,C:\Program Files\OpenCV\cmakeon Windows) - Paths in
CMAKE_SYSTEM_PREFIX_PATH(system-level standard directories)
- The
- MODULE Mode (Fallback): If no config file is found, CMake uses the built-in
FindOpenCV.cmakemodule. This module checks for legacy environment variables (likeOPENCV_DIR), system library paths, and header locations to locate OpenCV.
2. Should you define environment variables for Boost and similar libraries?
It depends on your CMake version and project needs, but here's the best practice:
- For CMake 3.12+: Yes, use
<PackageName>_ROOT(e.g.,Boost_ROOT) environment variables. This is the official, standardized way to hint at package locations, and it works consistently across most modern CMake-supported libraries once you enableCMP0074. - For older CMake versions: Use library-specific environment variables (e.g.,
BOOST_ROOTfor Boost,OPENCV_DIRfor older OpenCV releases) sinceCMP0074isn't available. - General rule: If your project targets modern CMake versions, enabling
CMP0074and using<PackageName>_ROOTis cleaner and more consistent than relying on library-specific variables.
3. General package lookup logic when no root environment variable is set
For most libraries, CMake follows this universal flow when no <PackageName>_ROOT or library-specific variable is defined:
- Check cache variables: First, it looks for
<PackageName>_DIR(e.g.,Boost_DIR), which points directly to the directory containing the package's config file. - Search prefix paths: It scans paths in
CMAKE_PREFIX_PATHandCMAKE_SYSTEM_PREFIX_PATH, checking common subdirectories where packages install their config files (likelib/cmake/<PackageName>orshare/<PackageName>/cmake). - Fallback to module mode: If no config file is found, it uses the
Find<PackageName>.cmakemodule (if available). These modules have custom logic tailored to the library, often checking system library directories, header paths, or legacy environment variables.
Optimized CMake Code for Your OpenCV Setup
To fix the warning and simplify your code, enable CMP0074 to let CMake automatically use OpenCV_ROOT when it's set, while maintaining default lookup behavior when it's not:
# Enable policy CMP0074 to use <PackageName>_ROOT variables cmake_policy(SET CMP0074 NEW) if(MSVC) set(BUILD_SHARED_LIBS OFF) find_package(OpenCV 4.2.0 REQUIRED) else() set(BUILD_SHARED_LIBS ON) find_package(OpenCV COMPONENTS core highgui imgproc imgcodecs videoio photo stitching flann ml features2d calib3d objdetect REQUIRED) endif()
This eliminates the need to manually convert OPENCV_ROOT to OpenCV_DIR and resolves the warning you're seeing.
内容的提问来源于stack exchange,提问作者mans

