Spec-Zone.ru › CMake 3.29

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:

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 сделает пакет обязательным.

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

Пакет с файлом конфигурации представляет собой набор файлов, предоставляемых 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() находит кандидатный файл конфигурации пакета, она ищет рядом с ним файл версии. Файл версии загружается для проверки, является ли версия пакета приемлемой для запрошенной версии. Если файл версии утверждает совместимость, файл конфигурации принимается. В противном случае он игнорируется.

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

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

Spec-Zone.ru

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