Spec-Zone.ru › CMake

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

END_OF_DOCUMENT_MARKER

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

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 для создания файлов пакета. Рассмотрим upstream, который предоставляет один общий библиотеку:

project(UpstreamLib)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)

set(Upstream_VERSION 3.4.1)

include(GenerateExportHeader)

add_library(ClimbingStats SHARED climbingstats.cpp)
generate_export_header(ClimbingStats)
set_property(TARGET ClimbingStats PROPERTY VERSION ${Upstream_VERSION})
set_property(TARGET ClimbingStats PROPERTY SOVERSION 3)
set_property(TARGET ClimbingStats PROPERTY
  INTERFACE_ClimbingStats_MAJOR_VERSION 3)
set_property(TARGET ClimbingStats APPEND PROPERTY
  COMPATIBLE_INTERFACE_STRING ClimbingStats_MAJOR_VERSION
)

install(TARGETS ClimbingStats EXPORT ClimbingStatsTargets
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)
install(
  FILES
    climbingstats.h
    "${CMAKE_CURRENT_BINARY_DIR}/climbingstats_export.h"
  DESTINATION
    include
  COMPONENT
    Devel
)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
  VERSION ${Upstream_VERSION}
  COMPATIBILITY AnyNewerVersion
)

export(EXPORT ClimbingStatsTargets
  FILE "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsTargets.cmake"
  NAMESPACE Upstream::
)
configure_file(cmake/ClimbingStatsConfig.cmake
  "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfig.cmake"
  COPYONLY
)

set(ConfigPackageLocation lib/cmake/ClimbingStats)
install(EXPORT ClimbingStatsTargets
  FILE
    ClimbingStatsTargets.cmake
  NAMESPACE
    Upstream::
  DESTINATION
    ${ConfigPackageLocation}
)
install(
  FILES
    cmake/ClimbingStatsConfig.cmake
    "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
  DESTINATION
    ${ConfigPackageLocation}
  COMPONENT
    Devel
)

Модуль CMakePackageConfigHelpers предоставляет макрос для создания простого файла ConfigVersion.cmake. Этот файл устанавливает версию пакета. Он считывается CMake, когда вызывается find_package() для определения совместимости с запрошенной версией и для установки некоторых переменных, специфичных для версии <PackageName>_VERSION, <PackageName>_VERSION_MAJOR, <PackageName>_VERSION_MINOR и т.д. Команда install(EXPORT) используется для экспорта целей в наборе экспорта ClimbingStatsTargets, определенном ранее командой install(TARGETS). Эта команда генерирует файл ClimbingStatsTargets.cmake для хранения целей IMPORTED, подходящих для использования downstream, и организует его установку в 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, когда оно используется downstream с командой target_link_libraries(). Таким образом, CMake может выдать диагностическое сообщение, если пакет, предоставляющий его, еще не найден.

В этом случае при использовании install(TARGETS) был указан INCLUDES DESTINATION. Это приводит к тому, что у целей IMPORTED заполняются их INTERFACE_INCLUDE_DIRECTORIES с каталогом include в CMAKE_INSTALL_PREFIX. При использовании цели IMPORTED downstream, она автоматически использует записи из этого свойства.

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

В этом случае файл ClimbingStatsConfig.cmake может быть таким простым, как:

include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")

Поскольку это позволяет downstream использовать цели 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, downstream также должен найти пакет 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 указаны, когда downstream использует 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–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html

Spec-Zone.ru

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