Spec-Zone.ru › CMake 3.23

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. Это приводит к тому, что цели 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, соответствующим образом заполненные. Эти импортированные цели затем могут быть использованы с командой target_link_libraries() для ClimbingStats:

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

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

К сожалению, многие 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–2022 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.23/manual/cmake-packages.7.html

Spec-Zone.ru

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