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 -
True, если версия — точное совпадение
-
PACKAGE_VERSION_COMPATIBLE -
True, если версия совместима
-
PACKAGE_VERSION_UNSUITABLE -
True, если не подходит ни для какой версии
Файлы версий загружаются в вложенном пространстве имен, поэтому они могут свободно устанавливать любые переменные, необходимые для своих вычислений. Команда 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> будет true. Это можно проверить с помощью логики в файле конфигурации пакета:
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_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–2020 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.15/manual/cmake-packages.7.html