I'll be brief.
One important thing you should realize, is that, unlike GNU Makefile, CMake variables and environment variables are different. You seem to be mixing these terms in your question.
The find_package
doc is very precise about its search procedure. I believe if you read the entire thing, you can answer this question yourself.
It's not that I don't want to answer in detail. It's just that I can't explain more clearly than the doc itself.
Instead I'll just make some key points:
CMAKE_MODULE_PATH
is where CMake searches "Find Modules", that is, FindOpenCV.cmake
, if it exists, which does not in this world we live in, because of the next point.
Because the authors of OpenCV provide a "Config" file, there is no need for anyone to write a "Find Module". CMAKE_PREFIX_PATH
is where CMake searches in lots of find_xxx
APIs, including find_package
, as it will be able to find OpenCVConfig.cmake
, if you set the path correctly. But in your case, it's empty.
You've set the env var OpenCV_DIR
, which is precisely why everything works. According to the doc, this var helps find the package:
Config mode search attempts to locate a configuration file provided by
the package to be found. A cache entry called PackageName_DIR is
created to hold the directory containing the file. By default the
command searches for a package with the name PackageName. If the
NAMES option is given the names following it are used instead of
PackageName. The command searches for a file called
PackageNameConfig.cmake or lower-case-package-name-config.cmake
for each name specified. A replacement set of possible configuration
file names may be given using the CONFIGS option. The search procedure
is specified below. Once found, the configuration file is read and
processed by CMake. Since the file is provided by the package it
already knows the location of package contents. The full path to the
configuration file is stored in the cmake variable
_CONFIG.
Search paths specified in cmake-specific environment variables. These
are intended to be set in the user’s shell configuration, and
therefore use the host’s native path separator (; on Windows and : on
UNIX). This can be skipped if NO_CMAKE_ENVIRONMENT_PATH is passed or
by setting the CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH to FALSE:
PackageName_DIR
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
Edit:
Q: Why can CMake find OpenCV?
A: When find_package(OpenCV)
is invoked, cmake will try to find OpenCVConfig.cmake
from several locations. I've never bothered to remember the order of the locations (since I never have to).
It will look for:
- CMake variable
CMAKE_PREFIX_PATH
- Environment variable
CMAKE_PREFIX_PATH
- CMake variable
OpenCV_DIR
- Environment variable
OpenCV_DIR
- And a lot more...
Note: CMake variable is a semi-colon separated string, while environment variable on Unix systems is colon separated string.
From your description, it seems CMake finds OpenCV through option #4.
Note: Refer to the doc for more details since:
- There are a lot more locations cmake will try looking up
- There are small difference in these variables. (For instance they are controlled on/off by different
find_package
parameters, etc.)
Normally, one does not specify paths to find on a per-package basis. This is why CMAKE_PREFIX_PATH
(Option #1) is more often used. (If not set, it's empty by default)
Usually, it is set on the command line, like this:
cmake -D CMAKE_PREFIX_PATH="/install/path0;/install/path1/;...;/install/pathn/" .....
Then cmake will iterate each path separated by ;
.
However of course, per-package basis has its own value: to prevent using the wrong version if multiple versions are installed on your pc (I've seen too many issues with /usr
vs /usr/local/
), like this:
cmake -DOpenCV_DIR=/path/to/the/version/I/meant/to/use .....