Spec-Zone.ru › CMake 3.26

cmake-packages(7)

  • Введение
  • Использование пакетов

    • Пакеты с конфигурационными файлами
    • Пакеты с модулями поиска
  • Структура пакета

    • Файл конфигурации пакета
    • Файл версии пакета
  • Создание пакетов

    • Создание файла конфигурации пакета

      • Создание файла конфигурации пакета для дерева сборки
    • Создание переносимых пакетов
  • Реестр пакетов

    • Пользовательский реестр пакетов
    • Системный реестр пакетов
    • Отключение реестра пакетов
    • Пример реестра пакетов
    • Владение реестром пакетов

Введение

Пакеты предоставляют информацию о зависимостях системам сборки, основанным на CMake. Пакеты находятся с помощью команды find_package(). Результатом использования find_package() является либо набор IMPORTED целей, либо набор переменных, соответствующих информации, относящейся к сборке.

Использование пакетов

CMake предоставляет прямую поддержку двух форм пакетов: пакеты с конфигурационными файлами и пакеты с модулями поиска. Непрямая поддержка pkg-config пакетов также предоставляется через модуль FindPkgConfig. Во всех случаях базовая форма вызовов find_package() одинакова:

find_package(Qt4 4.7.0 REQUIRED) # CMake provides a Qt4 find-module
find_package(Qt5Core 5.1.0 REQUIRED) # Qt provides a Qt5 package config file.
find_package(LibXml2 REQUIRED) # Use pkg-config via the LibXml2 find-module

В случаях, когда известно, что файл конфигурации пакета предоставляется upstream, и должен использоваться только он, может быть передан ключевое слово CONFIG команде find_package():

find_package(Qt5Core 5.1.0 CONFIG REQUIRED)
find_package(Qt5Gui 5.1.0 CONFIG)

Аналогично, ключевое слово MODULE указывает на использование только модуля поиска:

find_package(Qt4 4.7.0 MODULE REQUIRED)

Явное указание типа пакета улучшает сообщение об ошибке, отображаемое пользователю, если пакет не найден.

Оба типа пакетов также поддерживают указание компонентов пакета, либо после ключевого слова REQUIRED,

find_package(Qt5 5.1.0 CONFIG REQUIRED Widgets Xml Sql)

либо как отдельный список COMPONENTS,

find_package(Qt5 5.1.0 COMPONENTS Widgets Xml Sql)

либо как отдельный список OPTIONAL_COMPONENTS.

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

Установив переменную CMAKE_DISABLE_FIND_PACKAGE_<PackageName> в значение TRUE, поиск пакета <PackageName> будет отключен, и он всегда будет NOTFOUND. Аналогично, установка CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> в значение TRUE сделает пакет ОБОЯЗАТЕЛЬНЫМ.

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

Пакет с конфигурационным файлом — это набор файлов, предоставляемых upstream для использования downstream. CMake ищет файлы конфигурации пакета в ряде мест, как описано в документации к команде find_package(). Самый простой способ сказать CMake, чтобы искать пакет в нестандартном префиксе, — установить переменную кэша CMAKE_PREFIX_PATH.

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

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

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

Модуль поиска — это файл с набором правил для поиска необходимых компонентов зависимости, в основном заголовочных файлов и библиотек. Как правило, модуль поиска необходим, когда upstream не построен с помощью CMake или недостаточно осведомлен о CMake, чтобы иначе предоставить файл конфигурации пакета. В отличие от файла конфигурации пакета, он не поставляется с upstream, а используется downstream для поиска файлов с помощью догадок о расположении файлов с помощью платформенно-специфических подсказок.

В отличие от случая с предоставленным upstream файлом конфигурации пакета, нет единой точки отсчёта, идентифицирующей пакет как найденный, поэтому переменная <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 для создания файлов пакета. Рассмотрим верхний уровень, который предоставляет единственную общую библиотеку:

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–2023 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.26/manual/cmake-packages.7.html

Spec-Zone.ru

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