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|SameMinorVersion|ExactVersion> )
Записывает файл для использования в качестве файла <package>ConfigVersion.cmake в <filename>. Подробности см. в документации для find_package().
<filename> — это имя выходного файла, оно должно находиться в дереве сборки. <major.minor.patch> — это номер версии проекта, который будет установлен.
Если VERSION не задан, используется переменная PROJECT_VERSION. Если она не задана, выдаётся ошибка.
Режим COMPATIBILITY AnyNewerVersion означает, что установленная версия пакета будет считаться совместимой, если она новее или точно такая же, как запрошенная версия. Этот режим следует использовать для пакетов, которые полностью совместимы назад, также через основные версии. Если вместо SameMajorVersion используется AnyNewerVersion, то поведение отличается от AnyNewerVersion тем, что номер основной версии должен быть таким же, как запрошенный, например, версия 2.0 не будет считаться совместимой, если запрошена версия 1.0. Этот режим следует использовать для пакетов, которые гарантируют обратную совместимость в рамках одной основной версии. Если используется SameMinorVersion, то поведение такое же, как у SameMajorVersion, но и основная, и второстепенная версии должны быть такими же, как запрошенные, например, версия 0.2 не будет совместима, если запрошена версия 0.1. Если используется ExactVersion, пакет считается совместимым только в том случае, если запрошенная версия точно совпадает с его собственной версией (не учитывая версию-твик). Например, версия 1.2.3 пакета считается совместимой только с запрошенной версией 1.2.3. Этот режим предназначен для пакетов без гарантий совместимости. Если ваш проект имеет более сложные правила сопоставления версий, вам необходимо написать свой собственный пользовательский файл ConfigVersion.cmake вместо использования этого макроса.
Внутренне этот макрос выполняет 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–2019 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.12/module/CMakePackageConfigHelpers.html