Spec-Zone.ru › CMake 3.13

cmake-packages(7)

  • Введение
  • Использование пакетов
    • Пакеты с конфигурационными файлами
    • Пакеты с модулями поиска
  • Структура пакета
    • Файл конфигурации пакета
    • Файл версии пакета
  • Создание пакетов
    • Создание файла конфигурации пакета
      • Создание файла конфигурации пакета для дерева сборки
    • Создание переносимых пакетов
  • Реестр пакетов
    • Пользовательский реестр пакетов
    • Системный реестр пакетов
    • Отключение реестра пакетов
    • Пример реестра пакетов
    • Владение реестром пакетов

Введение

Пакеты предоставляют информацию о зависимостях для систем сборки CMake. Пакеты находятся с помощью команды find_package(). Результатом использования find_package является либо набор IMPORTED целей, либо набор переменных, соответствующих информации, относящейся к сборке.

Использование пакетов

CMake предоставляет прямую поддержку для двух форм пакетов: пакеты с конфигурационными файлами и пакеты с модулями поиска. Косвенная поддержка pkg-config пакетов также предоставляется через модуль FindPkgConfig. Во всех случаях базовая форма вызовов find_package() одинакова:

find_package(Qt4 4.7.0 REQUIRED) # CMake provides a Qt4 find-module
find_package(Qt5Core 5.1.0 REQUIRED) # Qt provides a Qt5 package config file.
find_package(LibXml2 REQUIRED) # Use pkg-config via the LibXml2 find-module

В тех случаях, когда известно, что конфигурационный файл пакета предоставляется вышестоящим уровнем, и должен использоваться только он, можно передать ключевое слово CONFIG команде find_package():

find_package(Qt5Core 5.1.0 CONFIG REQUIRED)
find_package(Qt5Gui 5.1.0 CONFIG)

Аналогично, ключевое слово MODULE указывает на использование только модуля поиска:

find_package(Qt4 4.7.0 MODULE REQUIRED)

Явное указание типа пакета улучшает сообщение об ошибке, отображаемое пользователю, если пакет не найден.

Оба типа пакетов также поддерживают указание компонентов пакета, либо после ключевого слова REQUIRED:

find_package(Qt5 5.1.0 CONFIG REQUIRED Widgets Xml Sql)

либо как отдельный список COMPONENTS:

find_package(Qt5 5.1.0 COMPONENTS Widgets Xml Sql)

либо как отдельный список OPTIONAL_COMPONENTS:

find_package(Qt5 5.1.0 COMPONENTS Widgets
                       OPTIONAL_COMPONENTS Xml Sql
)

Обработка COMPONENTS и OPTIONAL_COMPONENTS определяется пакетом.

Установив переменную CMAKE_DISABLE_FIND_PACKAGE_<PackageName> в значение TRUE, поиск пакета <PackageName> не будет производиться, и он всегда будет NOTFOUND.

Пакеты с конфигурационными файлами

Пакет с конфигурационным файлом — это набор файлов, предоставляемых вышестоящими компонентами для использования нижестоящими. CMake ищет файлы конфигурации пакета в ряде мест, как описано в документации к команде find_package(). Самый простой способ сообщить CMake, чтобы он искал пакет в нестандартном префиксе, заключается в установке переменной кэша CMAKE_PREFIX_PATH.

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

При использовании пакета с конфигурационным файлом также автоматически устанавливается набор переменных, предоставляющих информацию о статусе пакета. Переменная <PackageName>_FOUND устанавливается в значение true или false, в зависимости от того, был ли пакет найден. Переменная кэша <PackageName>_DIR устанавливается в расположение файла конфигурации пакета.

Пакеты с модулями поиска

Модуль поиска — это файл с набором правил для поиска необходимых компонентов зависимости, в первую очередь заголовочных файлов и библиотек. Обычно модуль поиска необходим, когда вышестоящий компонент не создан с помощью CMake или не достаточно поддерживает CMake, чтобы предоставить файл конфигурации пакета другим способом. В отличие от файла конфигурации пакета, он не поставляется с вышестоящим компонентом, но используется нижестоящим компонентом для поиска файлов, основываясь на предположениях о местоположении файлов с помощью платформозависимых подсказок.

