cmake-packages(7)
Введение
Пакеты предоставляют информацию о зависимостях для систем сборки CMake. Пакеты находятся с помощью команды find_package(). Результатом использования find_package является либо набор IMPORTED целей, либо набор переменных, соответствующих информации, относящейся к сборке.
Использование пакетов
CMake предоставляет прямую поддержку двух типов пакетов: пакеты с файлами конфигурации и пакеты с модулями поиска. Также поддерживается косвенная поддержка pkg-config пакетов через модуль FindPkgConfig. Во всех случаях базовая форма вызова find_package() одинакова:
find_package(Qt4 4.7.0 REQUIRED) # CMake provides a Qt4 find-module find_package(Qt5Core 5.1.0 REQUIRED) # Qt provides a Qt5 package config file. find_package(LibXml2 REQUIRED) # Use pkg-config via the LibXml2 find-module
В случаях, когда известно, что файл конфигурации пакета предоставляется upstream, и должен использоваться только он, можно передать ключевое слово CONFIG команде find_package():
find_package(Qt5Core 5.1.0 CONFIG REQUIRED) find_package(Qt5Gui 5.1.0 CONFIG)
Аналогично, ключевое слово MODULE указывает на использование только модуля поиска:
find_package(Qt4 4.7.0 MODULE REQUIRED)
Явное указание типа пакета улучшает сообщение об ошибке, отображаемое пользователю, если пакет не найден.
Оба типа пакетов также поддерживают указание компонентов пакета, либо после ключевого слова REQUIRED:
find_package(Qt5 5.1.0 CONFIG REQUIRED Widgets Xml Sql)
или как отдельный список COMPONENTS:
find_package(Qt5 5.1.0 COMPONENTS Widgets Xml Sql)
или как отдельный список OPTIONAL_COMPONENTS:
find_package(Qt5 5.1.0 COMPONENTS Widgets
OPTIONAL_COMPONENTS Xml Sql
)
Обработка COMPONENTS и OPTIONAL_COMPONENTS определяется пакетом.
Установкой переменной CMAKE_DISABLE_FIND_PACKAGE_<PackageName> в значение TRUE поиск пакета PackageName будет отключен, и он всегда будет NOTFOUND.
Пакеты с файлами конфигурации
Пакет с файлом конфигурации — это набор файлов, предоставляемых upstream для использования downstream. CMake ищет файлы конфигурации пакета в ряде расположений, как описано в документации к команде find_package(). Самый простой способ указать CMake искать пакет в нестандартном префиксе — установить переменную кэша CMAKE_PREFIX_PATH.
Пакеты с файлами конфигурации предоставляются поставщиками upstream в составе пакетов разработки, то есть они находятся вместе с заголовочными файлами и другими файлами, которые помогают downstream использовать пакет.
При использовании пакета с файлом конфигурации автоматически устанавливается набор переменных, которые предоставляют информацию о состоянии пакета. Переменная <Package>_FOUND устанавливается в true или false в зависимости от того, был ли найден пакет. Переменная кэша <Package>_DIR устанавливается в расположение файла конфигурации пакета.
Пакеты с модулями поиска
Модуль поиска — это файл с набором правил для поиска необходимых компонентов зависимости, в основном заголовочных файлов и библиотек. Обычно модуль поиска требуется, когда upstream не построен с помощью CMake или не достаточно осведомлён о CMake, чтобы предоставить файл конфигурации пакета другим способом. В отличие от файла конфигурации пакета, он не поставляется вместе с upstream, а используется downstream для поиска файлов, делая предположения о расположении файлов с помощью платформенно-специфических подсказок.
В отличие от случая с файлом конфигурации пакета, предоставляемого upstream, нет единой точки отсчёта, указывающей на обнаружение пакета, поэтому переменная <Package>_FOUND не устанавливается автоматически командой find_package(). Однако, по соглашению, она может быть установлена, и её должен установить автор модуля поиска. Аналогично, нет переменной <Package>_DIR, но каждый из артефактов, таких как расположения библиотек и заголовочных файлов, предоставляет отдельную переменную кэша.
См. руководство cmake-developer(7) для получения дополнительной информации о создании файлов модулей поиска.
Структура пакета
Пакет с файлом конфигурации состоит из файла конфигурации пакета и необязательно файла версии пакета, предоставляемых вместе с дистрибутивом проекта.
Файл конфигурации пакета
Представьте проект Foo, который устанавливает следующие файлы:
<prefix>/include/foo-1.2/foo.h <prefix>/lib/foo-1.2/libfoo.a
Он также может предоставить файл конфигурации пакета CMake:
<prefix>/lib/cmake/foo-1.2/FooConfig.cmake
с содержанием, определяющим IMPORTED цели или определяющим переменные, такие как:
# ...
# (compute PREFIX relative to file location)
# ...
set(Foo_INCLUDE_DIRS ${PREFIX}/include/foo-1.2)
set(Foo_LIBRARIES ${PREFIX}/lib/foo-1.2/libfoo.a)
Если другой проект хочет использовать Foo, ему достаточно найти файл FooConfig.cmake и загрузить его, чтобы получить всю необходимую информацию о расположениях содержимого пакета. Поскольку файл конфигурации пакета предоставляется установкой пакета, он уже знает все расположения файлов.
Команда find_package() может использоваться для поиска файла конфигурации пакета. Эта команда создаёт набор префиксов установки и ищет под каждым префиксом в нескольких местах. Учитывая имя Foo, она ищет файл с именем FooConfig.cmake или foo-config.cmake. Полный набор расположений указан в документации к команде find_package(). Одно из мест поиска —
<prefix>/lib/cmake/Foo*/
где Foo* — это выражение нечувствительное к регистру, использующее глоббинг. В нашем примере выражение глоббинга сопоставится с <prefix>/lib/cmake/foo-1.2 и файл конфигурации пакета будет найден.
После нахождения файл конфигурации пакета сразу же загружается. Он, вместе с файлом версии пакета, содержит всю необходимую информацию проекту для использования пакета.
Файл версии пакета
Когда команда find_package() находит файл конфигурации пакета, она ищет рядом с ним файл версии. Файл версии загружается для проверки, соответствует ли версия пакета запрошенной версии. Если файл версии заявляет о совместимости, файл конфигурации принимается. В противном случае он игнорируется.
Имя файла версии пакета должно соответствовать имени файла конфигурации пакета, но к имени добавлены -version или Version перед расширением .cmake. Например, файлы:
<prefix>/lib/cmake/foo-1.3/foo-config.cmake <prefix>/lib/cmake/foo-1.3/foo-config-version.cmake
и:
<prefix>/lib/cmake/bar-4.2/BarConfig.cmake <prefix>/lib/cmake/bar-4.2/BarConfigVersion.cmake
являются парами файлов конфигурации пакета и соответствующих файлов версии пакета.
При загрузке команды find_package() файла версии она сначала устанавливает следующие переменные:
-
PACKAGE_FIND_NAME - Имя <пакета>
-
PACKAGE_FIND_VERSION - Полная строка запрошенной версии
-
PACKAGE_FIND_VERSION_MAJOR - Главная версия, если запрошена, иначе 0
-
PACKAGE_FIND_VERSION_MINOR - Дополнительная версия, если запрошена, иначе 0
-
PACKAGE_FIND_VERSION_PATCH - Версия исправления, если запрошена, иначе 0
-
PACKAGE_FIND_VERSION_TWEAK - Версия доработки, если запрошена, иначе 0
-
PACKAGE_FIND_VERSION_COUNT - Количество компонентов версии, от 0 до 4
Файл версии должен использовать эти переменные для проверки совместимости или точного соответствия запрошенной версии и установить следующие переменные с результатами:
-
PACKAGE_VERSION - Полная строка предоставленной версии
-
PACKAGE_VERSION_EXACT - True, если версия является точным совпадением
-
PACKAGE_VERSION_COMPATIBLE - True, если версия совместима
-
PACKAGE_VERSION_UNSUITABLE - True, если не подходит ни для какой версии
Файлы версии загружаются вложенным образом, поэтому они могут свободно устанавливать любые переменные, которые им нужны, как часть своего вычисления. Команда find_package очищает область видимости, когда файл версии завершил работу и проверил переменные вывода. Когда файл версии заявляет, что является приемлемым совпадением для запрошенной версии, команда find_package устанавливает следующие переменные для использования проектом:
-
<package>_VERSION - Полная предоставленная строка версии
-
<package>_VERSION_MAJOR - Основная версия, если указана, иначе 0
-
<package>_VERSION_MINOR - Вспомогательная версия, если указана, иначе 0
-
<package>_VERSION_PATCH - Версия исправления, если указана, иначе 0
-
<package>_VERSION_TWEAK - Версия доработки, если указана, иначе 0
-
<package>_VERSION_COUNT - Количество компонентов версии, от 0 до 4
Переменные сообщают о версии пакета, который был фактически найден. Часть их имени <package>, соответствующая аргументу, заданному команде find_package().
Создание пакетов
Обычно, upstream зависит от самого CMake и может использовать некоторые возможности CMake для создания файлов пакета. Рассмотрим upstream, который предоставляет единственную общую библиотеку:
project(UpstreamLib)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
set(Upstream_VERSION 3.4.1)
include(GenerateExportHeader)
add_library(ClimbingStats SHARED climbingstats.cpp)
generate_export_header(ClimbingStats)
set_property(TARGET ClimbingStats PROPERTY VERSION ${Upstream_VERSION})
set_property(TARGET ClimbingStats PROPERTY SOVERSION 3)
set_property(TARGET ClimbingStats PROPERTY
INTERFACE_ClimbingStats_MAJOR_VERSION 3)
set_property(TARGET ClimbingStats APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING ClimbingStats_MAJOR_VERSION
)
install(TARGETS ClimbingStats EXPORT ClimbingStatsTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
install(
FILES
climbingstats.h
"${CMAKE_CURRENT_BINARY_DIR}/climbingstats_export.h"
DESTINATION
include
COMPONENT
Devel
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
VERSION ${Upstream_VERSION}
COMPATIBILITY AnyNewerVersion
)
export(EXPORT ClimbingStatsTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsTargets.cmake"
NAMESPACE Upstream::
)
configure_file(cmake/ClimbingStatsConfig.cmake
"${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfig.cmake"
COPYONLY
)
set(ConfigPackageLocation lib/cmake/ClimbingStats)
install(EXPORT ClimbingStatsTargets
FILE
ClimbingStatsTargets.cmake
NAMESPACE
Upstream::
DESTINATION
${ConfigPackageLocation}
)
install(
FILES
cmake/ClimbingStatsConfig.cmake
"${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
DESTINATION
${ConfigPackageLocation}
COMPONENT
Devel
)
Модуль CMakePackageConfigHelpers предоставляет макрос для создания простого файла ConfigVersion.cmake. Этот файл устанавливает версию пакета. Он читается CMake при вызове find_package() для определения совместимости с запрошенной версией и для установки некоторых переменных, специфичных для версии <Package>_VERSION, <Package>_VERSION_MAJOR, <Package>_VERSION_MINOR и т.д. Команда install(EXPORT) используется для экспорта целевых элементов в наборе экспорта ClimbingStatsTargets, определённом ранее командой install(TARGETS). Эта команда генерирует файл ClimbingStatsTargets.cmake, содержащий целевые элементы IMPORTED, пригодные для использования downstream, и организует его установку в lib/cmake/ClimbingStats. Сгенерированные файлы ClimbingStatsConfigVersion.cmake и cmake/ClimbingStatsConfig.cmake устанавливаются в то же местоположение, завершая создание пакета.
У сгенерированных целевых элементов IMPORTED установлены соответствующие свойства для определения их требований к использованию, таких как INTERFACE_INCLUDE_DIRECTORIES, INTERFACE_COMPILE_DEFINITIONS и другие соответствующие встроенные INTERFACE_ свойства. Вариант INTERFACE пользовательских свойств, перечисленных в COMPATIBLE_INTERFACE_STRING и другие Свойства совместимого интерфейса также распространяются на сгенерированные целевые элементы IMPORTED. В приведенном выше случае, ClimbingStats_MAJOR_VERSION определен как строка, которая должна быть совместима среди зависимостей любого потребителя. Установив это пользовательское свойство в этой версии и в следующей версии ClimbingStats, cmake(1) выдаст диагностическое сообщение, если будет попытка использовать версию 3 вместе с версией 4. Пакеты могут выбрать использование такой схемы, если разные основные версии пакета предназначены для несовместимости.
Для экспорта целевых элементов для установки используется NAMESPACE с двойными двоеточиями. Эта конвенция с двойными двоеточиями дает CMake подсказку, что имя — целевой элемент IMPORTED, когда он используется downstream с командой target_link_libraries(). Таким образом, CMake может выдать диагностическое сообщение, если пакет, который его предоставляет, ещё не найден.
В этом случае при использовании install(TARGETS) был указан INCLUDES DESTINATION. Это приводит к тому, что целевые элементы IMPORTED заполняют свой INTERFACE_INCLUDE_DIRECTORIES каталогом include в CMAKE_INSTALL_PREFIX. Когда целевой элемент IMPORTED используется downstream, он автоматически потребляет записи из этого свойства.
Создание файла конфигурации пакета
В этом случае файл ClimbingStatsConfig.cmake мог бы быть таким простым:
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
Так как это позволяет downstream использовать целевые элементы IMPORTED. Если какие-либо макросы должны предоставляться пакетом ClimbingStats, они должны быть в отдельном файле, который устанавливается в том же месте, что и файл ClimbingStatsConfig.cmake, и включаться оттуда.
Это также можно расширить для обработки зависимостей:
# ... add_library(ClimbingStats SHARED climbingstats.cpp) generate_export_header(ClimbingStats) find_package(Stats 2.6.4 REQUIRED) target_link_libraries(ClimbingStats PUBLIC Stats::Types)
Поскольку целевой элемент Stats::Types является PUBLIC зависимостью от ClimbingStats, downstream также должен найти пакет Stats и подключиться к библиотеке Stats::Types. Пакет Stats должен быть найден в файле ClimbingStatsConfig.cmake для обеспечения этого. Макрос find_dependency из модуля CMakeFindDependencyMacro помогает в этом, распространяя информацию о том, является ли пакет REQUIRED, или QUIET и т.д. Все REQUIRED зависимости пакета должны быть найдены в файле Config.cmake:
include(CMakeFindDependencyMacro)
find_dependency(Stats 2.6.4)
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")
Макрос find_dependency также устанавливает ClimbingStats_FOUND в False если зависимость не найдена, вместе с диагностикой, что пакет ClimbingStats не может использоваться без пакета Stats.
Если COMPONENTS указаны, когда downstream использует find_package(), они перечислены в переменной <Package>_FIND_COMPONENTS. Если конкретный компонент является необязательным, то <Package>_FIND_REQUIRED_<comp> будет истинным. Это может быть проверено с помощью логики в файле конфигурации пакета:
include(CMakeFindDependencyMacro)
find_dependency(Stats 2.6.4)
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")
set(_supported_components Plot Table)
foreach(_comp ${ClimbingStats_FIND_COMPONENTS})
if (NOT ";${_supported_components};" MATCHES _comp)
set(ClimbingStats_FOUND False)
set(ClimbingStats_NOTFOUND_MESSAGE "Unsupported component: ${_comp}")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake")
endforeach()
Здесь ClimbingStats_NOTFOUND_MESSAGE устанавливается в диагностику, что пакет не был найден из-за указания недействительного компонента. Это переменная сообщения может быть установлена для любого случая, когда переменная _FOUND устанавливается в False, и будет отображена пользователю.
Создание файла конфигурации пакета для дерева сборки
Команда export(EXPORT) создаёт файл определения целевых элементов IMPORTED, специфичный для дерева сборки, и непереносимый. Это аналогично может быть использовано с подходящим файлом конфигурации пакета и файлом версии пакета для определения пакета для дерева сборки, который может использоваться без установки. Потребители дерева сборки могут просто убедиться, что CMAKE_PREFIX_PATH содержит каталог сборки, или установить ClimbingStats_DIR в <build_dir>/ClimbingStats в кэше.
Создание переносимых пакетов
Переносимый пакет не должен ссылаться на абсолютные пути к файлам на машине, где пакет построен, которые не будут существовать на машинах, куда пакет может быть установлен.
Пакеты, созданные командой install(EXPORT), предназначены для переносимости, используя пути, относительные к месту расположения самого пакета. При определении интерфейса целевого элемента для EXPORT, имейте в виду, что каталоги включаемых файлов должны быть указаны как относительные пути, относительные к CMAKE_INSTALL_PREFIX:
target_include_directories(tgt INTERFACE
# Wrong, not relocatable:
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/TgtName>
)
target_include_directories(tgt INTERFACE
# Ok, relocatable:
$<INSTALL_INTERFACE:include/TgtName>
)
$<INSTALL_PREFIX> generator expression может быть использован в качестве заглушки для префикса установки без создания непереносимого пакета. Это необходимо, если используются сложные выражения генератора:
target_include_directories(tgt INTERFACE # Ok, relocatable: $<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>> )END_OF_DOCUMENT_MARKER
Это также относится к путям, ссылающимся на внешние зависимости. Не рекомендуется заполнять какие-либо свойства, которые могут содержать пути, такие как INTERFACE_INCLUDE_DIRECTORIES и INTERFACE_LINK_LIBRARIES, путями, относящимися к зависимостям. Например, этот код может не работать должным образом для переносимого пакета:
target_link_libraries(ClimbingStats INTERFACE
${Foo_LIBRARIES} ${Bar_LIBRARIES}
)
target_include_directories(ClimbingStats INTERFACE
"$<INSTALL_INTERFACE:${Foo_INCLUDE_DIRS};${Bar_INCLUDE_DIRS}>"
)
Ссылка на переменные может содержать абсолютные пути к библиотекам и каталогам включения в соответствии с машинным оборудованием, на котором был создан пакет. Это создаст пакет с жёстко закодированными путями к зависимостям, что не подходит для переноса.
В идеале такие зависимости должны использоваться через собственные импортированные цели, которые имеют свои IMPORTED_LOCATION и свойства, относящиеся к требованиям использования, такие как INTERFACE_INCLUDE_DIRECTORIES, заполненные должным образом. Эти импортированные цели затем могут быть использованы с командой target_link_libraries() для ClimbingStats.
target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar)
При таком подходе пакет ссылается на внешние зависимости только по именам импортированных целей. Когда пользователь использует установленный пакет, пользователь выполнит соответствующие команды find_package() (через макрос find_dependency описанный выше), чтобы найти зависимости и заполнить импортированные цели соответствующими путями на своей собственной машине.
К сожалению, многие modules, поставляемые с CMake, пока не предоставляют импортированные цели, поскольку их разработка предшествовала этому подходу. Это может постепенно улучшаться со временем. Решения для создания переносимых пакетов, использующих такие модули, включают:
- При сборке пакета укажите каждую запись кэша
Foo_LIBRARYкак просто имя библиотеки, например,-DFoo_LIBRARY=foo. Это сообщает соответствующему модулю поиска заполнитьFoo_LIBRARIESпростоfoo, чтобы попросить компоновщик поискать библиотеку вместо жёсткого кодирования пути. - Или, после установки содержимого пакета, но перед созданием исполняемого файла установки пакета для распространения, вручную замените абсолютные пути на заглушки для подстановки инструментом установки при установке пакета.
Реестр пакетов
CMake предоставляет два центральных местоположения для регистрации пакетов, которые были построены или установлены где-либо в системе:
Реестры особенно полезны для помощи проектам в поиске пакетов в нестандартных местах установки или непосредственно в собственных деревьях построения. Проект может заполнить либо пользовательский, либо системный реестр (используя свои собственные средства, см. ниже), чтобы сослаться на его расположение. В любом случае пакет должен хранить по зарегистрированному адресу файл конфигурации пакета (<package>Config.cmake) и, необязательно, файл версии пакета (<package>ConfigVersion.cmake).
Команда find_package() ищет два реестра пакетов как два шага поиска, указанных в документации. Если у него достаточно разрешений, он также удаляет устаревшие записи реестра пакетов, которые ссылаются на каталоги, которые не существуют или не содержат соответствующего файла конфигурации пакета.
Реестр пакетов пользователя
Реестр пакетов пользователя хранится в пользовательском месте. Команда export(PACKAGE) может быть использована для регистрации дерева построения проекта в пользовательском реестре пакетов. В настоящее время CMake не предоставляет интерфейс для добавления деревьев установки в пользовательский реестр пакетов. Инсталляторам необходимо вручную обучить регистрацию их пакетов, если это необходимо.
В Windows пользовательский реестр пакетов хранится в реестре Windows по ключу в HKEY_CURRENT_USER.
Значение <package> может появиться под ключом реестра:
HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\<package>
в качестве значения REG_SZ, с произвольным именем, указывающим каталог, содержащий файл конфигурации пакета.
В платформах UNIX пользовательский реестр пакетов хранится в домашнем каталоге пользователя по пути ~/.cmake/packages. Файл <package> может появиться в каталоге:
~/.cmake/packages/<package>
в качестве файла с произвольным именем, чьё содержимое указывает каталог, содержащий файл конфигурации пакета.
Реестр системных пакетов
Реестр системных пакетов хранится в системном месте. В настоящее время CMake не предоставляет интерфейса для добавления в системный реестр пакетов. Инсталляторам необходимо вручную обучить регистрацию их пакетов, если это необходимо.
В Windows системный реестр пакетов хранится в реестре Windows по ключу в HKEY_LOCAL_MACHINE. Значение <package> может появиться под ключом реестра:
HKEY_LOCAL_MACHINE\Software\Kitware\CMake\Packages\<package>
в качестве значения REG_SZ, с произвольным именем, указывающим каталог, содержащий файл конфигурации пакета.
В платформах, отличных от Windows, системный реестр пакетов отсутствует.
Отключение реестра пакетов
В некоторых случаях использование реестров пакетов нежелательно. CMake позволяет отключить их с помощью следующих переменных:
CMAKE_EXPORT_NO_PACKAGE_REGISTRYотключает командуexport(PACKAGE).CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRYотключает пользовательский реестр пакетов во всех вызовахfind_package().CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRYотключает системный реестр пакетов во всех вызовахfind_package().
Пример реестра пакетов
Простая конвенция для именования записей реестра пакетов — использование хешей содержимого. Они детерминированы и маловероятны для столкновений (export(PACKAGE) использует этот подход). Имя записи, ссылающейся на конкретный каталог, — это просто хеш содержимого самого пути к каталогу.
Если проект организует существование записей реестра пакетов, таких как:
> reg query HKCU\Software\Kitware\CMake\Packages\MyPackage HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\MyPackage 45e7d55f13b87179bb12f907c8de6fc4 REG_SZ c:/Users/Me/Work/lib/cmake/MyPackage 7b4a9844f681c80ce93190d4e3185db9 REG_SZ c:/Users/Me/Work/MyPackage-build
или:
$ cat ~/.cmake/packages/MyPackage/7d1fb77e07ce59a81bed093bbee945bd /home/me/work/lib/cmake/MyPackage $ cat ~/.cmake/packages/MyPackage/f92c1db873a1937f3100706657c63e07 /home/me/work/MyPackage-build
тогда код CMakeLists.txt:
find_package(MyPackage)
будет искать в зарегистрированных местах файлы конфигурации пакетов (MyPackageConfig.cmake). Порядок поиска среди записей реестра пакетов для одного пакета не определен, и имена записей (хеши в этом примере) не имеют смысла. Зарегистрированные места могут содержать файлы версии пакета (MyPackageConfigVersion.cmake), чтобы сообщить find_package(), подходит ли конкретное место для запрошенной версии.
Владение реестром пакетов
Записи реестра пакетов индивидуально принадлежат проектам установок, на которые они ссылаются. Инсталлятор пакета отвечает за добавление собственной записи, а соответствующий деинсталлятор — за её удаление.
Команда export(PACKAGE) заполняет пользовательский реестр пакетов местоположением дерева построения проекта. Деревья построения, как правило, удаляются разработчиками и не имеют события «деинсталляции», которое могло бы вызвать удаление их записей. Чтобы поддерживать чистоту реестров, команда find_package() автоматически удаляет устаревшие записи, которые она обнаруживает, если у неё достаточно разрешений. CMake не предоставляет интерфейса для удаления записи, ссылающейся на существующее дерево построения после того, как была вызвана команда export(PACKAGE). Однако, если проект удаляет свой файл конфигурации пакета из дерева построения, то запись, ссылающаяся на местоположение, будет считаться устаревшей.
© 2000–2019 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.5/manual/cmake-packages.7.html