Spec-Zone.ru › CMake 3.20

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 или не достаточно хорошо поддерживает 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, подходящих для использования 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(), они перечислены в переменной <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–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.20/manual/cmake-packages.7.html

Spec-Zone.ru

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