1. Введение в CMake: базовый синтаксис, структура CMakeLists.txt и сборка первого приложения
Введение в CMake: базовый синтаксис, структура CMakeLists.txt и сборка первого приложения
Добро пожаловать в курс CMake для C++ разработчика: от основ до Modern CMake. Мы начинаем наше путешествие с фундаментальных понятий. Если вы когда-либо пытались собрать сложный C++ проект вручную, прописывая десятки флагов компилятора, или мучились с переносом проекта из Visual Studio в Linux, то вы быстро поймете ценность CMake.
В этой статье мы разберем, что такое CMake, как он работает, изучим синтаксис языка и соберем наше первое приложение правильным способом.
Что такое CMake и зачем он нужен?
CMake (Cross-platform Make) — это кроссплатформенная система автоматизации сборки. Однако, важно сразу прояснить одно распространенное заблуждение: CMake не собирает ваш проект. Он не является компилятором (как g++ или clang) и не является системой сборки в привычном понимании (как Make или Ninja).
CMake — это генератор систем сборки.
Как это работает?
Вы описываете правила сборки вашего проекта в файле с именем CMakeLists.txt, используя специальный язык CMake. Затем вы запускаете CMake, и он, основываясь на ваших правилах и текущей операционной системе, генерирует файлы для конкретной системы сборки.
* В Linux он обычно генерирует Makefile.
* В Windows он может сгенерировать решение (.sln) для Visual Studio.
* В macOS он может создать проект Xcode.
!Схема, демонстрирующая роль CMake как генератора нативных проектов сборки
Это позволяет вам поддерживать всего один файл конфигурации (CMakeLists.txt) для всех платформ, вместо того чтобы вручную править Makefiles и файлы проектов IDE.
Базовый синтаксис CMake
Язык CMake — это скриптовый язык. Он достаточно прост, но имеет свои особенности. Все инструкции в CMake являются командами.
Формат команд
Команда выглядит следующим образом:
* Имена команд (например, project, add_executable) нечувствительны к регистру. Вы можете писать project(...), PROJECT(...) или Project(...). Однако общепринятым стандартом в Modern CMake является использование строчных букв (lowercase).
* Аргументы разделяются пробелами или переносами строк.
* Аргументы чувствительны к регистру. Имена файлов и переменных должны быть написаны точно так, как они есть.
Комментарии
Комментарии начинаются с символа # и продолжаются до конца строки.
Структура CMakeLists.txt
Файл CMakeLists.txt должен находиться в корне вашего проекта. Давайте создадим минимальный рабочий пример. Представьте, что у нас есть файл main.cpp:
Теперь создадим для него CMakeLists.txt. Минимальный файл состоит из трех обязательных команд.
1. Требование версии CMake
Первая строка любого CMakeLists.txt должна указывать минимально необходимую версию CMake.
Это гарантирует, что если у пользователя установлена слишком старая версия CMake, которая не поддерживает используемые вами функции, сборка остановится с понятной ошибкой. Версия 3.10 — это разумный минимум для большинства современных проектов, хотя в курсе мы будем ориентироваться на возможности версий 3.15+.
2. Определение проекта
Следующая команда задает имя проекта и, опционально, его версию и используемые языки.
* MyFirstProject — имя проекта.
* VERSION 1.0 — устанавливает переменные версии проекта.
* LANGUAGES CXX — явно указывает, что мы используем C++ (CXX в терминологии CMake означает C++).
3. Создание исполняемого файла
Наконец, мы должны сказать CMake, что мы хотим собрать.
* MyBinary — это имя цели (target). Именно так будет называться итоговый исполняемый файл (в Windows это будет MyBinary.exe, в Linux — MyBinary).
* main.cpp — исходный файл, из которого собирается цель. Если файлов несколько, их можно перечислить через пробел: add_executable(MyBinary main.cpp utils.cpp).
Итоговый файл CMakeLists.txt:
Переменные в CMake
CMake поддерживает переменные, которые помогают сделать скрипты гибкими. Для установки значения переменной используется команда set.
Чтобы получить значение переменной, используется синтаксис {EXECUTABLE_NAME} ${SOURCE_FILES})
bash
mkdir build
cd build
cmake ..
bash
cmake -S . -B build
bash
cmake --build build
`
Эта команда универсальна. Неважно, используете ли вы Make, Ninja или MSBuild — CMake сам вызовет нужную утилиту с правильными флагами.
!Последовательность шагов: написание кода, конфигурация проекта и финальная сборка
Генераторы (Generators)
Как CMake узнает, для какой системы генерировать файлы? По умолчанию он выбирает наиболее подходящую для вашей ОС (например, Unix Makefiles для Linux или Visual Studio для Windows).
Однако вы можете явно указать Генератор с помощью флага -G.
Примеры:
* cmake -G "Unix Makefiles" ..
* cmake -G "Ninja" .. (Ninja — очень быстрая система сборки, рекомендуемая для крупных проектов)
* cmake -G "Visual Studio 16 2019" ..
Чтобы увидеть список доступных генераторов на вашей машине, просто введите cmake --help.
Заключение
Мы сделали первый шаг в освоении CMake. Теперь вы знаете, что:
.) и сборку (cmake --build ...`).В следующей статье мы углубимся в работу с целями (targets), узнаем, как подключать несколько исходных файлов и как правильно управлять библиотеками.