Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Система построения проектов CMake. Учебник.pdf
X
- •Введение
- •Модульное программирование
- •Автоматизация построения проектов
- •Обзор инструментов построения проектов
- •qmake
- •Генераторы
- •Входные файлы
- •Пути
- •Синтаксис
- •Команды
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Основные концепции
- •Строки
- •Свойства
- •Примеры простых проектов
- •Команды общего назначения
- •cmake_minimum_required()
- •project()
- •include()
- •message()
- •Команды описания целей
- •add_executable()
- •add_library()
- •add_subdirectory()
- •Команды настроек целей
- •include_directories()
- •target_include_directories()
- •add_definitions(), add_compile_options()
- •target_compile_definitions()
- •target_compile_options()
- •target_compile_features()
- •target_link_libraries()
- •add_dependencies()
- •Команды обработки данных
- •math()
- •list()
- •Команды управляющих конструкций
- •foreach(), endforeach()
- •Команды работы с файлами
- •get_filename_component()
- •Команды добавления специальных целей
- •configure_file()
- •add_test(), enable_testing()
- •install()
- •add_custom_target()
- •Прочие команды
- •find_package()
- •get_property(), set_property()
- •Виды конфигураций
- •Выражения генераторов
- •Информационные выражения
- •Логические выражения
- •Преобразующие выражения
- •Вспомогательные выражения
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Интерфейс подключения библиотек
- •Подключение заголовочной библиотеки
- •Частичная подмена стандартной библиотеки
- •Интерфейс подключения библиотек
- •Локализация приложения
- •Установка приложения
- •Инструменты разработки
- •Управление версиями
- •Генерирование документации
- •Упражнения
- •Тест рубежного контроля
- •Проектное задание
- •Заключение
- •Библиография
- •Ответы на тесты

2.11. Прочие команды
Другое решение заключается в передаче аргумента
VERBATIM команде add_custom_command().
N
2.11. Прочие команды
2.11.1. find_package()
Команда find_package() предназначена для поиска пакетов CMake. Пакетом (package) называется набор внешних библиотек и инструментов вместе с модулями CMake, предоставляющими информацию о зависимостях для их подключения. Результатом выполнения команды в случае успешного поиска является набор целей и переменных, которые можно использовать в описании проекта (команды target_link_libraries(),
п. 2.6.7 и т. д.).
Для реализации логики поиска пакета нужно выполнить больше действий, чем просто сгенерировать командой
install(EXPORT ...) (п. 2.10.3) модуль для подключения библиотеки, поэтому в данном учебнике эта тема не рассматривается. Зато пользоваться командой find_package() удобнее, особенно для подключения наборов библиотек со сложной организацией. Во многих известных и широко используемых библиотеках уже встроена поддержка их поиска при помощи команды
find_package(), примеры использования можно найти в главе 3.
Команда find_package() поддерживает большое количество настроек при помощи необязательных аргументов, в настоящем руководстве будут рассмотрены только основные из них,
201

2. Основы языка CMake
имеющие наибольшую ценность для конечного пользователя
стороннего пакета. Стоит лишь отметить два режима работы команды:
При помощи конфигурационного файла: этот режим больше
подходит для поиска тех программных пакетов, которые разрабатывались с использованием системы CMake.
В этом случае разработчик стороннего пакета имеет
возможность в описании проекта реализовать правила
для генерирования конфигурационного файла, включая
рассмотренную ранее команду install(EXPORT ...),
а также команды из вспомогательного стандартного
модуля CMakePackageConfigHelpers. В этом случае
во время исполнения команды find_package() система CMake берёт на себя ответственность за автоматическое выполнение таких задач, как проверка
соответствия версий, заполнение стандартных переменных. Вместе с дистрибутивом файлов проекта,
предназначенных для разработчиков, распространяется конфигурационный файл hимя_пакетаiConfig.cmake
или hимя_пакета_в_нижнем_регистреi-config.cmake.
При помощи модуля поиска: этот режим может быть исполь-
зован для тех пакетов, которые разрабатывались без ис-
202
пользования системы CMake. В этом случае разработчик,
не имеющий отношения к разработке стороннего пакета,
может реализовать модуль поиска — модуль CMake с именем Findhимя_пакетаi.cmake, выполняющий поиск пакета
в системе по некоторым правилам. В этом случае модуль

