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() при создании файла <Name>Config.cmake или <Name>-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.
Если передан аргумент 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(<package_name>) должен вызываться в конце файла 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|ExactVersion> )
Записывает файл для использования в качестве файла <package>ConfigVersion.cmake в <filename>. Подробнее см. документацию к find_package().
<filename> — имя выходного файла, оно должно быть в дереве сборки. <major.minor.patch> — номер версии проекта, который будет установлен.
Если VERSION не задан, используется переменная PROJECT_VERSION. Если она не установлена, происходит ошибка.
Режим COMPATIBILITY AnyNewerVersion означает, что установленная версия пакета будет считаться совместимой, если она новее или точно такая же, как запрошенная версия. Этот режим следует использовать для пакетов, которые полностью совместимы, также и между основными версиями. Если используется SameMajorVersion, то поведение отличается от AnyNewerVersion, так как номер основной версии должен быть таким же, как запрошенная, например, версия 2.0 не будет считаться совместимой, если запрошена версия 1.0. Этот режим следует использовать для пакетов, которые гарантируют обратную совместимость в рамках одной основной версии. Если используется ExactVersion, то пакет считается совместимым только если запрошенная версия точно совпадает с собственной версией пакета (без учёта дополнительной версии). Например, версия 1.2.3 пакета считается совместимой только с запрошенной версией 1.2.3. Этот режим предназначен для пакетов без гарантий совместимости. Если ваш проект имеет более сложные правила соответствия версий, вам потребуется написать свой собственный файл ConfigVersion.cmake вместо использования этого макроса.
Внутренне этот макрос выполняет configure_file() для создания результирующего файла версии. В зависимости от COMPATIBLITY, используется либо файл BasicConfigVersion-SameMajorVersion.cmake.in, либо BasicConfigVersion-AnyNewerVersion.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.10/module/CMakePackageConfigHelpers.html