Spec-Zone.ru › CMake 3.18

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>
  [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 вместо использования этого макроса.

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

Примечание

ARCH_INDEPENDENT предназначен для библиотек только для заголовков или аналогичных пакетов без библиотек.

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

Spec-Zone.ru

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