В отличие от случая с предоставленным вышестоящим компонентом файлом конфигурации пакета, нет единственной точки отсчета, которая определяет, что пакет найден, поэтому переменная <PackageName>_FOUND не устанавливается автоматически командой find_package(). Однако можно ожидать, что она будет установлена по соглашению, и её должен установить автор модуля поиска. Аналогично, нет переменной <PackageName>_DIR, но каждый из артефактов, таких как расположение библиотек и заголовочных файлов, предоставляет отдельную переменную кэша.

См. руководство cmake-developer(7) для получения дополнительной информации о создании файлов модулей поиска.

Структура пакета

Пакет с конфигурационным файлом состоит из файла конфигурации пакета и необязательно файла версии пакета, предоставляемых вместе с проектом.

Файл конфигурации пакета

Представьте проект Foo, который устанавливает следующие файлы:

<prefix>/include/foo-1.2/foo.h
<prefix>/lib/foo-1.2/libfoo.a

Он также может предоставлять файл конфигурации пакета CMake:

<prefix>/lib/cmake/foo-1.2/FooConfig.cmake

содержимое которого определяет IMPORTED цели или переменные, такие как:

# ...
# (compute PREFIX relative to file location)
# ...
set(Foo_INCLUDE_DIRS ${PREFIX}/include/foo-1.2)
set(Foo_LIBRARIES ${PREFIX}/lib/foo-1.2/libfoo.a)

Если другой проект хочет использовать Foo, ему нужно только найти файл FooConfig.cmake и загрузить его, чтобы получить всю необходимую информацию о расположении содержимого пакета. Так как файл конфигурации пакета предоставляется установкой пакета, он уже знает все расположения файлов.

Команда find_package() может использоваться для поиска файла конфигурации пакета. Эта команда строит набор префиксов установки и ищет под каждым префиксом в нескольких местах. Учитывая имя Foo, она ищет файл, названный FooConfig.cmake или foo-config.cmake. Полный набор расположений указан в документации к команде find_package(). Одно из мест поиска:

<prefix>/lib/cmake/Foo*/

где Foo* — это выражение поиска, игнорирующее регистр. В нашем примере выражение поиска будет соответствовать <prefix>/lib/cmake/foo-1.2 и файл конфигурации пакета будет найден.

После нахождения файл конфигурации пакета сразу же загружается. Он, вместе с файлом версии пакета, содержит всю информацию, необходимую проекту для использования пакета.

Файл версии пакета

Когда команда find_package() находит кандидатный файл конфигурации пакета, она ищет рядом с ним файл версии. Файл версии загружается, чтобы проверить, соответствует ли версия пакета запрошенной версии. Если файл версии утверждает совместимость, файл конфигурации принимается. В противном случае он игнорируется.

Имя файла версии пакета должно совпадать с именем файла конфигурации пакета, но к нему добавляются -version или Version перед расширением .cmake. Например, файлы:

<prefix>/lib/cmake/foo-1.3/foo-config.cmake
<prefix>/lib/cmake/foo-1.3/foo-config-version.cmake

и:

<prefix>/lib/cmake/bar-4.2/BarConfig.cmake
<prefix>/lib/cmake/bar-4.2/BarConfigVersion.cmake

являются парами файлов конфигурации пакета и соответствующих файлов версии пакета.

Когда команда find_package() загружает файл версии, она сначала устанавливает следующие переменные:

PACKAGE_FIND_NAME
<PackageName>
PACKAGE_FIND_VERSION
Полная строка запрошенной версии
PACKAGE_FIND_VERSION_MAJOR
Основная версия, если запрошена, в противном случае 0
PACKAGE_FIND_VERSION_MINOR
Вспомогательная версия, если запрошена, в противном случае 0
PACKAGE_FIND_VERSION_PATCH
Версия исправления, если запрошена, в противном случае 0
PACKAGE_FIND_VERSION_TWEAK
Версия улучшения, если запрошена, в противном случае 0
PACKAGE_FIND_VERSION_COUNT
Количество компонентов версии, от 0 до 4

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

PACKAGE_VERSION
Полная строка предоставленной версии
PACKAGE_VERSION_EXACT
Истина, если версия является точным соответствием
PACKAGE_VERSION_COMPATIBLE
Истина, если версия совместима
PACKAGE_VERSION_UNSUITABLE
Истина, если версия непригодна

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

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

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

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

Обычно, зависимость от верхнего уровня зависит от самого CMake и может использовать некоторые средства CMake для создания файлов пакета. Рассмотрим верхний уровень, который предоставляет единственную общую библиотеку:

project(UpstreamLib)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)

set(Upstream_VERSION 3.4.1)

include(GenerateExportHeader)

add_library(ClimbingStats SHARED climbingstats.cpp)
generate_export_header(ClimbingStats)
set_property(TARGET ClimbingStats PROPERTY VERSION ${Upstream_VERSION})
set_property(TARGET ClimbingStats PROPERTY SOVERSION 3)
set_property(TARGET ClimbingStats PROPERTY
  INTERFACE_ClimbingStats_MAJOR_VERSION 3)
set_property(TARGET ClimbingStats APPEND PROPERTY
  COMPATIBLE_INTERFACE_STRING ClimbingStats_MAJOR_VERSION
)

install(TARGETS ClimbingStats EXPORT ClimbingStatsTargets
  LIBRARY DESTINATION lib
  ARCHIVE DESTINATION lib
  RUNTIME DESTINATION bin
  INCLUDES DESTINATION include
)
install(
  FILES
    climbingstats.h
    "${CMAKE_CURRENT_BINARY_DIR}/climbingstats_export.h"
  DESTINATION
    include
  COMPONENT
    Devel
)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
  VERSION ${Upstream_VERSION}
  COMPATIBILITY AnyNewerVersion
)

export(EXPORT ClimbingStatsTargets
  FILE "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsTargets.cmake"
  NAMESPACE Upstream::
)
configure_file(cmake/ClimbingStatsConfig.cmake
  "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfig.cmake"
  COPYONLY
)

set(ConfigPackageLocation lib/cmake/ClimbingStats)
install(EXPORT ClimbingStatsTargets
  FILE
    ClimbingStatsTargets.cmake
  NAMESPACE
    Upstream::
  DESTINATION
    ${ConfigPackageLocation}
)
install(
  FILES
    cmake/ClimbingStatsConfig.cmake
    "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
  DESTINATION
    ${ConfigPackageLocation}
  COMPONENT
    Devel
)

Модуль CMakePackageConfigHelpers предоставляет макрос для создания простого файла ConfigVersion.cmake. Этот файл устанавливает версию пакета. Он читается CMake при вызове find_package() для определения совместимости с запрошенной версией и для установки некоторых переменных, специфичных для версии <PackageName>_VERSION, <PackageName>_VERSION_MAJOR, <PackageName>_VERSION_MINOR и т. д. Команда install(EXPORT) используется для экспорта целевых объектов в ClimbingStatsTargets экспорт-множество, определённое ранее командой install(TARGETS). Эта команда генерирует файл ClimbingStatsTargets.cmake для хранения целевых объектов IMPORTED, подходящих для использования зависимыми проектами, и организует его установку в lib/cmake/ClimbingStats. Сгенерированные файлы ClimbingStatsConfigVersion.cmake и cmake/ClimbingStatsConfig.cmake устанавливаются в ту же папку, завершая создание пакета.

Сгенерированные целевые объекты IMPORTED имеют соответствующие свойства, определённые для их требований использования, такие как INTERFACE_INCLUDE_DIRECTORIES, INTERFACE_COMPILE_DEFINITIONS и другие соответствующие встроенные INTERFACE_ свойства. Вариант INTERFACE пользовательских свойств, перечисленных в COMPATIBLE_INTERFACE_STRING и другие Свойства совместимого интерфейса также распространяются на сгенерированные целевые объекты IMPORTED. В данном случае ClimbingStats_MAJOR_VERSION определяется как строка, которая должна быть совместима среди зависимостей любого зависимого проекта. Установив это пользовательское свойство в этой и следующей версии ClimbingStats, cmake(1) выдаст диагностическое сообщение, если будет попытка использовать версию 3 вместе с версией 4. Пакеты могут использовать такую схему, если разные основные версии пакета предназначены для несовместимости.

NAMESPACE с двойными двоеточиями указан при экспорте целевых объектов для установки. Эта конвенция двойных двоеточий даёт CMake подсказку, что имя является целевым объектом IMPORTED, когда он используется зависимыми проектами с помощью команды target_link_libraries(). Таким образом, CMake может выдать диагностическое сообщение, если пакет, который его предоставляет, ещё не найден.

