Spec-Zone.ru › CMake 3.25

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 предназначен для библиотек только с заголовками или аналогичных пакетов без двоичных файлов.

Добавлена в версии 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:

set(INCLUDE_INSTALL_DIR include/ ... CACHE )
set(LIB_INSTALL_DIR lib/ ... CACHE )
set(SYSCONFIG_INSTALL_DIR etc/foo/ ... CACHE )
#...
include(CMakePackageConfigHelpers)
configure_package_config_file(FooConfig.cmake.in
  ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
  INSTALL_DESTINATION ${LIB_INSTALL_DIR}/Foo/cmake
  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 ${LIB_INSTALL_DIR}/Foo/cmake )

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–2022 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.24/module/CMakePackageConfigHelpers.html

Spec-Zone.ru

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