Создашь два файла: код программы на C++ и описание её сборки.
Папка D:\dev\MyEngine пока пустая. Положим в эту папку два файла:
main.cpp — исходный код программы, которая печатает Hello, Engine!;
CMakeLists.txt — описание, как эту программу собрать
Сделать из файлов с кодом готовую программу.
.
Писать оба файла будем в Visual Studio: в ней ты проведёшь весь курс.
main.cpp
Сначала создадим файл main.cpp с кодом программы. Для двух способов из трёх понадобится консоль, которая стоит в папке проекта. Если консоль уже закрыта, открой PowerShell и перейди в папку проекта командой cd D:\dev\MyEngine.
Файл можно создать тремя способами. Выбери любой: результат один — пустой main.cpp в D:\dev\MyEngine, в который ты наберёшь код.
Если не получилось2
В окне создания файла нет пункта Visual C++.
Почему
В Visual Studio не установлена нагрузка для C++: этот пункт появляется вместе с ней.
Что сделать
Язык Visual Studio:
Закрой окно создания файла. Нажми клавишу Win, набери Visual Studio Installer
Программа от Microsoft, которая устанавливает Visual Studio и меняет набор её компонентов. Visual Studio Installer появляется на компьютере вместе с Visual Studio.
и нажми Enter. В окне найди карточку Visual Studio 2026 Community и нажми в ней кнопку ModifyИзменить. На вкладке WorkloadsРабочие нагрузки отметь нагрузку «Desktop development with C++Разработка классических приложений на C++»
и нажми ModifyИзменить внизу справа. Когда установка закончится, снова открой окно создания файла: пункт появится.
Нажал Ctrl+S, и Visual Studio ничего не спросила.
Почему
Бывает, что новый файл сохраняется без вопросов: под именем, которое придумала Visual Studio (например, Source1.cpp или TextFile1.txt), в её папку по умолчанию C:\Users\<имя>\source\repos. Тогда в D:\dev\MyEngine ничего не появится, и CMake этот файл не увидит.
Что сделать
Язык Visual Studio:
Выбери FileФайл → Save Source1.cpp As…Сохранить Source1.cpp как… (число в имени пункта может быть другим). Это окно спрашивает папку и имя всегда. Выбери D:\dev\MyEngine и нужное имя: main.cpp или CMakeLists.txt. Лишний файл в C:\Users\<имя>\source\repos можно удалить.
Вот этот код. Такую программу ты, скорее всего, уже писал, поэтому сцена рядом с кодом показывает, что стоит за каждой из семи строк: в том числе то, чего обычно не замечают.
Компьютер не выполняет текст напрямую: из main.cpp нужно сделать готовую программу, которую можно запустить. На схеме показано, что программа будет делать, когда запустится: возьмёт нужное из стандартной библиотеки и напечатает текст в консоли. Каждая строка кода станет частью программы.
#include <iostream> подключает из стандартной библиотеки всё нужное для вывода текста: сам язык C++ печатать не умеет. iostream — сокращение от input/output stream, «поток ввода и вывода». Подключает эта строка буквально: на её место встаёт весь текст файла iostream и файлов, которые подключает уже сам iostream. Из семи строк main.cpp так получается больше 37 тысяч строк кода, и все эти строки компилятор читает при каждой сборке main.cpp. Строка с решёткой — указание компилятору, а не команда программы, поэтому точки с запятой в её конце нет.
int main() — точка входа: с этой функции начинается твой код. Но Windows запускает программу не с main. Сначала работает код запуска
Часть стандартной библиотеки, которую линкер сам добавляет в каждую программу на C++. В Visual Studio этот код лежит в библиотеке MSVCRTD.lib для Debug и MSVCRT.lib для Release. Код запуска готовит программу к работе, вызывает main, а после main завершает программу.
из стандартной библиотеки: код запуска готовит к работе, например, std::cout и только потом вызывает функцию по имени main. Поэтому имя обязательно: если назвать функцию иначе, сборка остановится с ошибкой LNK2019, в которой сказано, что функция invoke_main из кода запуска не нашла main. Слово int перед именем — тип числа, которое main вернёт, когда закончится.
Всё между фигурными скобками — тело main, и строки тела выполняются сверху вниз. Когда main закончилась, программа ещё работает: управление возвращается в код запуска. Код запуска досылает в консоль текст, который ещё остался в std::cout, и только потом завершает программу.
std::cout — вывод в консоль (cout — сокращение от character output, «вывод символов»). Приставка std::
Двойное двоеточие читается как «из»: std::cout — это «cout из стандартной библиотеки». Так помечены все имена стандартной библиотеки, например std::string. Приставка не даёт этим именам спутаться с именами, которые придумаешь ты сам.
значит «из стандартной библиотеки». << — тот же оператор, что сдвигает биты в числах: 1 << 3 равно 8. Файл iostream задаёт оператору << для потоков другой смысл: «отправить значение в поток». Оператор << возвращает сам std::cout, поэтому отправки можно ставить цепочкой: std::cout << a << b. В конце текста в кавычках стоит \n
Две буквы в кавычках, которые значат один символ: перевод строки. Без перевода строки следующий текст в консоли продолжился бы на той же строке, вплотную к Hello, Engine!
— перевод строки. Вместо \n часто пишут std::endl: std::endl тоже переводит строку, но ещё и сразу выталкивает накопленный текст
std::cout копит текст в памяти и отдаёт консоли порциями: так быстрее, чем отдавать каждую строку отдельно. std::endl заставляет отдать накопленное немедленно.
в консоль. Когда строк много, такие выталкивания замедляют вывод, поэтому в курсе пишем \n.
return 0; завершает main и передаёт число 0 коду запуска, а код запуска отдаёт это число как код возврата той программе, которая запустила твою, здесь консоли. 0 значит «всё прошло хорошо»; любое другое число значило бы «что-то пошло не так», так программа сообщает об ошибке. Консоль снова ждёт команду.
CMakeLists.txt
main.cpp — это сам код. А из каких файлов собирать программу, на каком они языке
и как назвать результат — записано в CMakeLists.txt. Этот файл читает CMake.
А если назвать файл cmakelists.txt?
На Windows сработает: она не различает большие и маленькие буквы в именах файлов. А Linux и macOS различают,
и там CMake файл не найдёт. Проект, который собирается только у тебя, — плохой проект, поэтому имя пишем ровно так, как его ищет CMake.
Вот эти пять строк.
Как CMake читает CMakeLists.txt
CMakeLists.txtкоммит 3f85b6a
cmake_minimum_required(VERSION3.28)project(Engine LANGUAGES CXX)add_executable(app main.cpp)
CMake читает CMakeLists.txt сверху вниз, команду за командой. Команда — это имя и значения в круглых скобках. Значения разделяются пробелами, а не запятыми, как аргументы функции в C++.
cmake_minimum_required(VERSION 3.28) — «проект рассчитан на CMake 3.28 или новее». Твой CMake новее, ты видел его версию, когда проверял установку, — подходит. Эта строка всегда первая.
project(Engine LANGUAGES CXX) — имя проекта и язык. Первое слово, Engine, — имя всего проекта: оно нужно, чтобы отличать этот проект от других, и может быть любым. С именем будущей программы оно не связано: её имя мы зададим в следующей строке. CXX
Так в CMake называется C++: плюсы нельзя писать в именах, и их заменили буквами XX — повёрнутыми плюсами.
— это C++. Узнав язык, CMake ищет компилятор C++; у тебя это MSVC
Компилятор от Microsoft: он входит в Visual Studio и ставится вместе с ней. Компилятор — программа, которая переводит код на C++ в команды процессора.
из Visual Studio. Без LANGUAGES CXX CMake стал бы искать ещё и компилятор языка C, который нам не нужен.
add_executable(app main.cpp) — «собери программу app из файла main.cpp». Первое слово в скобках — имя программы, остальные — файлы с кодом, из которых её собирать. CMake не ищет файлы сам: появится в папке второй файл с кодом, его придётся дописать в скобки через пробел. Так в проекте появляется цель, и из неё получится исполняемый файл
Файл с готовой программой, который можно запустить. В Windows у него расширение .exe.
app.exe.
Почему 3.28, а не 4.0 или 3.5?
Какую версию указать в cmake_minimum_required
У тебя свежий CMake, а в файле стоит число 3.28. Почему не новее и почему не меньше? Для этого поймём, что значит это число. На шкале — версии CMake по порядку. Версия читается по частям: 3.28 — это «три и двадцать восемь», а 3.5 — «три и пять». Поэтому 3.5 меньше, чем 3.28.
Число в cmake_minimum_required — самая старая версия CMake, которой разрешено собирать проект. CMake 3.28 и новее соберёт, а старее остановится и напишет, что нужна версия 3.28. Твой CMake новее, поэтому подходит.
У числа есть и нижний предел: меньше 3.5 писать нельзя. Здесь важно не путать две версии: версию самой программы CMake, которая установлена у тебя, и число, которое ты пишешь в файле CMakeLists.txt. Допустим, ты напишешь в файле 3.0. Старая программа CMake с этим справится, а программа CMake версии 4.0 или новее, как твоя, остановится и выдаст ошибку. Причина в том, что с версии 4.0 разработчики убрали очень старые правила работы команд, которые действовали до 3.5, а число в файле как раз и выбирает, по каким правилам работать. Число 3.28 больше, чем 3.5 (версия читается по частям: 28 больше 5), поэтому подходит.
Почему не 4.0 или свежее? Не у всех свежий CMake. Например, в Ubuntu 24.04, популярной версии Linux, по умолчанию стоит 3.28. Если напишешь 4.0, на Ubuntu 24.04 проект откажется собираться, хотя ничего из 4.0 нам не нужно.
Почему тогда не взять 3.5 — самое маленькое из разрешённых? Это версия CMake 2016 года, а мы пишем новый проект, и нам нужны возможности, которые CMake получил за эти годы. Поэтому берём 3.28: эта версия достаточно новая для нас, но не слишком свежая, чтобы проект собрался у тех, у кого CMake такой же, как в Ubuntu 24.04.
Число задаёт и правила. Новые версии CMake иногда меняют поведение команд, и твой CMake, увидев 3.28, будет работать по правиламCMake 3.28. Поэтому новые версии CMake собирают проект так же, как CMake 3.28, пока поддерживают правила этой версии.
Проверка
Если не получилось2
В списке CMakeLists.txt.txt или main.cpp.txt.
Почему
Расширение дописала программа, в которой ты создал файл: Visual Studio при сохранении или Проводник, если в нём скрыты расширения.
Что сделать
Переименуй файл командой Rename-Item. Команде Rename-Item нужны два имени: сначала старое, потом новое.
CMakeLists.txt.txtCMakeLists.txtПереименовывает файл в текущей папке. Папка та же, меняется только имя.Сама команда: «переименовать».
Rename-Itemmain.cpp.txtmain.cppТо же для файла с кодом.
В списке нет нужного файла или в его имени опечатка.
Почему
Консоль стоит не в той папке, файл сохранён в другую папку или имя набрано с ошибкой, например CMakeList.txt без буквы s.
Что сделать
Язык Visual Studio:
Посмотри на начало строки консоли: там должно быть PS D:\dev\MyEngine>. Если там другая папка, перейди командой cd D:\dev\MyEngine и снова набери dir.
Если папка верная, а файла нет, вернись в Visual Studio к тексту, который ты набрал: он остался открытым в окне редактора. Вкладки открытых файлов стоят в верхней части окна Visual Studio, над текстом; щёлкни по вкладке этого файла, чтобы он стал текущим. Затем в верхнем меню выбери FileФайл → Save As…Сохранить как… (в меню в этом пункте написано ещё и имя файла). Укажи папку D:\dev\MyEngine и нужное имя.
Если в имени опечатка, исправь её:
Rename-ItemCMakeList.txtCMakeLists.txtСначала имя с опечаткой, потом правильное. Подставь своё имя с опечаткой.