поиска должен реализовать собственную логику таких за-
дач, как проверка версий на совместимость и т. д. Модуль
поиска, как и любой модуль CMake, может располагаться
в любом из каталогов, перечисленных в специальной пе-
ременной CMAKE_MODULE_PATH. Система CMake поставляет-
ся с большим количеством (более 140) модулей поиска для
основных популярных программных пакетов.
Синтаксис команды для выполнения в режиме конфигурационного файла:
find_package(
hимя_пакетаifhверсияi
f f
COMPONENTS
f
CONFIG
f
NAMES hимя1i ... hимяnig)
g f
hкомпонент1i ... hкомпонентni
NO_MODULE
g f
g
EXACT
g f
QUIET
2.11. Прочие команды
g f
REQUIRED
g
g g
Здесь первый аргумент определяет имя пакета, после которого может быть указана версия. Команда найдёт пакет в системе, совместимый с указанной версией. Если таких пакетов окажется несколько, будет получена информация о произвольном
из них.
— При помощи необязательного аргумента EXACT можно
определить, что необходим поиск только указанной вер-
сии пакета.
— Указание необязательного аргумента QUIET приводит к то-
му, что в случае неудачного поиска не будет выведено со-
общения об этом.
203

2. Основы языка CMake
— Использование необязательного аргумента REQUIRED при-
водит к тому, что в случае неудачного поиска будет прервана работа CMake, как при использовании команды
message(FATAL_ERROR ...) (п. 2.4.4). По умолчанию выполнение CMake продолжается, и факт успешности поиска пакета можно определить при помощи проверки значений специальных переменных (см. далее).
— После необязательного аргумента COMPONENTS можно ука-
зать имена компонент пакета, которые требуется загрузить. Крупные пакеты, такие как Qt, могут состоять из множества компонент, причём для построения конкретных
приложений далеко не все из них нужны (см. пример
на с. 300). Если указан аргумент REQUIRED, аргумент
COMPONENTS можно пропустить.
— При помощи необязательного аргумента CONFIG или его
синонима NO_MODULE можно явно указать, что команда
find_package() должна работать в режиме конфигурационного файла. Если не указывать настройки, специфичные
для этого режима, синтаксис команды полностью совпадает с синтаксисом для режима модуля поиска. По умолчанию в таком случае CMake сначала пытается запустить команду в режиме модуля поиска, и, если его найти не удаётся, запускается режим конфигурационного файла.
— После необязательного аргумента NAMES можно указать од-
но или несколько альтернативных имён, которые будут использованы вместо имени пакета (см. далее).
204

2.11. Прочие команды
Для каждого указанного имени пакета (первый аргумент команды, а также все последующие за аргументом
NAMES) команда find_package() ищет файлы с именами вида hимяiConfig.cmake и hимя_в_нижнем_регистреi-config.cmake
в ряде каталогов (аналогично командам find_file() и т. п.,
п. 2.9.2), среди которых основное значение имеют следующие:
1) Каталоги, перечисленные в специальной переменной
CMake CMAKE_PREFIX_PATH. В системе OS X также исполь-
зуются специальные переменные CMAKE_FRAMEWORK_PATH
и CMAKE_APPBUNDLE_PATH для поиска каркасов и пакетов
приложений.
2) Каталоги, перечисленные в переменных окружения с именами вида hимя_пакетаi_DIR, а также в одноимённых к переменным CMake из предыдущего пункта.
3) Перечисленные в стандартной переменной окружения
PATH.
4) Перечисленные в пользовательском реестре пакетов —
специальной базе имён и путей установки пакетов.
В Windows для этого используется ветвь реестра пользователя (внутри корня HKEY_CURRENT_USER), в POSIX-совместимых системах — подкаталог .cmake/packages домашнего
каталога пользователя.
5) Перечисленные в системном реестре пакетов. В Windows
для этого используется ветвь системного реестра (внутри
корня HKEY_LOCAL_MACHINE), в других системах это хранилище не реализовано.
205

2. Основы языка CMake
В каждом из этих каталогов команда ищет указанные файлы дополнительно в подкаталогах с фиксированными именами
(например, CMake в Windows и т. д.). В случае нахождения файла он запускается на исполнение системой CMake. По результатам поиска системой CMake автоматически заполняется ряд переменных (табл. 2.13).
Таблица 2.13
Переменные, заполняемые по результатам поиска пакета
Переменная Значение
hимя_пакетаi_FOUND Устанавливается
в TRUE, если пакет
найден, и в FALSE, если
нет
hимя_пакетаi_DIR Переменная кэша, в ко-
торую записывается
путь к каталогу, содержащему найденный
файл конфигурации
hимя_пакетаi_CONFIG Содержит полный путь
к файлу конфигурации
hимя_пакетаi_CONSIDERED_CONFIGS Содержит список путей
206
к файлам конфигураций, которые были просмотрены для поиска
подходящей версии

