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 цели, которые имеют свои собственные 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–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.21/manual/cmake-packages.7.html