Добавил:
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.2. Синтаксис
message(STATUS "Building for Windows")
endif()
Замечание: все конструкции, включая endif() в примере выше,
являются командами, поэтому после них необходимо ставить
∗
скобки.
N
Как правило, команды поддерживают переменное количе-
ство аргументов.
Имена команд нечувствительны к регистру, в настоящем
учебнике мы будем использовать для их записи строчные буквы и символ подчёркивания.
2.2.2. Строки
Аргументами команд являются строки. Как и в языках
Bourne Shell, make и т. д., строки представляют собой про-
извольные последовательности символов (кроме специальных), поддерживаются активные символы (п. 2.2.3) и escapeпоследовательности. Чтобы включить в строку символы-разделители, можно заключить её в двойные кавычки. В этом случае
интерпретатор будет считать данные символы частью строки,
а не разделителями аргументов. Строки в кавычках могут занимать несколько строк в тексте программы, при этом символ «\»
в конце строки текста приводит к тому, что следующий за ним
символ перевода строки не будет считаться частью строки.
51

2. Основы языка CMake
ПРИМЕР
Команда вывода сообщения (п. 2.4.4):
message(
"AB\nCD
\tEF\
GH \${DATA}\"\\#" # строка
)
выведет на консоль следующую строку:
AB
CD
EF GH ${DATA}"\#
— Команда выполняет первый перевод строки после симво-
лов «AB», так как в строковой константе после них указана
escape-последовательность «\n», означающая символ перевода строки, как и в языках C++и т. д.
— Следующий перевод строки после символов «CD» указан
в строковой константе явно.
— Следующая строка начинается с двух пробелов и символа
табуляции («\t»), символ перевода строки после «EF» подавляется стоящим перед ним escape-символом «\». Таким
образом, после символов «EF» на печать выводятся два пробела и символы «GH».
— За символами «GH» выводится пробел, так как он считается
частью строки, ограниченной двойными кавычками. Если
52

2.2. Синтаксис
бы кавычек не было, пробел считался бы разделителем ар-
гументов команды message() и на печать не был бы выве-
ден.
— Дальше выводятся символы «${DATA}». Если бы в стро-
ковой константе перед символом «$» не было escape-
символа «\», конструкция «${DATA}» внутри строковой
константы считалась бы ссылкой на переменную с именем
DATA и была бы заменена её значением (п. 2.2.3).
— Далее выводится символ «"». Поскольку в строковой кон-
станте перед ним стоит escape-символ «\», он считается ча-
стью строки, а не завершающей её двойной кавычкой.
— Затем на печать выводится символ «\». Так как в языке
CMake он является escape-символом, для его включения
в строковую константу его нужно дополнить им же.
— В конце выводится символ «#». Так как он указан внутри
строковой константы, ограниченной двойными кавычка-
ми, он считается её частью, а не началом комментария.
— Так как следующий символ «#» встречается в программе
уже после завершения строковой константы и вне двой-
ных кавычек, он считается началом комментария.
Хотя все данные в CMake имеют строковый тип, в некоторых случаях строковые значения служат в качестве данных других типов. Так, строки используются для представления чисел
53
∗

2. Основы языка CMake
в десятичной записи — как целых, так и с плавающей точкой.
Формат записи аналогичен другим языкам программирования.
При использовании управляющих конструкций необходим способ представления логических значений. Для этого могут быть использованы различные строковые значения
(табл. 2.1).
Таблица 2.1
Строковые значения, соответствующие логическим
константам
«Истина» «Ложь»
TRUE FALSE
YES NO
Y N
ON OFF
Десятичная запись
ненулевого числа
0
IGNORE
NOTFOUND
Любая строка, заканчивающаяся на «-NOTFOUND»
"" (пустая строка)
Запись всех именованных логических констант нечувствительна к регистру. Значения, заканчивающиеся на «-NOTFOUND»,
можно использовать для проверки результатов успешности поиска файлов, библиотек и т. д. при помощи команд find_file(),
find_library() (п. 2.9.2) и т. д., которые записывают путь к най-
54

2.2. Синтаксис
денному объекту в заданную переменную. Если поиск закончился неудачей, эти команды записывают в переменную её имя,
дополненное суффиксом «-NOTFOUND».
Другим типом данных, поддерживаемым языком CMake,
является список. Списки представляются при помощи обычных
строк, внутри которых символы «;» («точка с запятой») разделяют соседние элементы. Перебор элементов списка можно выполнять при помощи команд foreach() и endforeach() (п. 2.8).
При передаче списков в команды в качестве аргументов их элементы передаются внутрь команд несколькими аргументами
вместо одного. Чтобы заставить команду воспринимать список
как один аргумент, его можно поместить в двойные кавычки.
ПРИМЕР
Следующий фрагмент кода:
message(a;b;c)
message("a;b;c")
выведет на печать следующие строки:
abc
a;b;c
Здесь первая команда message() (п. 2.4.4) получит три аргумента: «a», «b» и «c». Команда выводит свои аргументы друг
за другом без пробелов. Вторая команда message() получит
один аргумент: строку «a;b;c». ∗
55

