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 переносимым. Использование:
- Напишите файл
FooConfig.cmake.in, как вы привыкли - Вставьте строку, содержащую только строку
@PACKAGE_INIT@ - Вместо
set(FOO_DIR "@SOME_INSTALL_DIR@"), используйтеset(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@")(это должно быть после строки@PACKAGE_INIT@) - Вместо использования обычной команды
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.21/module/CMakePackageConfigHelpers.html