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.
Пакеты с файлами конфигурации предоставляются поставщиками в составе пакетов разработки, то есть они находятся вместе с заголовочными файлами и другими файлами, предназначенными для помощи потребителям в использовании пакета.
Набор переменных, предоставляющих информацию о статусе пакета, также устанавливается автоматически при использовании пакета с файлом конфигурации. Переменная <Package>_FOUND устанавливается в значение true или false в зависимости от того, был ли пакет найден. Переменная кэша <Package>_DIR устанавливается в значение расположения файла конфигурации пакета.
Пакеты с модулями поиска
Модуль поиска — это файл с набором правил для поиска необходимых компонентов зависимости, в первую очередь заголовочных файлов и библиотек. Как правило, модуль поиска необходим, когда поставщик не использует CMake или не достаточно CMake-совместим, чтобы иначе предоставить файл конфигурации пакета. В отличие от файла конфигурации пакета, он не поставляется с поставщиком, а используется потребителем для поиска файлов, используя сведения о расположении файлов для каждой платформы.
В отличие от случая, когда поставщик предоставляет файл конфигурации пакета, ни одна точка отсчёта не идентифицирует пакет как найденный, поэтому переменная <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() находит кандидатный файл конфигурации пакета, она ищет рядом с ним файл версии. Файл версии загружается для проверки, соответствует ли версия пакета запрошенной версии. Если файл версии заявляет о совместимости, файл конфигурации принимается. В противном случае он игнорируется.
Имя файла версии пакета должно совпадать с именем файла конфигурации пакета, но к нему добавлены -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 - Имя пакета
-
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 устанавливает следующие переменные для использования проектом:
-
<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, определенном ранее командой install(TARGETS). Эта команда генерирует файл ClimbingStatsTargets.cmake для хранения целевых объектов IMPORTED, подходящих для использования зависимыми пакетами, и организует его установку в lib/cmake/ClimbingStats. Сгенерированные файлы ClimbingStatsConfigVersion.cmake и cmake/ClimbingStatsConfig.cmake устанавливаются в то же место, завершая создание пакета.
Сгенерированные целевые объекты IMPORTED имеют соответствующие свойства, определяющие их требования к использованию, такие как INTERFACE_INCLUDE_DIRECTORIES, INTERFACE_COMPILE_DEFINITIONS и другие соответствующие встроенные свойства INTERFACE_. Также в сгенерированные целевые объекты IMPORTED распространяются варианты пользовательских свойств, перечисленные в COMPATIBLE_INTERFACE_STRING и другие Свойства совместимого интерфейса. В данном случае, 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.9/manual/cmake-packages.7.html