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(1) о поиске в нестандартном префиксе для пакета — установить переменную кэша 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().
Создание пакетов
Обычно upstream зависит от самого 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_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 позволяет отключить их, используя следующие переменные:
- Команда
export(PACKAGE)не заполняет пользовательский регистр пакетов, когдаCMP0090установлено вNEW, за исключением случая, когда переменнаяCMAKE_EXPORT_PACKAGE_REGISTRYявно разрешает это. КогдаCMP0090не установлено вNEW, тогдаexport(PACKAGE)заполняет пользовательский регистр пакетов, за исключением случая, когда переменнаяCMAKE_EXPORT_NO_PACKAGE_REGISTRYявно отключает это. -
CMAKE_FIND_USE_PACKAGE_REGISTRYотключает пользовательский регистр пакетов во всех вызовахfind_package(), когда установлено вFALSE. - Устаревшая переменная
CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRYотключает пользовательский регистр пакетов во всех вызовахfind_package(), когда установлено вTRUE. Эта переменная игнорируется, когдаCMAKE_FIND_USE_PACKAGE_REGISTRYуже установлена. -
CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRYотключает системный регистр пакетов во всех вызовахfind_package().
Пример регистра пакетов
Простая конвенция для именования записей в реестре пакетов — использование хэшей содержимого. Они детерминированы и вряд ли столкнутся (export(PACKAGE) использует этот подход). Имя записи, ссылающейся на определённый каталог, просто хэш содержимого самого пути к каталогу.
Если проект организует существование записей в реестре пакетов, таких как:
> reg query HKCU\Software\Kitware\CMake\Packages\MyPackage HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\MyPackage 45e7d55f13b87179bb12f907c8de6fc4 REG_SZ c:/Users/Me/Work/lib/cmake/MyPackage 7b4a9844f681c80ce93190d4e3185db9 REG_SZ c:/Users/Me/Work/MyPackage-build
или:
$ cat ~/.cmake/packages/MyPackage/7d1fb77e07ce59a81bed093bbee945bd /home/me/work/lib/cmake/MyPackage $ cat ~/.cmake/packages/MyPackage/f92c1db873a1937f3100706657c63e07 /home/me/work/MyPackage-build
тогда код CMakeLists.txt:
find_package(MyPackage)
будет искать зарегистрированные расположения для файлов конфигурации пакетов (MyPackageConfig.cmake). Порядок поиска среди записей реестра пакетов для одного пакета не определен, а имена записей (хеши в данном примере) не имеют значения. Зарегистрированные расположения могут содержать файлы версии пакета (MyPackageConfigVersion.cmake), чтобы сообщить find_package(), подходит ли конкретное расположение для запрошенной версии.
Владение реестром пакетов
Записи реестра пакетов индивидуально принадлежат проектам, на которые они ссылаются. Установщик пакета отвечает за добавление собственной записи, а соответствующий удалитель отвечает за ее удаление.
Команда export(PACKAGE) заполняет пользовательский реестр пакетов расположением дерева проекта сборки. Деревья сборки имеют тенденцию удаляться разработчиками и не имеют события «удаления», которое могло бы инициировать удаление их записей. Для поддержания чистоты реестров команда find_package() автоматически удаляет устаревшие записи, с которыми она сталкивается, если у нее есть достаточные разрешения. CMake не предоставляет интерфейс для удаления записи, ссылающейся на существующее дерево сборки, после того, как была вызвана export(PACKAGE). Однако, если проект удаляет файл конфигурации пакета из дерева сборки, запись, ссылающаяся на расположение, будет считаться устаревшей.
© 2000–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.28/manual/cmake-packages.7.html