Добавил:
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. Прочие команды
Команды get_property() и set_property() используются для считывания и установки значений свойств (п. 2.2.4). При
считывании значения обязательно указываются:
1) имя переменной, в которую будет считан результат выполнения команды;
2) тип и, если требуется, название сущности, для которой считывается свойство;
3) имя свойства после аргумента PROPERTY.
Тип и название сущности определяются c помощью следу-
ющих аргументов:
GLOBAL: глобальное свойство, имя объекта не требуется.
DIRECTORY: свойство каталога подпроекта (в котором распола-
гается файл CMakeLists.txt). По умолчанию опрашивается свойство каталога, обрабатываемого CMake в настоящий
момент, однако можно задать ранее обработанный каталог. Указывается полный или относительный путь.
TARGET: свойство цели. Указывается имя цели, ранее опреде-
лённой при помощи команды add_executable() (п. 2.5.1)
и т. п.
SOURCE: свойство исходного файла. Указывается путь к файлу
(имеет смысл указывать относительный путь по отноше-
нию к каталогу текущего проекта). Файл должен существовать на диске, но не обязательно должен принадлежать какой-либо из определённых целей. Устанавливаемые свой-
211

2. Основы языка CMake
ства влияют только на цели, добавляемые в текущем подпроекте.
INSTALL: свойство устанавливаемого файла. Указывается путь
к файлу (по отношению к каталогу установки).
TEST: свойство теста. Указывается имя теста, ранее определён-
ное при помощи команды add_test() (п. 2.10.2).
CACHE: свойство переменной кэша. Указывается имя перемен-
ной.
VARIABLE: этот аргумент не задаёт никакой сущности, для кото-
рой будет опрашиваться свойство. Он позволяет использовать команду get_property() для определения состояния
(см. ниже) переменной, имя которой указывается в этом
случае после аргумента PROPERTY.
— Необязательный аргумент команды get_property() (или
его отсутствие) определяет, какую информацию о состоянии свойства нужно записать в переменную:
По умолчанию: возвращается значение свойства. Если
свойство ранее не было установлено или его не существует, возвращается пустая строка.
SET: возвращается логическое значение, определяющее,
ся:
212
было ли ранее установлено свойство.
DEFINED: возвращается логическое значение, указываю-
щее на то, существует ли такое свойство.
При установке значений свойств обязательно указывают-

2.11. Прочие команды
1) тип и, возможно, названия нескольких сущностей, для которых устанавливается свойство;
2) имя свойства после аргумента PROPERTY;
3) набор значений, формирующих список.
Особенностью команды set_property() является возмож-
ность установить одно значение для одного и того же свойства сразу нескольким сущностям одного типа (кроме каталога)
при помощи одной команды. Передаваемые команде последние
аргументы формируют список (п. 2.2.3), определяющий присваиваемое значение.
— Наличие или отсутствие остальных необязательных ар-
гументов команды set_property() определяет способ добавления нового значения к существующим значениям
свойств:
По умолчанию: значения будут присвоены свойствам
вместо их предыдущих значений.
APPEND: значения будут добавлены в конец существую-
щих значений свойств, рассматриваемых как списки
(с разделением элементов точками с запятой).
APPEND_STRING: значения будут добавлены в конец су-
ществующих значений свойств, рассматриваемых
как строки (конкатенацией строк).
Замечание: многие свойства предпочтительнее устанавливать
не при помощи команды set_property(), а при помощи специализированных команд. Например, в графическом интерфейсе
213

2. Основы языка CMake
утилит CMake есть возможность отображать не все переменные
кэша, а лишь основные. За это отвечает свойство ADVANCED переменной кэша, определяющее, будет ли переменная по умолчанию скрыта. Для установки этого свойства значения истины
удобнее использовать команду mark_as_advanced(), в аргументах которой перечисляются имена переменных.
ПРИМЕРЫ
1)
add_executable(exec main.cpp file1.cpp file1.h)
set_property(
TARGET exec
PROPERTY OUTPUT_NAME
my_prog)
Здесь устанавливается свойство цели exec с именем
OUTPUT_NAME, которое определяет основу имени для выход-
N
214
ного файла (без возможного расширения «.exe» и т. д.).
По умолчанию если значение свойства не установлено,
в качестве базы имени используется логическое имя цели
(exec).
2)
foreach(LANG C CXX)
#
get_property(
FEATURES
GLOBAL
PROPERTY CMAKE_${LANG}_KNOWN_FEATURES)

