Spec-Zone.ru › CMake 3.31

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.

Обработка COMPONENTS и OPTIONAL_COMPONENTS определяется пакетом.

Установив переменную CMAKE_DISABLE_FIND_PACKAGE_<PackageName> в значение TRUE, поиск пакета <PackageName> будет отключён, и он всегда будет NOTFOUND. Аналогично, установка CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> в значение TRUE сделает пакет обязательным (REQUIRED).

Пакеты с файлами конфигурации

Пакет с файлом конфигурации — это набор файлов, предоставляемых предшественниками для использования потомками. 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 targets, которые имеют свои собственные IMPORTED_LOCATION и свойства требований к использованию, такие как INTERFACE_INCLUDE_DIRECTORIES, заполненные должным образом. Эти импортированные targets могут затем использоваться с командой target_link_libraries() для ClimbingStats:

target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar)

С этим подходом пакет ссылается на свои внешние зависимости только по именам IMPORTED targets. Когда пользователь использует установленный пакет, пользователь выполнит соответствующие команды find_package() (через макрос find_dependency описанный выше), чтобы найти зависимости и заполнить импортированные targets соответствующими путями на своей машине.

К сожалению, многие modules, поставляемые с CMake, ещё не предоставляют IMPORTED targets, потому что их разработка предшествовала этому подходу. Это может постепенно улучшаться со временем. Способы создания переносимых пакетов, использующих такие модули, включают:

  • При создании пакета укажите каждую запись кэша 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.31/manual/cmake-packages.7.html

Spec-Zone.ru

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