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
В тех случаях, когда известно, что файл конфигурации пакета предоставлен предшественником и должен использоваться только он, может быть передан ключевое слово 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. Аналогично, установка CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> в значение TRUE сделает пакет ОБОЯЗАТЕЛЬНЫМ.
Пакеты конфигурационных файлов
Пакет конфигурационного файла — это набор файлов, предоставляемых поставщиками для использования конечными пользователями. CMake ищет файлы конфигурации пакета в ряде местоположений, как описано в документации к команде find_package(). Наиболее простой способ указать CMake искать пакет в нестандартном префиксе — установить переменную кэша CMAKE_PREFIX_PATH.
Пакеты конфигурационных файлов предоставляются поставщиками в составе пакетов разработки, то есть они входят вместе с заголовочными файлами и другими файлами, которые помогают конечным пользователям использовать пакет.
При использовании пакета конфигурационного файла также автоматически устанавливается набор переменных, предоставляющих информацию о статусе пакета. Переменная <PackageName>_FOUND устанавливается в значение true или false в зависимости от того, был ли найден пакет. Переменная кэша <PackageName>_DIR устанавливается в расположение файла конфигурации пакета.
Пакеты модулей поиска
Модуль поиска — это файл с набором правил для поиска необходимых элементов зависимости, в первую очередь заголовочных файлов и библиотек. Модуль поиска обычно необходим, когда пакет не создается с помощью CMake или не поддерживает CMake для предоставления файла конфигурации пакета. В отличие от файла конфигурации пакета, он не поставляется с пакетом, а используется конечными пользователями для поиска файлов с использованием платформ-зависимых подсказок.
В отличие от случая с файлом конфигурации пакета, предоставленного предшественником, нет единой точки отсчета, определяющей, что пакет найден, поэтому переменная <PackageName>_FOUND не устанавливается автоматически командой find_package(). Однако по соглашению она всё ещё может быть установлена, и авторы модуля поиска должны её устанавливать. Аналогично, нет переменной <PackageName>_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 -
<PackageName> -
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 -
Истинно, если версия является точным соответствием
-
PACKAGE_VERSION_COMPATIBLE -
Истинно, если версия совместима
-
PACKAGE_VERSION_UNSUITABLE -
Истинно, если не подходит как любая версия
Файлы версий загружаются во вложенном контексте, поэтому они могут свободно устанавливать любые переменные, которые они пожелают в рамках своих вычислений. Команда find_package очищает контекст, когда файл версии завершил работу и проверил выходные переменные. Когда файл версии утверждает, что является приемлемым соответствием для запрошенной версии, команда find_package устанавливает следующие переменные для использования проектом:
-
<PackageName>_VERSION -
Полная предоставленная строка версии
-
<PackageName>_VERSION_MAJOR -
Главная версия, если указана, иначе 0
-
<PackageName>_VERSION_MINOR -
Дополнительная версия, если указана, иначе 0
-
<PackageName>_VERSION_PATCH -
Версия исправления, если указана, иначе 0
-
<PackageName>_VERSION_TWEAK -
Версия доработки, если указана, иначе 0
-
<PackageName>_VERSION_COUNT -
Количество компонентов версии, от 0 до 4
Переменные сообщают о версии пакета, который был фактически найден. Часть имени <PackageName> соответствует аргументу, заданному команде 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() для определения совместимости с запрошенной версией и для установки некоторых переменных, специфичных для версии <PackageName>_VERSION, <PackageName>_VERSION_MAJOR, <PackageName>_VERSION_MINOR и т.д. Команда install(EXPORT) используется для экспорта целевых объектов в наборе экспорта ClimbingStatsTargets, определенном ранее командой install(TARGETS). Эта команда генерирует файл ClimbingStatsTargets.cmake для хранения целевых объектов IMPORTED, подходящих для использования зависимыми пакетами, и организует его установку в 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, когда он используется зависимыми пакетами с командой target_link_libraries(). Таким образом, CMake может выдать диагностическое сообщение, если пакет, предоставляющий его, еще не найден.
В этом случае, при использовании install(TARGETS) был указан INCLUDES DESTINATION. Это приводит к тому, что целевые объекты IMPORTED имеют свои INTERFACE_INCLUDE_DIRECTORIES заполненными каталогом include в CMAKE_INSTALL_PREFIX. Когда целевой объект IMPORTED используется зависимым пакетом, он автоматически потребляет записи из этого свойства.
Создание файла конфигурации пакета
В этом случае файл ClimbingStatsConfig.cmake может быть таким простым:
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
Поскольку это позволяет зависимым пакетам использовать целевые объекты 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, зависимые пакеты также должны найти пакет 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 указаны при использовании зависимым пакетом find_package(), они перечислены в переменной <PackageName>_FIND_COMPONENTS. Если какой-либо конкретный компонент является обязательным, то <PackageName>_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(_ClimbingStats_supported_components Plot Table)
foreach(_comp ${ClimbingStats_FIND_COMPONENTS})
if (NOT ";${_ClimbingStats_supported_components};" MATCHES ";${_comp};")
set(ClimbingStats_FOUND False)
set(ClimbingStats_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake")
endforeach()
Здесь ClimbingStats_NOT_FOUND_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>> )
Это также относится к путям, ссылающимся на внешние зависимости. Не рекомендуется заполнять какие-либо свойства, которые могут содержать пути, такие как 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 цели, которые имеют свои собственные IMPORTED_LOCATION и свойства требований использования, такие как INTERFACE_INCLUDE_DIRECTORIES, заполненные должным образом. Эти импортированные цели затем можно использовать с командой target_link_libraries() для ClimbingStats:
target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar)
С этим подходом пакет ссылается на свои внешние зависимости только по именам IMPORTED целей. Когда потребитель использует установленный пакет, потребитель запустит соответствующие команды find_package() (через макрос find_dependency описанный выше), чтобы найти зависимости и заполнить импортированные цели соответствующими путями на собственной машине потребителя.
К сожалению, многие modules, поставляемые с CMake, пока не предоставляют IMPORTED цели, поскольку их разработка предшествовала этому подходу. Это может постепенно улучшаться со временем. Обходные пути для создания переносимых пакетов, использующих такие модули, включают:
- При построении пакета укажите каждую запись кеша
Foo_LIBRARYтолько как имя библиотеки, например-DFoo_LIBRARY=foo. Это сообщает соответствующему модулю поиска о заполненииFoo_LIBRARIESтолькоfooдля запроса к компоновщику поиска библиотеки вместо жёсткой привязки пути. - Или, после установки содержимого пакета, но перед созданием двоичного файла установки пакета для распространения, вручную замените абсолютные пути на местозаполнители для подстановки инструментом установки при установке пакета.
Реестр пакетов
CMake предоставляет два центральных расположения для регистрации пакетов, которые были построены или установлены где-либо в системе:
Реестры особенно полезны для помощи проектам в поиске пакетов в нестандартных местах установки или непосредственно в собственных деревьях построения. Проект может заполнить либо пользовательский, либо системный реестр (используя собственные средства, см. ниже), чтобы сослаться на своё расположение. В любом случае пакет должен хранить в зарегистрированном месте Файл конфигурации пакета (<PackageName>Config.cmake) и необязательно Файл версии пакета (<PackageName>ConfigVersion.cmake).
Команда find_package() ищет два реестра пакетов как две из шагов поиска, указанных в документации. Если у него достаточно разрешений, он также удаляет устаревшие записи реестра пакетов, которые ссылаются на каталоги, которые не существуют или не содержат соответствующий файл конфигурации пакета.
Пользовательский реестр пакетов
Пользовательский реестр пакетов хранится в местоположении пользователя. Команда export(PACKAGE) может быть использована для регистрации дерева построения проекта в пользовательском реестре пакетов. В настоящее время CMake не предоставляет интерфейс для добавления деревьев установки в пользовательский реестр пакетов. Инсталляторам необходимо вручную обучить, как регистрировать свои пакеты, если это необходимо.
В Windows пользовательский реестр пакетов хранится в реестре Windows в ключе HKEY_CURRENT_USER.
<PackageName> может появиться в ключе реестра:
HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\<PackageName>
в качестве REG_SZ значения с произвольным именем, которое указывает каталог, содержащий файл конфигурации пакета.
На платформах UNIX пользовательский реестр пакетов хранится в домашнем каталоге пользователя в ~/.cmake/packages. <PackageName> может появиться в каталоге:
~/.cmake/packages/<PackageName>
в качестве файла с произвольным именем, содержимое которого указывает каталог, содержащий файл конфигурации пакета.
Системный реестр пакетов
Системный реестр пакетов хранится в системном местоположении. В настоящее время CMake не предоставляет интерфейс для добавления в системный реестр пакетов. Инсталляторам необходимо вручную обучить, как регистрировать свои пакеты, если это необходимо.
В Windows системный реестр пакетов хранится в реестре Windows в ключе HKEY_LOCAL_MACHINE. <PackageName> может появиться в ключе реестра:
HKEY_LOCAL_MACHINE\Software\Kitware\CMake\Packages\<PackageName>
в качестве REG_SZ значения с произвольным именем, которое указывает каталог, содержащий файл конфигурации пакета.
На платформах, отличных от Windows, системного реестра пакетов нет.
Отключение реестра пакетов
В некоторых случаях использование реестров пакетов нежелательно. CMake позволяет отключить их с помощью следующих переменных:
- Команда
export(PACKAGE)не заполняет пользовательский реестр пакетов, когдаCMP0090установлена вNEW, если переменнаяCMAKE_EXPORT_PACKAGE_REGISTRYне включена явно. КогдаCMP0090не установлена вNEW, тогдаexport(PACKAGE)заполняет пользовательский реестр пакетов, если переменнаяCMAKE_EXPORT_NO_PACKAGE_REGISTRYне отключена явно. -
CMAKE_FIND_USE_PACKAGE_REGISTRYотключает пользовательский реестр пакетов во всех вызовахfind_package(), когда установлено значениеFALSE. - Устаревшая
CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRYотключает пользовательский реестр пакетов во всех вызовахfind_package(), когда установлено значениеTRUE. Эта переменная игнорируется, когдаCMAKE_FIND_USE_PACKAGE_REGISTRYбыла установлена. -
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–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.30/manual/cmake-packages.7.html