Spec-Zone.ru › CMake 3.20

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: COMPATIBILITY_MODE AnyNewerVersion, SameMajorVersion и SameMinorVersion обрабатывают диапазон версий, если он указан (см. команду 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–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.20/module/CMakePackageConfigHelpers.html

Spec-Zone.ru

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