Spec-Zone.ru › CMake 3.14

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

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

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

К сожалению, многие modules, поставляемые с CMake, пока не предоставляют импортированные цели, потому что их разработка предшествовала этому подходу. Это может улучшаться со временем. Обходные пути для создания переносимых пакетов, использующих такие модули, включают:

  • При построении пакета укажите каждую запись кеша 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 позволяет отключить их, используя следующие переменные:

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

END_OF_DOCUMENT_MARKER

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

Spec-Zone.ru

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