Как работает команда find_package() в cmake

Скажите, пожалуйста, как в cmake работает команда find_package()?

Мне не удалось найти исчерпывающего объяснения и понятных примеров, даже в официальной документации.

Например, если в проекте cmake вызывается команда find_package(), достаточно ли мне (на Linux) установить нужный пакет в систему? Или же мне нужно каким-то образом прицепить нужный пакет к проекту до вызова find_package()?


Ответы (1 шт):

Автор решения: Fat-Zer

Если не вдаваться в детали, то find_package(Package) просто ищет специальный cmake-файл, устанавливает несколько переменных и исполняет его аналогично include. Сей файл:

  • В «классическом» Module-варианте называется именем вида FindPackage.cmake. Набор таких файлов распространяется вместе с самим cmake (на *nix системах обычно лежат где-то в /usr/share/cmake/Modules), а также может быть в дистрибутиве собираемого проекта (в типовом варианте для этого CMAKE_MODULE_PATH присваивается каталог с оным).
  • В Config-варианте такой файл называется PackageConfig.cmake, или package-config.cmake и ищется в одном из местоположений, описанных в документации.

Строго говоря, от самого файла не требуется делать что-то конкретное или устанавливать какие-либо переменные. Единственное — в случае если пакет «найден», то он должен установить Package_FOUND в истинное значение.

Все прочие действия и переменные остаются на усмотрение авторов конкретных модулей. За подробностями стоит обращаться к их документации или самим скриптам. Обычно устанавливаются:

  • Package_VERSION
  • Package_INCLUDE_DIRECTORIES
  • Package_LIBRARIES

Обычно эти переменные являются кешированными (см. CACHE), так что по мере необходимости их можно переопределить из командной строки.

Подробности см. в документации cmake.

Например, если в проекте cmake вызывается команда find_package(), достаточно ли мне (на Linux) установить нужный пакет в систему? Или же мне нужно каким-то образом прицепить нужный пакет к проекту до вызова find_package()?

Обычно этого достаточно, подразумевая, что при этом также устанавливаются пакеты с заголовочными файлами и прочей мишурой для разработчиков (*-dev или *-devel пакеты).

Но т.к. всё это делается простым скриптом, то иногда он может не находить некоторые файлы т.к., например, они установлены в неожиданное для его автора место. В таких случаях обычно достаточно установить несколько входных и/или выходных переменных при запуске cmake, например, передав ему что-то вроде -DPackage_INCLUDE_DIR=/usr/include/package. Но конкретные значение крайне зависят от конкретных же модулей. Зачастую, когда возникают подобные ошибки, приходится обращаться к коду самих скриптов поиска, чтобы понять, где же их надо погладить.

→ Ссылка