Spec-Zone.ru › CMake 3.26

CMakePackageConfigHelpers

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

Добавляет команды configure_package_config_file() и write_basic_package_version_file().

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

configure_package_config_file

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

configure_package_config_file(<input> <output>
  INSTALL_DESTINATION <path>
  [PATH_VARS <var1> <var2> ... <varN>]
  [NO_SET_AND_CHECK_MACRO]
  [NO_CHECK_REQUIRED_COMPONENTS_MACRO]
  [INSTALL_PREFIX <path>]
  )

Следует использовать configure_package_config_file() вместо обычной команды configure_file() при создании файла <PackageName>Config.cmake или <PackageName>-config.cmake для установки проекта или библиотеки. Это помогает сделать релоцируемым получившийся пакет, избегая жёстко закодированных путей в установленных файлах Config.cmake.

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

set(FOO_INCLUDE_DIR   "@CMAKE_INSTALL_FULL_INCLUDEDIR@" )
set(FOO_DATA_DIR   "@CMAKE_INSTALL_PREFIX@/@RELATIVE_DATA_INSTALL_DIR@" )
set(FOO_ICONS_DIR   "@CMAKE_INSTALL_PREFIX@/share/icons" )
#...logic to determine installedPrefix from the own location...
set(FOO_CONFIG_DIR  "${installedPrefix}/@CONFIG_INSTALL_DIR@" )

Все 4 приведенные выше варианта недостаточны, так как первые 3 используют абсолютные пути, а четвёртый вариант работает только если логика определения installedPrefix верна и CONFIG_INSTALL_DIR содержит относительный путь, что в общем случае гарантировать нельзя. Это приводит к тому, что получившийся файл FooConfig.cmake будет работать плохо в Windows и OSX, где пользователи привыкли выбирать место установки двоичного пакета во время установки, независимо от того, как был задан CMAKE_INSTALL_PREFIX при построении/cmake.

