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.
Если передаётся аргумент 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 вместо использования этого макроса.
Если указан ARCH_INDEPENDENT, установленная версия пакета будет считаться совместимой даже если она была скомпилирована для другой архитектуры, чем запрошенная архитектура. В противном случае будет выполнена проверка архитектуры, и пакет будет считаться совместимым только в том случае, если архитектура совпадает точно. Например, если пакет скомпилирован для 32-битной архитектуры, пакет считается совместимым только при использовании на 32-битной архитектуре, если не указан ARCH_INDEPENDENT, в этом случае пакет считается совместимым на любой архитектуре.
Примечание
ARCH_INDEPENDENT предназначен для библиотек только с заголовками или аналогичных пакетов без двоичных файлов.
Внутренне, этот макрос выполняет 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–2020 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.16/module/CMakePackageConfigHelpers.html