Spec-Zone.ru › CMake 3.22

cmake-packages(7)

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

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

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

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

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

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

Введение

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

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

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

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

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

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

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

find_package(Qt4 4.7.0 MODULE REQUIRED)

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

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

find_package(Qt5 5.1.0 CONFIG REQUIRED Widgets Xml Sql)

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

find_package(Qt5 5.1.0 COMPONENTS Widgets Xml Sql)

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

find_package(Qt5 5.1.0 COMPONENTS Widgets
                       OPTIONAL_COMPONENTS Xml Sql
)

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

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

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

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

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

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

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

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

В отличие от случая файла конфигурации пакета, предоставляемого предшественником, нет одной точки отсчёта, которая идентифицирует пакет как найденный, поэтому переменная <PackageName>_FOUND не устанавливается автоматически командой find_package(). Однако можно ожидать, что она будет установлена по соглашению, и её должен установить автор модуля поиска. Аналогично, нет переменной <PackageName>_DIR , но каждый из артефактов, таких как расположение библиотек и заголовочных файлов, предоставляет отдельную переменную кэша.

См. руководство cmake-developer(7) для получения дополнительной информации о создании файлов модулей поиска.

Структура пакета

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

Файл конфигурации пакета

Рассмотрим проект Foo , который устанавливает следующие файлы:

<prefix>/include/foo-1.2/foo.h
<prefix>/lib/foo-1.2/libfoo.a

Он также может предоставить файл конфигурации пакета CMake:

<prefix>/lib/cmake/foo-1.2/FooConfig.cmake

с содержимым, определяющим IMPORTED цели или определяющим переменные, такие как:

# ...
# (compute PREFIX relative to file location)
# ...
set(Foo_INCLUDE_DIRS ${PREFIX}/include/foo-1.2)
set(Foo_LIBRARIES ${PREFIX}/lib/foo-1.2/libfoo.a)

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

Команда find_package() может использоваться для поиска файла конфигурации пакета. Эта команда строит набор префиксов установки и ищет под каждым префиксом в нескольких местах. Учитывая имя Foo, она ищет файл под названием FooConfig.cmake или foo-config.cmake. Полный набор местоположений указан в документации к команде find_package(). Одно из мест, где она ищет, это:

<prefix>/lib/cmake/Foo*/

где Foo* — это выражение с игнорированием регистра и подстановкой. В нашем примере выражение подстановки будет соответствовать <prefix>/lib/cmake/foo-1.2 , и файл конфигурации пакета будет найден.

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

Файл версии пакета

Когда команда find_package() находит кандидатный файл конфигурации пакета, она ищет рядом с ним файл версии. Файл версии загружается для проверки, является ли версия пакета приемлемым соответствием запрошенной версии. Если файл версии утверждает совместимость, файл конфигурации принимается. В противном случае он игнорируется.

Имя файла версии пакета должно совпадать с именем файла конфигурации пакета, но к нему добавлено либо -version , либо Version перед расширением .cmake. Например, файлы:

<prefix>/lib/cmake/foo-1.3/foo-config.cmake
<prefix>/lib/cmake/foo-1.3/foo-config-version.cmake

и:

<prefix>/lib/cmake/bar-4.2/BarConfig.cmake
<prefix>/lib/cmake/bar-4.2/BarConfigVersion.cmake

являются парами файлов конфигурации пакета и соответствующих файлов версии пакета.

При загрузке файла версии командой find_package() сначала устанавливаются следующие переменные:

PACKAGE_FIND_NAME

<PackageName>

PACKAGE_FIND_VERSION

Полная строка запрошенной версии

PACKAGE_FIND_VERSION_MAJOR

Основная версия, если запрошена, в противном случае 0

PACKAGE_FIND_VERSION_MINOR

Дополнительная версия, если запрошена, в противном случае 0

PACKAGE_FIND_VERSION_PATCH

Версия исправления, если запрошена, в противном случае 0

PACKAGE_FIND_VERSION_TWEAK

Версия доработки, если запрошена, в противном случае 0

PACKAGE_FIND_VERSION_COUNT

Количество компонентов версии, от 0 до 4

Файл версии должен использовать эти переменные для проверки совместимости или точного соответствия запрошенной версии и установить следующие переменные с результатами:

PACKAGE_VERSION

Полная предоставленная строка версии

PACKAGE_VERSION_EXACT

Истина, если версия является точным соответствием

PACKAGE_VERSION_COMPATIBLE

Истина, если версия совместима

PACKAGE_VERSION_UNSUITABLE

Истина, если не подходит в качестве версии

Файлы версий загружаются во вложенном объёме, поэтому они могут свободно устанавливать любые переменные в качестве части своего вычисления. Команда find_package очищает область видимости после завершения файла версии и проверки выходных переменных. Когда файл версии заявляет о себе как о приемлемом соответствии запрошенной версии, команда find_package устанавливает следующие переменные для использования проектом:

<PackageName>_VERSION

Полная предоставленная строка версии

<PackageName>_VERSION_MAJOR

Главная версия, если указана, иначе 0

<PackageName>_VERSION_MINOR

Вспомогательная версия, если указана, иначе 0

<PackageName>_VERSION_PATCH

Версия исправления, если указана, иначе 0

<PackageName>_VERSION_TWEAK

Версия доработки, если указана, иначе 0

<PackageName>_VERSION_COUNT

Количество компонентов версии, от 0 до 4

Переменные сообщают о версии пакета, который был фактически найден. Часть имени, <PackageName>, соответствует аргументу, заданному команде find_package().

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

Обычно, зависимость от верхнего уровня зависит от самого 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. Это заставляет INTERFACE_INCLUDE_DIRECTORIES целей заполняться каталогом include в CMAKE_INSTALL_PREFIX. При использовании INTERFACE_INCLUDE_DIRECTORIES зависимыми пакетами, они автоматически используют значения из этого свойства.

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

В данном случае файл 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(_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-цели, которые имеют свои собственные 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) заполняет реестр пакетов пользователя местоположением дерева сборки проекта. Деревья сборки часто удаляются разработчиками и не имеют события "uninstall", которое могло бы инициировать удаление их записей. Для поддержания чистоты реестров команда find_package() автоматически удаляет устаревшие записи, которые она обнаруживает, если у неё есть достаточные разрешения. CMake не предоставляет интерфейс для удаления записи, ссылающейся на существующее дерево сборки после вызова export(PACKAGE). Однако, если проект удаляет файл конфигурации пакета из дерева сборки, то запись, ссылающаяся на местоположение, будет считаться устаревшей.

© 2000–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.22/manual/cmake-packages.7.html

Spec-Zone.ru

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