Добавил:
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. Синтаксис
— целям;
— тестам (п. 2.10.2);
— исходным файлам;
— переменным, хранящимся в кэше (п. 2.2.3);
— файлам для установки (п. 2.10.3).
Также существуют глобальные свойства. Как и переменные, свойства могут быть стандартными (имеющими предопределённое назначение). Изменение таких свойств приводит
к определённым изменениям в генерируемой системе построения. В дальнейшем стандартные свойства будут рассматриваться по мере необходимости. Некоторые стандартные свойства доступны только на чтение. Таким образом, можно провести аналогию между свойствами CMake и свойствами классов в объектно-ориентированных языках программирования.
Для считывания и установки значений свойств используются команды get_property() и set_property() (п. 2.11.2).
Замечание: в отличие от переменных, которые имеют области
действия, свойства всегда связаны с объектами, для которых
они определены. Например, глобальное свойство с заданным
именем всегда существует в единственном экземпляре, в то время как одновременно может существовать сразу несколько переменных с одним и тем же именем в разных областях действия.
N
61

2. Основы языка CMake
2.2.5. Регулярные выражения
Некоторые из команд CMake (string(), п. 2.7.4, if(),
п. 2.8.1, install(), п. 2.10.3) имеют возможность работы с регулярными выражениями. В CMake поддерживается язык регулярных выражений, аналогичный многим утилитам POSIX
(табл. 2.2).
Таблица 2.2
Элементы регулярных выражений
Строка Описание
ˆ Соответствует началу строки
$ Соответствует концу строки
. (точка) Соответствует одному любому символу
[hсимволыi] Соответствует одному любому символу
из перечисленных в скобках
[ˆhсимволыi] Соответствует одному любому символу,
которого нет в скобках
hсимволi-hсимволi Внутри скобок определяет диапазон
символов между находящимися слева
и справа от «-»: «[a-d]» эквивалентно «[abcd]». Если символ «-» граничит со скобками, он рассматривается
62
как литерал. Например: «[-+]» соответствует «-» или «+»

2.2. Синтаксис
Окончание табл. 2.2
Строка Описание
hобразецi* Соответствует образцу 0 или больше
раз
hобразецi+ Соответствует образцу 1 или больше
раз
hобразецi? Соответствует образцу 0 или 1 раз
hобразецi|hобразецi Соответствует образцу слева или спра-
ва от «|»
(hобразецi) Используется для явного указания по-
рядка операций. Кроме этого, сохраняет соответствующую строку для дальнейшего использования в выражении
замены (п. 2.7.4) и в специальной переменной CMAKE_MATCH_1 и т. д.
— Операции повтора образца («*», «+» и «?») имеют более
высокий приоритет по сравнению с конкатенацией. Конкатенация (в теории формальных грамматик) — это следование обычных символов (не представленных в табл. 2.2)
и образцов, она обозначается пустой строкой (как операция умножения в арифметике). Таким образом, регулярное выражение «aX*» следует понимать как «a(X*)»,
а не «(aX)*». То есть ему соответствует строка «aXXX»,
но не «aXaX».
63

2. Основы языка CMake
— Операция дизъюнкции образцов («|»), наоборот, имеет бо-
лее низкий приоритет по сравнению с конкатенацией. Так,
выражение «ab|cd» следует понимать как «(ab)|(cd)»,
а не «a(b|c)d». Ему соответствуют строки «ab» и «cd»,
но не «abd» и «acd».
Специальная переменная CMAKE_MATCH_0 содержит последнюю подстроку, распознанную как соответствующую регулярному выражению любой командой CMake. Аналогично, переменные CMAKE_MATCH_1, CMAKE_MATCH_2 и т. д. содержат
подстроки, соответствующие группирующим подвыражениям
(частям регулярных выражений в круглых скобках). Начиная с версии 3.2 CMake также поддерживает переменную
CMAKE_MATCH_COUNT, которая принимает значение максимального номера n заполненной последним сопоставлением переменной CMAKE_MATCH_hni.
Замечания:
— Регулярные выражения имеют свойство «жадности». Это
значит, что при выделении командой string() подстрок,
соответствующих заданному регулярному выражению, вы-
деляется наиболее длинная подстрока, насколько это воз-
можно. Например, в строке «---ab-cd-cd---» в соответ-
ствии с выражением «ab.*cd» будет выделена подстрока
«ab-cd-cd», а не «ab-cd».
— CMake поддерживает меньший набор возможностей
по сравнению с регулярными выражениями POSIX1. На-
пример, конструкции, ссылающиеся на распознанные
1
http://en.wikibooks.org/wiki/Regular_Expressions (дата обращения: 16.02.2015).
64

2.3. Примеры простых проектов
подстроки («\1», «\2» и т. д.), допустимы только в выра-
жениях замены команды string(REGEX REPLACE ...)
(п. 2.7.4), но не в том же самом регулярном выражении.
Образцы повтора после скобок («(aX)*») в CMake не имеют
смысла.
N
Примеры использования регулярных выражений приведе-
ны в описании команды string() (п. 2.7.4).
2.3. Примеры простых проектов
Прежде чем приступать к изучению основных команд языка CMake, рассмотрим несколько простых примеров его использования.
ПРИМЕР
Пусть требуется построить проект из одного исходного файла,
в результате чего должен быть создан исполняемый модуль.
Рассмотрим возможную структуру каталогов проекта (рис. 2.1).
Здесь в некоторой рабочей папке находятся каталог исходных
файлов проекта (test_cmake) и каталог построения (_build).
В этом примере оба каталога расположены рядом друг с другом
для упрощения команды вызова инструмента CMake, в реальности эти каталоги могут располагаться совершенно в разных местах.
Для решения задачи в каталоге проекта должен содержаться файл CMakeLists.txt со следующим возможным содержанием:
65