Использование configure_package_config_file помогает. При правильном использовании, он делает получившийся файл FooConfig.cmake переносимым. Использование:

  1. напишите файл FooConfig.cmake.in как обычно
  2. вставьте строку, содержащую только строку @PACKAGE_INIT@
  3. вместо set(FOO_DIR "@SOME_INSTALL_DIR@"), используйте set(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@") (эта строка должна идти после строки @PACKAGE_INIT@)
  4. вместо обычной команды configure_file(), используйте configure_package_config_file()

Аргументы <input> и <output> являются входным и выходным файлами, так же, как и в configure_file().

<path> задаваемый INSTALL_DESTINATION должен быть местом назначения, куда будет установлен файл FooConfig.cmake. Этот путь может быть абсолютным или относительным к пути INSTALL_PREFIX.

Переменные <var1> до <varN>, передаваемые как PATH_VARS, являются переменными, содержащими места установки. Для каждой из них макрос создаст вспомогательную переменную PACKAGE_<var...>. Эти вспомогательные переменные должны использоваться в файле FooConfig.cmake.in для установки местоположения. Они рассчитываются configure_package_config_file, чтобы всегда быть относительными к месту установки пакета. Это работает как для относительных, так и для абсолютных путей. Для абсолютных путей это работает только если абсолютный путь является подкаталогом INSTALL_PREFIX.

Добавлена в версии 3.1: Если передан аргумент INSTALL_PREFIX, он используется в качестве базового пути для расчёта всех относительных путей. Аргумент <path> должен быть абсолютным путём. Если этот аргумент не передан, вместо него будет использована переменная CMAKE_INSTALL_PREFIX. Значение по умолчанию подходит для генерации файла FooConfig.cmake для использования вашего пакета из дерева установки. При генерации файла FooConfig.cmake для использования вашего пакета из дерева сборки следует использовать этот параметр.

По умолчанию configure_package_config_file также генерирует два вспомогательных макроса, set_and_check() и check_required_components() в файл FooConfig.cmake.

set_and_check() следует использовать вместо обычной команды set() для установки каталогов и расположений файлов. Помимо установки переменной, он также проверяет, что указанный файл или каталог реально существует, и в противном случае завершается ошибкой с FATAL_ERROR. Это гарантирует, что созданный файл FooConfig.cmake не содержит неправильных ссылок. При использовании NO_SET_AND_CHECK_MACRO, этот макрос не генерируется в файл FooConfig.cmake.

check_required_components(<PackageName>) должен вызываться в конце файла FooConfig.cmake. Этот макрос проверяет, были ли найдены все необходимые, не опциональные компоненты, и если это не так, устанавливает переменную Foo_FOUND в FALSE, чтобы пакет считался не найденным. Это делается путём проверки переменных Foo_<Component>_FOUND для всех запрошенных необходимых компонентов. Этот макрос следует вызывать, даже если пакет не предоставляет каких-либо компонентов, чтобы убедиться, что пользователи не ошибаются в указании компонентов. При использовании опции NO_CHECK_REQUIRED_COMPONENTS_MACRO, этот макрос не генерируется в файл FooConfig.cmake.

Пример см. в документации для write_basic_package_version_file().

Генерация файла версии пакета

write_basic_package_version_file

Создаёт файл версии для проекта:

write_basic_package_version_file(<filename>
  [VERSION <major.minor.patch>]
  COMPATIBILITY <AnyNewerVersion|SameMajorVersion|SameMinorVersion|ExactVersion>
  [ARCH_INDEPENDENT] )

Записывает файл для использования в качестве файла <PackageName>ConfigVersion.cmake в <filename>. Подробнее см. документацию к команде find_package().

<filename> — имя выходного файла, оно должно находиться в дереве сборки. <major.minor.patch> — номер версии устанавливаемого проекта.

Если VERSION не указан, используется переменная PROJECT_VERSION. Если она не задана, возникает ошибка.

Режим COMPATIBILITY AnyNewerVersion означает, что установленная версия пакета будет считаться совместимой, если она новее или идентична запрошенной версии. Этот режим следует использовать для пакетов, которые полностью совместимы в обратном направлении, также и между версиями. Если используется SameMajorVersion, поведение отличается от AnyNewerVersion, так как номер главной версии должен быть таким же, как запрошенный, например, версия 2.0 не будет считаться совместимой, если запрошена версия 1.0. Этот режим следует использовать для пакетов, которые гарантируют обратную совместимость в пределах одной главной версии. Если используется SameMinorVersion, поведение такое же, как у SameMajorVersion, но и главная, и второстепенная версии должны совпадать с запрошенной, например, версия 0.2 не будет совместима с запрошенной версией 0.1. Если используется ExactVersion, пакет считается совместимым только в том случае, если запрошенная версия точно совпадает с собственной версией пакета (без учёта разностной версии). Например, версия 1.2.3 пакета считается совместимой только с запрошенной версией 1.2.3. Этот режим предназначен для пакетов без гарантий совместимости. Если в вашем проекте есть более сложные правила соответствия версий, вам потребуется создать свой собственный пользовательский файл ConfigVersion.cmake вместо использования этого макроса.

Добавлена в версии 3.11: Режим совместимости SameMinorVersion.

Добавлена в версии 3.14: Если передан аргумент ARCH_INDEPENDENT, установленная версия пакета будет считаться совместимой, даже если она была скомпилирована для другой архитектуры, чем запрошенная архитектура. В противном случае будет произведена проверка архитектуры, и пакет будет считаться совместимым только если архитектура совпадает точно. Например, если пакет скомпилирован для 32-битной архитектуры, пакет будет считаться совместимым только для использования на 32-битной архитектуре, если не передан аргумент ARCH_INDEPENDENT, в этом случае пакет считается совместимым для любой архитектуры.

Примечание

ARCH_INDEPENDENT предназначен для header-only библиотек или аналогичных пакетов без двоичных файлов.

Добавлена в версии 3.19: Файл версии, сгенерированный аргументами AnyNewerVersion, SameMajorVersion и SameMinorVersion команды COMPATIBILITY, обрабатывают диапазон версий, если он указан (см. команду find_package() для подробностей). Режим ExactVersion несовместим с диапазонами версий и будет выводить предупреждение автору, если таковой указан.

Внутренне, этот макрос выполняет configure_file() для создания получившегося файла версии. В зависимости от COMPATIBILITY, используется соответствующий файл BasicConfigVersion-<COMPATIBILITY>.cmake.in. Обратите внимание, что эти файлы являются внутренними для CMake и вы не должны вызывать configure_file() на них сами, но их можно использовать в качестве отправной точки для создания более сложных пользовательских файлов ConfigVersion.cmake.

Пример генерации файлов пакета

Пример использования как configure_package_config_file(), так и write_basic_package_version_file():

CMakeLists.txt:

include(GNUInstallDirs)
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/Foo
    CACHE PATH "Location of header files" )
set(SYSCONFIG_INSTALL_DIR ${CMAKE_INSTALL_SYSCONFDIR}/foo
    CACHE PATH "Location of configuration files" )
#...
include(CMakePackageConfigHelpers)
configure_package_config_file(FooConfig.cmake.in
  ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
  INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Foo
  PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)
write_basic_package_version_file(
  ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
  VERSION 1.2.3
  COMPATIBILITY SameMajorVersion )
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
              ${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Foo )

FooConfig.cmake.in:

set(FOO_VERSION x.y.z)
...
@PACKAGE_INIT@
...
set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")

check_required_components(Foo)

© 2000–2023 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.26/module/CMakePackageConfigHelpers.html

Spec-Zone.ru

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