2. Основы языка CMake
2.2.3. Переменные
Так же как и в языках Bourne Shell и др., в языке CMake
есть поддержка переменных строкового типа. Значения переменных могут использоваться внутри аргументов команд при
помощи конструкции «ссылка на переменную»: ${VAR_NAME}.
ПРИМЕР
set(GREETING Hello)
message("${GREETING} world!")
Здесь переменной GREETING присваивается значение
«Hello», после чего выводится сообщение «Hello world!». ∗
Кроме пользовательских переменных в CMake также существует множество встроенных, имеющих специальное назначение (специальные переменные). Некоторые из этих переменных
будут рассмотрены далее по мере необходимости.
Имена переменных чувствительны к регистру и могут состоять почти из любых символов. В настоящем учебнике мы будем использовать для них прописные буквы, цифры и символ
подчёркивания.
Замечание: при обработке проектов система CMake создаёт пе-
ременные с именами вида hимя_проектаi_SOURCE_DIR (с. 75). Более свободные по сравнению с другими языками программирования правила именования переменных позволяют накладывать минимальные ограничения на названия проектов. Например, имя 01-hello_SOURCE_DIR является допустимым, хотя лек-
56

2.2. Синтаксис
сический анализатор большинства других языков мог бы воспринять его как арифметическое выражение.
N
Как и в других языках программирования, переменные
имеют собственную область действия. Области действия определяются следующими сущностями:
Функция. Функции в языке CMake определяют пользователь-
ские команды, которые могут использовать локальные пе-
ременные. Функции определяются при помощи команд
function() и endfunction() (п. 2.8.4).
Каталог (под)проекта. Каждый обрабатываемый каталог ис-
ходных файлов со своим описанием CMakeLists.txt за-
даёт собственную область действия переменных. Перед
началом обработки подпроекта с собственным файлом
CMakeLists.txt система CMake копирует в новую область
все переменные из родительской области. Сценарии, запус-
каемые командой «cmake -P ...» (п. 2.1.2), также задают
область действия.
Кэш. Некоторые переменные могут быть определены в про-
грамме как предназначенные для постоянного хранения
в файле CMakeCache.txt, записываемом в выходной ката-
лог. Эти переменные будут сохранять свои значения меж-
ду повторными запусками инструмента CMake (до момен-
та удаления файла CMakeCache.txt). Значения перемен-
ных можно редактировать, например, при помощи гра-
фической утилиты ccmake из состава CMake. Переменные
кэша предназначены для хранения изменяемых настро-
57

2. Основы языка CMake
ек построения проекта. Первый запуск CMake заполняет их некоторыми значениями по умолчанию, последующие запуски используют уже значения, отредактированные пользователем.
Замечания:
— В отличие от подпроектов, подключаемых командой
add_subdirectory() (п. 2.5.3), модули CMake, которые подключаются командой include() (п. 2.4.3), отдельной области действия переменных не образуют.
— Область действия также относится и к специальным пере-
менным. То есть их значения и действие ограничиваются текущей областью. Таким образом, статус «специальности» переменной определяется её именем. При этом в разных областях действия могут существовать разные специальные переменные с одним и тем же именем.
— Переменные, которые создаются в командной строке
при вызове инструмента CMake с помощью ключа «-D»
(см. пример на с. 68), попадают в кэш.
N
При исполнении команд каждая найденная ссылка на переменную (${VAR_NAME}) заменяется значением этой переменной. Поиск значения выполняется от вершины в глубину
стека областей действия переменных, образуемого динамически вложенными вызовами функций. Последней просматривается область действия текущего интерпретируемого файла
CMakeLists.txt (если переменная не была найдена ранее), а по-
58

2.2. Синтаксис
сле неё — область кэша. Если переменная нигде не найдена,
ссылка на неё заменяется пустой строкой.
Для установки значения переменных в языке CMake суще-
ствует ряд команд (п. 2.7).
Специальная конструкция вида ENV{hимя_переменнойi}
может быть использована для доступа к переменной окружения работающего процесса CMake. Она может использоваться везде, где можно применять обычные переменные (не кэша). Доступ к значению переменной окружения осуществляется
при помощи конструкции $ENV{hимя_переменнойi}.
ПРИМЕР
set(ENV{PATH} "$ENV{PATH};${CMAKE_BINARY_DIR}")
Здесь при помощи команды set() (п. 2.7.1) к переменной
окружения PATH добавляется через точку с запятой путь к каталогу построения проекта верхнего уровня, который хранится в специальной переменной CMAKE_BINARY_DIR. Переменная
окружения PATH в различных системах содержит список каталогов, в которых осуществляется поиск, в частности, исполняемых
файлов при указании их имени в командной строке (в формате
«cmd_name», т. е. без пути в начале). ∗
Замечания:
— В разных системах пути в переменной окружения PATH мо-
гут отделяться друг от друга разными символами. В POSIX-
совместимых системах для этого используется двоеточие.
59

2. Основы языка CMake
— Выполненное в примере выше изменение переменной
окружения, унаследованной процессом CMake от родителя,
будет действительно только для этого процесса на время
его работы. Оно не повлияет на значение этой переменной
для родительского процесса или процессов, которые будут
в дальнейшем выполнять построение проекта. Чтобы установить значения переменных окружения для инструментов, которые запускаются во время исполнения правил,
определяемых командами add_custom_target() (п. 2.10.4)
и add_custom_command() (п. 2.10.5), можно воспользоваться командой «cmake -E env ...» (см. также пример и замечание к нему на с. 223).
— CMake выдвигает те же требования к именам перемен-
ных окружения, что и для своих переменных. В частности, в именах переменных недопустимы скобки.
Это затрудняет использование переменной окружения
ProgramFiles(x86), определённой в 64-битных версиях системы Windows. Пример на с. 192 демонстрирует,
как можно обойти это ограничение.
2.2.4. Свойства
Свойства (properties) аналогичны переменным, но относят-
ся к различным объектам:
N
— каталогам проектов (как каталогам верхнего уровня, пе-
редаваемым CMake в качестве аргумента командной
строки, так и подключаемым при помощи команды
add_subdirectory() (п. 2.5.3));
60
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