2. Основы языка CMake
hрабочий каталогi
_build ........................каталог построения проекта
test_cmake .............каталог исходных файлов проекта
main.cpp
...
CMakeLists.txt ..................файл описания проекта
build.cmd (build.sh)
Рис. 2.1. Структура каталога простого проекта
# CMakeLists.txt - описание простого проекта
project(test_cmake)
add_executable(test_cmake main.cpp)
Первая строка файла является комментарием. Дальше следует команда project(), задающая имя проекта. Это имя будет использовано при создании системы построения в качестве
имени решения или основного проекта.
Последняя строка содержит команду add_executable(),
которая определяет новую цель построения с именем
test_cmake и исходным файлом main.cpp. По умолчанию
построение цели должно привести к созданию исполняемого
модуля с тем же именем, что и имя цели (test_cmake) в выходном каталоге проекта. На платформе Windows имя файла будет
дополнено расширением «.exe».
Если в дальнейшем будет необходимо добавить в проект
другие исходные файлы, их имена можно добавить в список аргументов команды add_executable().
66

2.3. Примеры простых проектов
Для удобства можно создать файл сценария build.cmd
в ОС Windows (build.sh в системах на основе Linux, OS X и т. д.)
рядом с каталогом _build, при помощи которого можно автоматизировать процесс построения вызовом инструмента CMake
с нужными аргументами. Содержимое этого файла является специфичным для компьютера, на котором выполняется построение, поэтому нет смысла помещать его в каталог исходных файлов.
mkdir _build
cd _build
set PATH=C:\Program Files\CodeBlocks\MinGW\bin;%PATH%
cmake -G "CodeBlocks - MinGW Makefiles" ../test_cmake
В первой строке исполняется команда mkdir, создающая каталог построения, если его не существует. Следующая команда
(cd) выбирает каталог построения в качестве текущего. Следующая за ней команда добавляет в начало системной переменной окружения PATH путь к исполняемым файлам компилятора MinGW, входящего в состав дистрибутива интегрированной
среды Code::Blocks. Это необходимо для того, чтобы инструмент
CMake мог найти нужные файлы инструментов компилятора
MinGW и сгенерировать рассчитанные на них файлы построе-
ния.
В последней строке вызывается сам инструмент CMake.
Ему передаётся два аргумента: имя генератора при помощи ключа «-G» (здесь генерируется файл проекта для среды Code::Blocks,
67

2. Основы языка CMake
использующий утилиту построения mingw32-make) и путь к каталогу проекта, в котором расположен файл CMakeLists.txt.
Таким образом, каталог _build можно удалить в любой момент. Для повторного построения достаточно запустить командный файл build.cmd и обработать созданный проект при помощи среды Code::Blocks (рис. 2.2).
Рис. 2.2. Сгенерированный проект, открытый в среде
Code::Blocks
Похожим образом можно написать аналогичный сценарий build.sh для операционных систем на основе Linux,
FreeBSD и т. п.
ПРИМЕР
Пусть необходимо построить проект, содержащий две цели: статическую библиотеку и приложение, использующее эту библио-
68

2.3. Примеры простых проектов
теку. Пусть файлы в каталоге проекта организованы так, как
изображено на рис. 2.3.
hрабочий каталогi
_build_lib ....................... каталог построения проекта
lib ......................... каталог исходных файлов проекта
sample_lib ................подкаталог проекта библиотеки
sample_module.cpp
sample_module.h
CMakeLists.txt ........... описание проекта библиотеки
sample_program ..подкаталог проекта исполняемого файла
main.cpp
CMakeLists.txt ........... описание проекта приложения
CMakeLists.txt .......... описание проекта верхнего уровня
build_lib.cmd (build_lib.sh)
Рис. 2.3. Структура каталога проекта с библиотекой
Здесь исходные файлы библиотеки и приложения расположены в двух подкаталогах проектов нижнего уровня, каждый
из которых имеет собственный файл описания CMakeLists.txt.
Оба проекта объединяются третьим файлом CMakeLists.txt,
расположенным на каталог выше, в корне составного проекта.
Эти файлы могут иметь следующее содержание:
Файл CMakeLists.txt верхнего уровня:
cmake_minimum_required(VERSION 2.8)
project(lib)
add_subdirectory(sample_lib)
add_subdirectory(sample_program)
69

2. Основы языка CMake
Файл CMakeLists.txt проекта библиотеки:
add_library(
sample_lib sample_module.cpp sample_module.h)
Файл CMakeLists.txt проекта исполняемого файла:
add_executable(sample_program main.cpp)
include_directories(../sample_lib)
target_link_libraries(sample_program sample_lib)
Описание проекта верхнего уровня начинается с команды cmake_minimum_required() (п. 2.4.1), устанавливающей наименьшую версию инструмента CMake, которым может быть обработан проект. Далее устанавливается название проекта при
помощи команды project() (п. 2.4.2). Затем к проекту присоединяются два проекта нижнего уровня при помощи команд
add_subdirectory() (п. 2.5.3), задающих пути к подкаталогам.
Описание проекта библиотеки содержит единственную команду add_library() (п. 2.5.2), в которой задаются имя цели
и список исходных файлов проекта. Сборка проекта должна привести к созданию статической библиотеки в выходном каталоге проекта sample_lib (подкаталога sample_lib выходного каталога проекта верхнего уровня). Имя файла библиотеки будет
по умолчанию совпадать с именем цели sample_lib с префиксом и расширением, зависящими от компилятора. Например,
для компилятора gcc имя библиотеки будет libsample_lib.a.
Описание проекта приложения отличается от предыдущего примера добавлением двух новых команд. Команда
70
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