2.11. Прочие команды
Окончание табл. 2.13
Переменная Значение
hимя_пакетаi_CONSIDERED_VERSIONS Содержит список путей
рассмотренных версий,
соответствующий списку в предыдущей переменной. Значения этих
переменных можно выводить на печать для
отладки процесса поиска подходящей версии
пакета
Эти переменные можно использовать, например, для про-
верки успешности поиска.
ПРИМЕР
Пусть требуется обеспечить построение сложного проекта,
часть целей которого использует библиотеки Qt для реализации
пользовательского интерфейса. Если эти библиотеки отсутствуют в системе, требуется только выполнить построение остальных целей. Эту задачу можно решить при помощи следующего
фрагмента кода:
# ...
find_package(Qt5Widgets)
207

2. Основы языка CMake
set(MY_BUILD_GUI_APP ${Qt5Widgets_FOUND})
if(MY_BUILD_GUI_APP)
add_executable(
my_gui my_gui.cpp main_window.cpp main_window.h)
target_link_libraries(my_gui Qt5::Widgets)
# ...
else()
message(
WARNING "The GUI part will not be built")
endif()
Здесь используется команда find_package() для поиска
пакета Qt5Widgets. Результат успешности поиска записывается
в переменную Qt5Widgets_FOUND, значение которой сохраняется в переменную MY_BUILD_GUI_APP для дальнейшего использования. В случае успеха к проекту добавляется цель my_gui, которая связывается с библиотекой Qt Widgets (см. п. 3.3.1). ∗
Синтаксис команды find_package() для выполнения в режиме модуля поиска:
find_package(
hимя_пакетаifhверсияi
f
g
g f
EXACT
g f
QUIET
g f
g
MODULE
REQUIRED
f f
COMPONENTS
g f
hкомпонент
i ... hкомпонент
1,1
1,m
g g
i
f
OPTIONAL_COMPONENTS hкомпонент
i ... hкомпонент
2,1
2,n
ig)
208

2.11. Прочие команды
Большинство аргументов этой формы команды совпадает
с аргументами команды в режиме конфигурационного файла.
Ниже приведено описание аргументов, специфических для режима модуля поиска:
— Необязательный аргумент MODULE явно указывает, что ко-
манда должна запускаться в этом режиме и не запускать-
ся в режиме конфигурационного файла, если соответству-
ющий модуль поиска не будет найден.
— После необязательного аргумента OPTIONAL_COMPONENTS
перечисляются имена необязательных компонент пакета.
В этом режиме модуль поиска отвечает за заполнение переменных, перечисленных в табл. 2.13, а также любых других,
приведённых в документации к модулю.
Замечание: команде find_package() необходимо передавать
имя пакета точно в тех же регистрах символов, как оно указано в имени файла модуля поиска или конфигурационного файла (если только он не имеет форму нижнего регистра, см. выше).
Например, нужно указывать имя «Git» вместо «git» (п. 3.5.1).
Эта ошибка не будет проявляться на платформах с нечувствительными к регистру имён файловыми системами.
N
2.11.2. get_property(), set_property()
get_property(
hимя_переменнойi
hсущностьi
209

2. Основы языка CMake
PROPERTY hимя_свойстваi
f
SET
hсущностьi F
GLOBAL
DIRECTORYfhкаталогi
TARGET hимя_целиi
SOURCE hфайлi
INSTALL hфайлi
TEST hимя_тестаi
CACHE hимя_переменнойi
DEFINEDg)
g
VARIABLE
set_property(
hсущностиi
f
APPEND
PROPERTY hимя_свойстваi
g f
APPEND_STRING
g
f
hзначение1i ... hзначениеmig)
hсущностиi F
GLOBAL
DIRECTORYfhкаталогi
TARGETfhимя_цели1i ... hимя_целиni
SOURCEfhфайл1i ... hфайлni
INSTALLfhфайл1i ... hфайлni
TESTfhимя_теста1i ... hимя_тестаni
CACHEfhимя_переменной1i ... hимя_переменнойni
g
g
g
g
g
g
210
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
