Spec-Zone.ru › CMake 3.13

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.

Если передаётся аргумент 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> )

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

Внутренне этот макрос выполняет 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–2019 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.13/module/CMakePackageConfigHelpers.html

Spec-Zone.ru

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