Spec-Zone.ru › CMake 3.18

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 ищет файлы конфигурации пакета в нескольких расположениях, как описано в документации команды find_package(). Наиболее простой способ сообщить CMake о поиске пакета в нестандартном префиксе — установить переменную кэша CMAKE_PREFIX_PATH.

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

При использовании пакета конфигурационных файлов также автоматически устанавливается набор переменных, предоставляющих информацию о состоянии пакета. Переменная <PackageName>_FOUND устанавливается в значение true или false, в зависимости от того, был ли найден пакет. Переменная кэша <PackageName>_DIR устанавливается в расположение файла конфигурации пакета.

Пакеты модулей поиска

Модуль поиска — это файл с набором правил поиска необходимых частей зависимости, в основном заголовочных файлов и библиотек. Обычно модуль поиска необходим, когда поставщик не использует 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().

Создание пакетов

Обычно, зависимость от самого 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 целевых объектов, подходящих для использования 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. Это приводит к тому, что 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(), они перечислены в переменной <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(_supported_components Plot Table)

foreach(_comp ${ClimbingStats_FIND_COMPONENTS})
  if (NOT ";${_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_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 предоставляет два центральных места для регистрации пакетов, которые были построены или установлены где-либо на системе:

  • Пользовательский Регистр пакетов
  • Системный Регистр пакетов

Регистры особенно полезны, чтобы помочь проектам найти пакеты в нестандартных местах установки или непосредственно в собственных деревьях сборки. Проект может заполнить либо пользовательский, либо системный регистр (с использованием собственных средств, см. ниже), чтобы указать на свое расположение. В любом случае пакет должен хранить по зарегистрированному адресу файл Конфигурационного файла пакета (<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–2020 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.18/manual/cmake-packages.7.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API