В данном случае, при использовании install(TARGETS) был указан INCLUDES DESTINATION. Это приводит к тому, что целевые объекты IMPORTED получают INTERFACE_INCLUDE_DIRECTORIES с папкой include в CMAKE_INSTALL_PREFIX. Когда целевой объект IMPORTED используется зависимым проектом, он автоматически использует записи из этого свойства.

Создание файла конфигурации пакета

В данном случае, файл ClimbingStatsConfig.cmake может быть таким простым:

include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")

Поскольку это позволяет зависимым проектам использовать целевые объекты IMPORTED. Если пакет ClimbingStats должен предоставлять макросы, они должны быть в отдельном файле, установленным в том же месте, что и файл ClimbingStatsConfig.cmake, и включён в него.

Это также можно расширить, чтобы охватить зависимости:

# ...
add_library(ClimbingStats SHARED climbingstats.cpp)
generate_export_header(ClimbingStats)

find_package(Stats 2.6.4 REQUIRED)
target_link_libraries(ClimbingStats PUBLIC Stats::Types)

Поскольку целевой объект Stats::Types является зависимостью PUBLIC от ClimbingStats, зависимые проекты также должны найти пакет Stats и связаться с библиотекой Stats::Types. Пакет Stats должен быть найден в файле ClimbingStatsConfig.cmake, чтобы это гарантировать. Макрос find_dependency из CMakeFindDependencyMacro помогает в этом, передавая, является ли пакет REQUIRED, или QUIET и т. д. Все REQUIRED зависимости пакета должны быть найдены в файле Config.cmake:

include(CMakeFindDependencyMacro)
find_dependency(Stats 2.6.4)

include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")

Макрос find_dependency также устанавливает ClimbingStats_FOUND в False, если зависимость не найдена, наряду с диагностическим сообщением о том, что пакет ClimbingStats не может быть использован без пакета Stats.

Если COMPONENTS указаны при использовании зависимым проектом find_package(), они перечислены в переменной <PackageName>_FIND_COMPONENTS. Если конкретный компонент является необязательным, то <PackageName>_FIND_REQUIRED_<comp> будет истинным. Это можно проверить с помощью логики в файле конфигурации пакета:

include(CMakeFindDependencyMacro)
find_dependency(Stats 2.6.4)

include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")

set(_supported_components Plot Table)

foreach(_comp ${ClimbingStats_FIND_COMPONENTS})
  if (NOT ";${_supported_components};" MATCHES _comp)
    set(ClimbingStats_FOUND False)
    set(ClimbingStats_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
  endif()
  include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake")
endforeach()

Здесь ClimbingStats_NOT_FOUND_MESSAGE устанавливается в диагностическое сообщение о том, что пакет не был найден из-за указания неверного компонента. Эта переменная сообщения может быть установлена для любого случая, когда переменная _FOUND установлена в False, и будет отображаться пользователю.

Создание файла конфигурации пакета для дерева сборки

Команда export(EXPORT) создаёт файл определения целевых объектов IMPORTED, который специфичен для дерева сборки и не является переносимым. Это аналогичным образом может быть использовано с соответствующим файлом конфигурации пакета и файлом версии пакета для определения пакета для дерева сборки, который может быть использован без установки. Потребители дерева сборки могут просто убедиться, что CMAKE_PREFIX_PATH содержит каталог сборки или установить ClimbingStats_DIR в <build_dir>/ClimbingStats в кэше.

Создание переносимых пакетов

Переносимый пакет не должен ссылаться на абсолютные пути к файлам на компьютере, на котором пакет построен, если эти файлы не будут существовать на компьютерах, на которые может быть установлен пакет.

Пакеты, созданные с помощью install(EXPORT), предназначены для переносимости, используя пути, относительные к расположению самого пакета. При определении интерфейса целевого объекта для EXPORT, следует помнить, что каталоги включаемых файлов должны быть указаны как относительные пути, относительные к CMAKE_INSTALL_PREFIX:

target_include_directories(tgt INTERFACE
  # Wrong, not relocatable:
  $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/TgtName>
)

target_include_directories(tgt INTERFACE
  # Ok, relocatable:
  $<INSTALL_INTERFACE:include/TgtName>
)

$<INSTALL_PREFIX> generator expression может быть использован как placeholder для префикса установки без создания непереносимого пакета. Это необходимо, если используются сложные выражения генератора:

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 позволяет отключить их с помощью следующих переменных:

  • 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.13/manual/cmake-packages.7.html

Spec-Zone.ru

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