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 представленных выше варианта недостаточны, поскольку первые три жёстко кодируют абсолютные пути к директориям, а четвёртый вариант работает только если логика определения 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() для установки каталогов и файлов. В дополнение к установке переменной, он также проверяет, что указанный файл или каталог реально существует, и при этом возвращает ошибку. Это гарантирует, что создаваемый файл 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, поведение отличается от 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.7/module/CMakePackageConfigHelpers.html