#cmake
#cmake
Вопрос:
Я новичок в cmake и в настоящее время изучаю find_package()
В режиме модуля CMake выполняет поиск файла с именем Find.cmake. Поиск файла сначала выполняется в CMAKE_MODULE_PATH, затем среди модулей поиска, предоставляемых установкой CMake. Если файл найден, он считывается и обрабатывается 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 ?
Спасибо!!
Ответ №1:
Я буду краток.
Одна важная вещь, которую вы должны понимать, заключается в том, что, в отличие от GNU Makefile, переменные CMake и переменные среды различны. Похоже, вы смешиваете эти термины в своем вопросе.
find_package
Документ очень точно описывает свою процедуру поиска. Я верю, что если вы прочтете все это целиком, то сможете сами ответить на этот вопрос.
Дело не в том, что я не хочу отвечать подробно. Просто я не могу объяснить это более ясно, чем сам документ.
Вместо этого я просто сделаю несколько ключевых моментов:
CMAKE_MODULE_PATH
где CMake выполняет поиск «Найти модули», то естьFindOpenCV.cmake
, если он существует, чего нет в этом мире, в котором мы живем, из-за следующего пункта.- Поскольку авторы OpenCV предоставляют файл «Config», никому не нужно писать «Модуль поиска».
CMAKE_PREFIX_PATH
это место, где CMake выполняет поиск во множествеfind_xxx
API, в том числеfind_package
, как он сможет найтиOpenCVConfig.cmake
, если вы правильно зададите путь. Но в вашем случае он пустой. - Вы установили переменную env
OpenCV_DIR
, и именно поэтому все работает. Согласно документу, этот параметр помогает найти пакет:
Поиск в режиме конфигурации пытается найти файл конфигурации, предоставленный пакетом, который нужно найти. Для хранения каталога, содержащего файл, создается запись кэша с именем PackageName_DIR. По умолчанию команда ищет пакет с именем PackageName . Если задан параметр NAMES, вместо PackageName используются следующие за ним имена. Команда выполняет поиск файла с именем PackageNameConfig.cmake или с именем пакета в нижнем регистре config.cmake для каждого указанного имени. С помощью опции CONFIGS можно задать набор возможных имен файлов конфигурации для замены. Процедура поиска указана ниже. После нахождения файл конфигурации считывается и обрабатывается CMake. Поскольку файл предоставляется пакетом, он уже знает расположение содержимого пакета. Полный путь к файлу конфигурации хранится в переменной cmake _CONFIG .
Пути поиска, указанные в переменных среды, специфичных для cmake. Они предназначены для установки в конфигурации оболочки пользователя и, следовательно, используют собственный разделитель пути хоста (; в Windows и : в 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?
Ответ: При find_package(OpenCV)
вызове cmake попытается найти OpenCVConfig.cmake
из нескольких местоположений. Я никогда не утруждал себя запоминанием порядка расположения объектов (поскольку мне никогда не приходилось этого делать).
Он будет искать:
- Переменная CMake
CMAKE_PREFIX_PATH
- Переменная среды
CMAKE_PREFIX_PATH
- Переменная CMake
OpenCV_DIR
- Переменная среды
OpenCV_DIR
- И многое другое…
Примечание: переменная CMake представляет собой строку, разделенную точкой с запятой, в то время как переменная среды в системах Unix представляет собой строку, разделенную двоеточием.
Из вашего описания кажется, что CMake находит OpenCV с помощью опции # 4.
Примечание: обратитесь к документу для получения более подробной информации, поскольку:
- Есть намного больше мест, которые cmake попытается найти
- В этих переменных есть небольшая разница. (Например, они управляются включением / выключением с помощью разных
find_package
параметров и т.д.)
Обычно пути для поиска для каждого пакета не указываются. Вот почему CMAKE_PREFIX_PATH
(вариант #1) используется чаще. (Если не задано, по умолчанию оно пустое)
Обычно он устанавливается в командной строке, например:
cmake -D CMAKE_PREFIX_PATH="/install/path0;/install/path1/;...;/install/pathn/" .....
Затем cmake будет повторять каждый путь, разделенный ;
.
Однако, конечно, для каждого пакета есть своя ценность: чтобы предотвратить использование неправильной версии, если на вашем ПК установлено несколько версий (я видел слишком много проблем с /usr
vs /usr/local/
), например:
cmake -DOpenCV_DIR=/path/to/the/version/I/meant/to/use .....
Комментарии:
1. «Но в вашем случае он пустой. (Поскольку существует файл «Config», никому не нужно писать «Find Module»)» , я не совсем понимаю это предложение, особенно «существует файл «Config»», что это значит? И из этого cmake.org/cmake/help/v3.0/variable/CMAKE_PREFIX_PATH.html , CMAKE_PREFIX_PATH , по — видимому , означает быть пустым по умолчанию .
2. @Pro_gram_mer Извините, плохая формулировка. Я должен был объяснить, почему в этом мире нет «FindOpenCV.cmake», что никак не связано с тем, почему CMAKE_PREFIX_PATH пуст. Я отредактирую через минуту.
3. Хорошо, еще один вопрос по этой ссылке: cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html в нем говорится, что по умолчанию CMAKE_MODULE_PATH пуст, это на самом деле меня смущает, оно установлено пустым, однако, когда я запускаю cmake и включаю режим отладки, cmake фактически ищет пакет, находя что-то в {Path, где я устанавливаю cmake}/Modules/FindOpenCV.cmake.
4. @Pro_gram_mer Отредактировал еще немного внизу.
5. @Pro_gram_mer Это в значительной степени подходит для вашего случая. Просто для ясности,
MODULE
mode ищетFindOpenCV.cmake
;Config
mode ищетOpenCVConfig.cmake
. Когда авторы библиотеки предоставляют файл конфигурации, пользователям библиотеки не нужно писатьFindOpenCV.cmake
.