2.11. Прочие команды
#
message(STATUS "Known ${LANG} features:")
foreach(FEATURE ${FEATURES})
message(STATUS " ${FEATURE}")
endforeach()
#
endforeach()
Здесь при помощи первой команды foreach() (п. 2.8.3)
реализована обработка глобальных свойств с именами
CMAKE_C_KNOWN_FEATURES и CMAKE_CXX_KNOWN_FEATURES
(см. п. 2.6.6). Для каждого из этих свойств считывается его
значение в переменную FEATURES, которая затем распечатывается поэлементно при помощи вложенного цикла.
3)
set(
MY_SETTING_VALUES One Two Three)
set(
MY_SETTING_DESCRIPTION
"Sample setting, possible values: "
"${MY_SETTING_VALUES}")
set(
MY_SETTING One
CACHE STRING "${MY_SETTING_DESCRIPTION}")
set_property(
215

2. Основы языка CMake
CACHE MY_SETTING
PROPERTY STRINGS
${MY_SETTING_VALUES})
list(FIND MY_SETTING_VALUES ${MY_SETTING} INDEX)
if(INDEX EQUAL -1)
set(
MY_SETTING One
CACHE STRING "${MY_SETTING_DESCRIPTION}"
FORCE)
endif()
Здесь в кэше создаётся переменная MY_SETTING, для которой устанавливается свойство STRINGS. Оно определяет набор возможных значений для переменной, которые, например, будут отображаться в выпадающем списке утилиты CMake с графическим интерфейсом (рис. 2.14). Дальше
выполняется проверка принадлежности текущего значения переменной списку. Если переменной кэша присвоено
недопустимое значение (например, из командной строки),
оно заменяется на одно из допустимых. ∗
216

2.12. Поддержка нескольких конфигураций построения
Рис. 2.14. Редактирование переменной кэша с набором
допустимых значений при помощи выпадающего списка
2.12. Поддержка нескольких конфигураций
построения
2.12.1. Виды конфигураций
В описании проекта многие настройки инструментов (ком-
пилятор, компоновщик и т. д.) зависят от операционной системы, используемого набора инструментов построения, версий
найденных пакетов и т. д. Это реализуется при помощи команды if() (п. 2.8.1), проверяющей значения специальных переменных.
ПРИМЕР
Пусть требуется использовать возможности стандарта C++11.
Для этого компилятору gcc нужно передать специальный ключ
217

2. Основы языка CMake
командной строки. Кроме того, в случае его использования нужно включить режим вывода всех предупреждений, а также подключить библиотеки libpthread и libdl. Это можно реализовать при помощи следующего фрагмента:
if(CMAKE_COMPILER_IS_GNUCXX)
add_compile_options(-Wall -std=c++11)
target_link_libraries(my_app -lpthread -ldl)
endif()
∗
Также настройки инструментов могут зависеть и от используемой конфигурации. Для проверки конфигурации используется специальная переменная CMAKE_BUILD_TYPE.
ПРИМЕР
if(CMAKE_COMPILER_IS_GNUCXX)
if(CMAKE_BUILD_TYPE STREQUAL Debug)
add_definitions(-D_DEBUG)
else()
add_definitions(-DNDEBUG)
endif()
endif()
По умолчанию генерируется конфигурация с пустым именем. Переменной CMAKE_BUILD_TYPE можно присваивать значение, например, в командной строке при вызове CMake:
218
∗

2.12. Поддержка нескольких конфигураций построения
cmake -D CMAKE_BUILD_TYPE=Debug ...
Названия всех доступных конфигураций перечислены
в специальной переменной CMAKE_CONFIGURATION_TYPES. В зависимости от конфигурации компилятору передаются различные ключи командной строки. По умолчанию в CMake определены 4 конфигурации, характеристики которых приведены ниже
(наличие конкретных настроек зависит от компилятора).
Debug: конфигурация для отладки:
— Включена отладочная информация.
— Включены проверки на ошибки времени исполнения
(выход за границы стека и т. п.).
— Отключены оптимизации.
— Отключена подстановка функций (inlining).
— Определён символ препроцессора _DEBUG, что позво-
ляет условно включать в коде дополнительные проверки корректности.
Release: конфигурация для поставки конечному пользовате-
лю:
— Отключена отладочная информация.
— Отключены проверки на ошибки времени исполне-
ния.
— Включены оптимизации, направленные на создание
более быстродействующего кода.
219

2. Основы языка CMake
— Компилятору позволяется выполнять подстановку
любых функций, которые он сочтёт нужными, в дополнение к явно указанным (inline).
— Определён символ препроцессора NDEBUG, что отклю-
чает проверки при помощи стандартного макроса
assert().
RelWithDebInfo: конфигурация для поставки конечному поль-
зователю с включённой отладочной информацией. Может
быть полезной для получения от пользователя осмысленных отчётов об ошибках времени исполнения:
— Включена отладочная информация.
— Отключены проверки на ошибки времени исполне-
ния.
— Включены оптимизации, направленные на создание
более быстродействующего кода.
— Компилятору позволяется выполнять подстановку
любых функций, которые он сочтёт нужными, в дополнение к явно указанным (inline).
— Определён символ препроцессора NDEBUG.
MinSizeRel: конфигурация для поставки конечному пользова-
телю с кодом минимального размера:
220
— Отключена отладочная информация.
— Отключены проверки на ошибки времени исполне-
ния.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
