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