Spec-Zone.ru › CMake 3.12

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
Истина, если версия является точной
PACKAGE_VERSION_COMPATIBLE
Истина, если версия совместима
PACKAGE_VERSION_UNSUITABLE
Истина, если не подходит в качестве любой версии

Файлы версии загружаются вложенным способом, поэтому они могут свободно устанавливать любые переменные, которые они желают, как часть своего вычисления. Команда find_package очищает область видимости, когда файл версии завершает работу и проверил переменные вывода. Когда файл версии заявляет, что является приемлемым соответствием запрошенной версии, команда find_package устанавливает следующие переменные для использования проектом:

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

Переменные сообщают о версии пакета, который был фактически найден. Часть имени <package> соответствует аргументу, заданному команде find_package().

Создание пакетов

Обычно, зависимость от верхнего уровня (upstream) основана на самом 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, подходящих для использования последующими зависимостями (downstreams), и организует его установку в 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 при использовании зависимостями (downstreams) с помощью команды 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")

Поскольку это позволяет зависимостям (downstreams) использовать цели 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, зависимостям (downstreams) также необходимо найти пакет 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(), они перечислены в переменной <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_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 предоставляет два центральных расположения для регистрации пакетов, которые были построены или установлены где-либо в системе:

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

Регистры особенно полезны для помощи проектам в поиске пакетов в нестандартных расположениях установки или непосредственно в своих собственных деревьях построения. Проект может заполнить либо пользовательский, либо системный регистр (используя собственные средства, см. ниже) для указания своего расположения. В любом случае пакет должен хранить в зарегистрированном месте файл конфигурации пакета (<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.12/manual/cmake-packages.7.html

Spec-Zone.ru

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