Spec-Zone.ru › CMake 3.22

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 жёстко кодируют абсолютные расположения каталогов, а 4-й вариант работает только в том случае, если логика определения 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() для установки каталогов и расположения файлов. В дополнение к установке переменной, он также проверяет, существует ли указанный файл или каталог на самом деле, и возвращает ошибку в противном случае. Это гарантирует, что созданный файл 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.22/module/CMakePackageConfigHelpers.html

Spec-Zone.ru

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