Spec-Zone.ru › CMake 3.11

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.

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

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

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

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

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

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

В отличие от случая с конфигурационным файлом пакета, предоставленным upstream, нет единой точки отсчета для определения того, что пакет найден, поэтому переменная <Package>_FOUND не устанавливается автоматически командой find_package(). Однако можно ожидать, что она будет установлена по соглашению, и её должен установить автор модуля поиска. Аналогично, нет переменной <Package>_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
Имя пакета
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 устанавливает следующие переменные для использования проектом:

<package>_VERSION
Полная предоставленная строка версии
<package>_VERSION_MAJOR
Главная версия, если предоставлена, иначе 0
<package>_VERSION_MINOR
Дополнительная версия, если предоставлена, иначе 0
<package>_VERSION_PATCH
Версия исправления, если предоставлена, иначе 0
<package>_VERSION_TWEAK
Версия доработки, если предоставлена, иначе 0
<package>_VERSION_COUNT
Количество компонентов версии, от 0 до 4

Переменные сообщают о версии пакета, который фактически был найден. Часть их имени <package> соответствует аргументу, предоставленному команде 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() для определения совместимости с запрошенной версией и для установки некоторых переменных, специфичных для версии <Package>_VERSION, <Package>_VERSION_MAJOR, <Package>_VERSION_MINOR и т. д. Команда install(EXPORT) используется для экспорта целевых объектов в ClimbingStatsTargets export-set, определенный ранее командой 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(), они перечислены в переменной <Package>_FIND_COMPONENTS. Если конкретный компонент является необязательным, то <Package>_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 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 предоставляет два центральных места для регистрации пакетов, которые были построены или установлены где-либо в системе:

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

Реестры особенно полезны для помощи проектам в поиске пакетов в нестандартных местах установки или непосредственно в своих собственных деревьях построения. Проект может заполнить пользовательский или системный реестр (используя собственные средства, см. ниже), чтобы указать на своё расположение. В любом случае пакет должен хранить в зарегистрированном месте файл конфигурации пакета (<package>Config.cmake) и, необязательно, файл версии пакета (<package>ConfigVersion.cmake).

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

Пользовательский реестр пакетов

Пользовательский реестр пакетов хранится в расположении пользователя. Команда export(PACKAGE) может использоваться для регистрации дерева построения проекта в пользовательском реестре пакетов. В настоящее время CMake не предоставляет интерфейса для добавления деревьев установки в пользовательский реестр пакетов. Установщикам нужно вручную обучать регистрацию их пакетов, если это требуется.

В Windows пользовательский реестр пакетов хранится в реестре Windows по ключу в HKEY_CURRENT_USER.

Значение <package> может появиться под ключом реестра:

HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\<package>

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

На платформах UNIX пользовательский реестр пакетов хранится в домашнем каталоге пользователя в ~/.cmake/packages. Файл <package> может появиться в каталоге:

~/.cmake/packages/<package>

в виде файла с произвольным именем, содержимое которого указывает каталог, содержащий файл конфигурации пакета.

Системный реестр пакетов

Системный реестр пакетов хранится в системном расположении. В настоящее время CMake не предоставляет интерфейса для добавления в системный реестр пакетов. Установщикам нужно вручную обучать регистрацию их пакетов, если это требуется.

В Windows системный реестр пакетов хранится в реестре Windows по ключу в HKEY_LOCAL_MACHINE. Значение <package> может появиться под ключом реестра:

HKEY_LOCAL_MACHINE\Software\Kitware\CMake\Packages\<package>

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

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

Spec-Zone.ru

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