Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Система построения проектов CMake. Учебник.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆

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
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]